How Skills Are Structured Within Each Plugin in dotnet/skills
Skills in dotnet/skills are organized as markdown-driven definitions inside self-contained plugin folders, where each plugin contains a JSON manifest file, a dedicated skills directory with SKILL.md files, and optional agents and MCP server configurations.
The dotnet/skills repository implements a modular architecture that separates capabilities into independent plugins. Understanding how skills are structured within each plugin is essential for extending the system or integrating with the skill-validator runtime. This guide examines the exact file-system contract used by plugins like dotnet-test and dotnet-msbuild to register and execute AI-driven workflows.
Plugin Manifest Structure
Every plugin begins with a plugin manifest located at plugins/<plugin-name>/plugin.json. This JSON file declares the plugin's metadata and points to its skill directories.
According to the source code, the manifest contains:
- Name, version, and description – Identifies the plugin for the validator
- Skills array – Specifies the folder containing skill definitions (typically
"./skills/") - Agents array – Optional references to specialized AI agents
- MCP servers – Optional tool server definitions for external process communication
For example, the dotnet-test plugin manifest at plugins/dotnet-test/plugin.json registers its skills folder and several test-generation agents, while plugins/dotnet-msbuild/plugin.json configures the binlog MCP server for MSBuild log parsing.
Skill Definition Layout
Inside each plugin, the skills/ directory contains one subfolder per skill. The structure follows this pattern:
plugins/<plugin-name>/
├── plugin.json
└── skills/
└── <skill-name>/
├── SKILL.md
└── references/ (optional)
The SKILL.md file serves as the single source of truth for a skill's behavior. It contains:
- Front-matter metadata – YAML-style headers defining inputs, outputs, and validation rules
- Workflow steps – Instructions the validator executes
- Usage guidance – Documentation for consumers
For instance, the writing-mstest-tests skill in plugins/dotnet-test/skills/writing-mstest-tests/SKILL.md defines input parameters and testing workflows, while plugins/dotnet-msbuild/skills/msbuild-antipatterns/SKILL.md contains MSBuild-specific analysis logic.
Optional Components
Beyond the core manifest and skill definitions, plugins may include additional directories that extend functionality.
References Directory
Skills requiring supplementary documentation include a references/ folder adjacent to SKILL.md. This directory stores supporting files such as diagrams, external markdown documentation, or code samples. The migrate-nullable-references skill, for example, includes references/nullable-attributes.md to support its migration workflow.
Agent Definitions
The agents/ directory at plugins/<plugin-name>/agents/ houses specialized AI agent definitions. These markdown files (e.g., code-testing-generator.agent.md) describe agents that the skill-validator invokes for code generation or analysis tasks. When a skill's workflow references an agent, the validator loads the definition from this directory to perform specialized operations.
MCP Server Configuration
For skills requiring external tool integration, the plugin manifest's "mcpServers" section defines Model Context Protocol servers. These configurations specify commands to launch external processes that communicate via JSON over stdio. The dotnet-msbuild plugin configures the binlog MCP server using dotnet dnx Microsoft.AITools.BinlogMcp --yes, enabling skills to parse binary MSBuild logs without embedding the parser logic directly.
How the Validator Processes the Structure
The skill-validator runtime consumes this structure through a five-stage discovery process:
- Plugin Discovery – Walks the
plugins/directory and parses eachplugin.json - Skill Registration – Resolves the paths specified in the
"skills"array and registers every subfolder containingSKILL.md - Input Validation – Loads the markdown front-matter and validates user-supplied inputs against the declared schema
- Agent Resolution – Loads agent definitions from
agents/when workflows reference them - MCP Initialization – Launches configured MCP servers as separate processes for tool-dependent skills
This architecture ensures that adding a new skill requires only creating a folder with SKILL.md under the plugin's skills/ directory, without recompiling the validator host.
Code Examples
Loading Skills Programmatically
You can discover available skills by parsing the plugin manifest and scanning the skills directory:
using System.Text.Json;
using System.IO;
// Load the plugin manifest
var manifestPath = Path.Combine(repoRoot, "plugins", "dotnet-test", "plugin.json");
var manifestJson = File.ReadAllText(manifestPath);
var manifest = JsonSerializer.Deserialize<JsonElement>(manifestJson);
// Resolve the skills folder from the manifest
var skillsRoot = Path.Combine(repoRoot, "plugins", "dotnet-test",
manifest.GetProperty("skills")[0].GetString());
// Enumerate available skills
foreach (var skillDir in Directory.GetDirectories(skillsRoot))
{
var skillFile = Path.Combine(skillDir, "SKILL.md");
if (File.Exists(skillFile))
Console.WriteLine($"Found skill: {Path.GetFileName(skillDir)}");
}
Running Skills via CLI
Invoke a specific skill using the validator's run command with the plugin-name/skill-name syntax:
skill-validator run dotnet-test/writing-mstest-tests \
--input "Test scenario: Verify that OrderService.CalculateTotal applies discount correctly"
Summary
- Plugin manifests (
plugin.json) declare the plugin metadata and locate the skills directory - Skill definitions reside in
skills/<skill-name>/SKILL.mdfiles containing front-matter metadata and workflow instructions - References stored in
references/folders provide supplementary documentation for complex skills - Agents defined in
agents/enable specialized AI behavior for code generation and analysis - MCP servers configured in the manifest allow external tool integration via stdio JSON communication
- The validator discovers and executes skills by walking this file structure without requiring host recompilation
Frequently Asked Questions
What is the minimum required structure for a plugin?
A valid plugin requires only two files: plugins/<plugin-name>/plugin.json and at least one plugins/<plugin-name>/skills/<skill-name>/SKILL.md. The manifest must specify the skills directory path, and the SKILL.md must contain valid front-matter defining the skill's inputs. References, agents, and MCP servers are optional extensions.
How does the skill-validator discover new skills?
The validator walks the plugins/ directory and reads each plugin.json to locate the "skills" array entries. It then scans the specified directories for subfolders containing SKILL.md files, registering each valid file as an executable skill. This discovery happens at runtime, allowing dynamic plugin loading without application restart.
Can a plugin contain multiple skills?
Yes, a single plugin can contain any number of skills. Each skill resides in its own subfolder under plugins/<plugin-name>/skills/, with its own SKILL.md file. The dotnet-test plugin, for example, contains multiple testing-related skills including writing-mstest-tests and writing-nunit-tests, all sharing the same plugin manifest and agent pool.
What is the purpose of the SKILL.md front-matter?
The front-matter in SKILL.md declares the skill's interface contract, including input parameter definitions, types, validation rules, and output specifications. The validator parses this YAML-style header before execution to validate user inputs and configure the execution environment, ensuring type safety and required parameter enforcement before running the workflow steps.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →