dotnet/skills
The .NET team ships agent skills the way it ships products: per-plugin versioning, baseline-vs-skilled evals for 94 of 98 skills, and 22,454 committed eval sessions anyone can inspect.
This is the most measurably engineered vendor skill pack GearScope has reviewed: every plugin carries paired baseline-vs-skilled evaluations, the results ship in a public dashboard, and the install paths worked verbatim on Claude Code and byte-identical for Hermes. Content depth is real (median 223 lines per skill, zero stubs, 16 custom agents, a Roslyn language-server bridge). The gaps are metadata-level: all 16 plugins fail strict validation on a missing author field, one skill ships without a license declaration, and the experimental plugin is stranded off every marketplace manifest.
$/plugin marketplace add dotnet/skills
$/plugin install dotnet-test@dotnet-agent-skills
$codex plugin marketplace add dotnet/skills
install if
- Any C#/.NET developer using an agent that supports plugins or agentskills.io directories. The migration family alone (dotnet 8 to 9 to 10 to 11, MSTest v1/v2 to v3 to v4, VSTest to Microsoft.Testing.Platform, nullable reference adoption) covers work most .NET teams have queued right now.
- Teams standardizing agent behavior on a Microsoft stack. The Roslyn LSP bridge in the base dotnet plugin gives agents real compiler-grounded answers instead of hallucinated API usage, and the token projections per skill let you budget context.
- Skill authors who want a reference architecture. The eval harness (paired baselines, dormancy guards, judge rubrics, public dashboards) is the best-documented open template for proving a skill earns its context cost.
skip if
- Non-.NET teams. Every skill is C#/.NET-specific; nothing here generalizes to other stacks.
- Users who want an MCP server. This is a skills-plus-LSP pack with plugin manifests, not an MCP deployment; the Microsoft surface for that use case is elsewhere (azure-skills, mcp-toolbox).
- Anyone on a locked-down Python 3.9 environment who needs the untested-source tooling. The one Python helper will not run there and its error message will not tell you why.
- Minimal-context setups. The published plugins each add a small always-on cost (measured ~200 tokens for the smallest), and installing several plugins stacks that; the dashboard exists precisely because the team measures this, so check it before bulk-installing all 15.
What It Does
The official .NET Foundation repository of agent skills for C# and .NET development, maintained by the .NET team at Microsoft (the Codex marketplace manifest lists the owner as ".NET Team at Microsoft"). It ships 16 plugins holding 98 SKILL.md files across the .NET surface: MSBuild diagnosis (19 skills), testing (22), Blazor (9), MAUI (8), performance and crash analysis (7), framework migrations (6), template engine (6), test-framework migration (5), ASP.NET Core (4), advanced scenarios (4), data access (2), AI integration (1), NuGet (1), the base dotnet plugin (1), and .NET 11 previews (1). Sixteen custom agents ride along, including a nine-agent code-testing pipeline in dotnet-test. The base plugin also wires the Roslyn C# language server into coding agents via a dnx-hosted LSP bridge, so an agent gets real compiler intelligence, not just prompt text. The target user is a .NET developer running Claude Code, Copilot CLI, Codex, Cursor, or VS Code.
The Good
The evaluation culture is the deepest in any vendor pack GearScope has reviewed. Every skill is expected to have a paired eval under tests/
The results are public, committed, and fresh. Evaluations run as baseline (no skills) versus skilled (exactly one skill) arms with claude-opus-4.6 as both executor and judge, per the committed dotnet-skills.experiment.yaml. The sessions land in a separate repo (dotnet/skills-data) whose manifest we fetched: 22,454 eval sessions across 17 plugin namespaces and 515 distinct skill-eval combinations, generated 2026-08-30T16:28Z, two days before this review. A public Chart.js dashboard (dotnet.github.io/skills) renders token use, elapsed time, activation rates, and not-passed rates by plugin, skill, executor model, and judge model, with a freshness module that prefers "unknown" over inventing a stale classification. No other vendor pack publishes its skills' measured cost and pass rates this way.
Install paths work verbatim, on four ecosystems. The README's Claude Code path ran exactly as written: marketplace add dotnet-skills, install dotnet11@dotnet-agent-skills, and the plugin details command returned a real component inventory with token projections (~200 always-on tokens, ~3.7k on-invoke for its one skill). Uninstall and marketplace removal were clean. The repo ships three marketplace manifests in-tree (.claude-plugin for Claude, .agents/plugins for Codex, .cursor-plugin for Cursor, each with the same 15 entries) plus a documented VS Code preview path. For the wider ecosystem, npx skills add with the hermes-agent target landed dotnet-webapi at the project level (.hermes/skills/) with a SKILL.md byte-identical to the clone and a skills-lock.json recording the source path and a sha256 content hash. Demand-side, skills.sh indexes 76 entries from this repo totaling 111,539 all-time installs, led by analyzing-dotnet-performance at 2,399.
The content has no filler. Across the 98 skills the minimum SKILL.md is 41 lines, the median is 223, the maximum is 531, and 59 skills exceed 200 lines. Descriptions follow a routing contract (USE FOR and DO NOT USE FOR lists) with a median length of 81 characters and a maximum of 927, inside the agentskills.io frontmatter budget. One hundred nine reference files back the skills with progressive disclosure (322 bytes to 27KB). The seven executable helpers are useful rather than decorative: crash symbolication for Apple and Android formats, CRAP-score coverage analysis in PowerShell, nullable-migration readiness checks, and the Python untested-source finder we functionally verified below.
This is a production engineering project, not a docs dump. 758 commits in the last 52 weeks across 31 active weeks, from identifiable .NET team members (Evangelink 189, AbhitejJohn 135, ViktorHofer 113, JanKrivanek 106, plus timheuer, tannergooding, AaronRobinsonMSFT). Twenty-nine CI workflows include a daily skill-validator build that publishes nightly releases (the latest shipped the morning of this review), an eval-quality gate, skill-coverage tracking, markdownlint, actionlint, and agent-driven workflows for issue triage and malicious-PR scanning. Plugins version independently via Nerdbank.GitVersioning with path filters that exclude manifest files from bump propagation. SECURITY.md is the standard Microsoft MSRC policy. A tagged v1.0.0 exists from April 2026.
The Bad
All 16 plugins fail claude plugin validate --strict, and the marketplace fails with it. Every plugin.json omits the author field, which strict mode treats as an error ("No author information provided for plugin attribution"), and the root marketplace manifest additionally lacks a description. These are the only strict failures: the structure, skills, and manifests are otherwise sound, and normal (non-strict) installs work fine. But an official Microsoft repo shipping zero-for-seventeen on Claude Code's own validator, with a nightly CI that never runs it, is a governance gap. Open issue #1087 reports a sibling symptom: the plugin.json files omit $schema, which breaks loading in Kiro.
The Python helper breaks on macOS system Python with misleading guidance. find_untested_sources.py declares tree-sitter-language-pack as its dependency, but on Python 3.9 pip resolves that package to a legacy wheel that lacks the process API the script imports. The script then prints "ERROR: tree-sitter-language-pack is not installed. Run: pip install tree-sitter-language-pack", which is false: the package is installed at the latest published version (0.9.1) and the same version works on Python 3.11. Neither the SKILL.md nor the script documents a minimum Python version, so the documented fix sends affected users in a circle.
The experimental plugin is stranded. plugins/dotnet-experimental (v0.1.2, two skills: exp-mock-usage-analysis and exp-test-maintainability) exists on disk but appears in none of the three marketplace manifests and is absent from the README's plugin table, with no stated policy for how it graduates or why it is excluded. Anyone installing "everything from dotnet/skills" via a marketplace silently misses it, and the dashboard tags also carry a dotnet-aspnet namespace (222 sessions) for a plugin that no longer exists under that name.
One skill ships without a license declaration. 97 of 98 SKILL.md files declare license: MIT in frontmatter; dotnet-data/create-datadriven-aspnetcore does not. Trivial to fix, but it is the kind of inconsistency the repo's own validator should be catching before merge.
There is no changelog and the star graph is noisy. Release history beyond the nightly validator artifacts is effectively git log: no CHANGELOG, one product tag (v1.0.0, April) behind plugin versions that have moved 19 minor versions since. The repo also gained 814 stars in a single six-hour window on 2026-08-31 (a rate 200x its prior week) followed by near-zero movement, a pattern the pipeline tracked as anomalous; the code, commit cadence, and maintainer roster all check out as genuine, so this reads as an organized star drop on an official repo rather than a quality signal either way. A third-party bot (costrict-plugins-repo) also mirror-squatted 17 dotnet-agent-skills-* repos off the marketplace name during the same window; all now return 404, and we verified the official repo remains the only install source.
Smoke Test Results
Host-based hands-on testing on macOS 26.5.2 aarch64 (Node 24.13.1, Claude Code 2.1.152): fresh 26MB shallow clone at HEAD 34950f8, structural validation across all 98 skills, the Claude Code marketplace flow end to end, the skills CLI hermes-agent path with byte-identity assertions, and functional runs of the one helper script runnable on this host.
Run A - Fresh clone, structural validation, no dependencies
$ git clone --depth 1 https://github.com/dotnet/skills.git /tmp/dotnet-skills-review
β
26MB clone, HEAD 34950f8 "Merge pull request #1094 from dotnet/automated/gh-aw-upgrade", MIT LICENSE (.NET Foundation and Contributors)
$ frontmatter parse across plugins/*/skills/*/SKILL.md
β
98 of 98 parse, 98 of 98 declare name, median 223 lines (min 41, max 531), 0 stubs under 40 lines
$ license field check
β 97 of 98 declare license: MIT; dotnet-data/skills/create-datadriven-aspnetcore/SKILL.md missing the field
$ internal file-link resolution (markdown links to .md/.ps1/.py/.cs/.yaml inside skills)
β
81 links checked, 0 broken
$ marketplace manifest reconciliation (.claude-plugin, .agents/plugins, .cursor-plugin)
β each manifest lists 15 plugins but 16 exist on disk; dotnet-experimental (v0.1.2) is in none of them and not in the README table
$ eval coverage (tests/<plugin>/<skill>/eval.yaml)
β
98 eval.yaml files, 94 of 98 skills covered (uncovered: copy-to-output-directory, code-testing-extensions, filter-syntax, test-analysis-extensions)
$ security scan of all skill and reference files
β
0 hardcoded secrets, 0 curl-to-shell pipes (the single curl pipe found is Microsoft's official dot.net install script, documented in a MAUI troubleshooting reference)
$ CI inventory
β
29 workflow files incl. skill-validator (daily + nightly releases), eval-quality, skill-coverage, markdownlint, actionlint, malicious-PR-scan agent
Pass rate: 6 of 8. The two failures are metadata gaps (one missing license field, one stranded plugin), not structural breakage.
Run B - Sandbox with deps preinstalled: Claude Code marketplace flow
$ claude plugin validate --strict . (marketplace level, local clone)
β FAIL: 1 warning treated as error, "No marketplace description provided"
$ claude plugin validate --strict plugins/dotnet11
β FAIL: same single warning, "author: No author information provided"
$ claude plugin validate --strict plugins/<name> (looped over all 16 plugins)
β 0 of 16 pass; every plugin fails on the identical author-field warning
$ claude plugin marketplace add dotnet/skills (README-verbatim)
β
"Successfully added marketplace: dotnet-agent-skills (declared in user settings)"
$ claude plugin install dotnet11@dotnet-agent-skills
β
"Successfully installed plugin: dotnet11@dotnet-agent-skills (scope: user)"
$ claude plugin details dotnet11@dotnet-agent-skills
β
dotnet11 0.1.1, 1 skill (system-text-json-net11), projected ~200 always-on + ~3.7k on-invoke tokens
$ claude plugin uninstall dotnet11@dotnet-agent-skills
β
"Successfully uninstalled plugin: dotnet11 (scope: user)"
$ claude plugin marketplace remove dotnet-agent-skills
β
"Successfully removed marketplace: dotnet-agent-skills"; host left clean
Pass rate: 6 of 8. The canonical install path works end to end; strict validation fails everywhere on the same two cosmetic metadata fields.
Run C - Functional verification
$ python3 plugins/dotnet-test/skills/find-untested-sources/scripts/find_untested_sources.py --help (Python 3.9, tree-sitter-language-pack 0.9.1 installed)
β "ERROR: tree-sitter-language-pack is not installed" (false: installed; the py3.9 wheel lacks the process API)
$ same command under Python 3.11 venv, same package version
β
usage text prints: --lang {csharp,go,java,javascript,python,ruby,rust,tsx,typescript}, positional root
$ run against committed fixture with no tests (fixtures/needs-wrappers)
β
correct JSON: 5 source, 0 test, 5 untested, each with declarations (Program, ConsolePrompter, ...) and suggested test paths
$ run against committed fixture with tests (grade-tests/production-available)
β
correct JSON: 1 source, 1 test, 0 untested, 0 orphan tests (BankAccount correctly paired with BankAccountTests)
$ run against a nonexistent directory
β
clean rejection: "ERROR: not a directory", exit 1
$ npx skills add dotnet/skills --skill dotnet-webapi --agent hermes-agent --copy --yes
β
lands ./.hermes/skills/dotnet-webapi/SKILL.md (project level)
$ diff landed SKILL.md against the clone
β
byte-identical; skills-lock.json records source dotnet/skills, skillPath plugins/dotnet-aspnetcore/skills/dotnet-webapi/SKILL.md, sha256 9f9ca386...
$ dashboard data manifest fetch
β
22,454 sessions, 515 skill-eval combinations, 17 plugin namespaces, generated 2026-08-30T16:28Z (2 days old)
Functional pass rate: 7 of 8. The one failure is the Python 3.9 trap with its misleading error message, documented in The Bad.
What the runs tell you
The install surfaces are solid: every documented marketplace path we could exercise worked first try, and the skills CLI delivered byte-identical content with a lock file for Hermes, a host the README never mentions. The functional core we could reach (the untested-source finder) produces correct structured output on both a positive and a covered fixture, but its dependency handling punishes the macOS system-Python user. What we could not exercise is the .NET-specific machinery: the Roslyn LSP bridge, the PowerShell helpers, and the agent workflows all need a .NET SDK or pwsh on the host.
Setup Walkthrough
- In Claude Code or Copilot CLI:
/plugin marketplace add dotnet/skills, then/plugin install dotnet-test@dotnet-agent-skills(or any of the 15 published plugins), then restart. Verified working exactly as documented. - In Codex CLI v0.121.0+:
codex plugin marketplace add dotnet/skills, then browse/pluginsunder the dotnet-agent-skills tab. The manifest is committed in-repo; we verified its structure but did not run Codex. - In Cursor: the repo is a Cursor plugin marketplace; search ".NET" in the marketplace panel. We did not run Cursor.
- For any other agent (including Hermes and OpenClaw):
npx skills add dotnet/skills --skillfrom the project root; the skill lands under ./.hermes/skills/ (or your host's equivalent) byte-identical, with skills-lock.json for reproducibility. Verified.--agent --copy --yes - If you use the Python helper in dotnet-test/find-untested-sources, use Python 3.11 or newer. On 3.9 the dependency installs but the import fails with an error that wrongly tells you to install what you already have.
- The eng/skill-validator tooling builds with the .NET SDK (global.json pins the version) and ships as nightly GitHub Release artifacts; day-to-day skill consumers never need it.
Alternatives
- microsoft/azure-skills (reviewed 4.5/5) covers the Azure deployment and diagnosis pipeline rather than the C# language surface; the two are complementary, not rivals.
- github/awesome-copilot carries community one-off .NET skills (dotnet-best-practices at ~14.6K skills.sh installs) with no eval harness and no vendor backing; prefer it only for single-purpose prompts.
- affaan-m/ECC (reviewed 4.5/5) bundles a dotnet-patterns skill inside a 278-skill cross-harness pack; broader coverage, far less .NET depth, no per-skill measurement.
- wshobson/agents ships a dotnet-backend-patterns agent (~17.1K installs) as a single-file alternative when you want one prompt, not a plugin ecosystem.
Reviews stay honest because nobody pays us to publish them. If this one saved you time, throw a coin.
Tip the reviewer- reviewed by
- GearScope
- tested
- 2026-09-01 · macOS (Apple Silicon)
- last verified
- 2026-09-01
- depth
- HANDS-ON
- sponsorship
- none, ever
Don't install your next skill blind.
Every week: the shortlist of skills worth installing β and the ones to skip β from 100+ hands-on tests. No spam, no affiliate links.