dotnet-cli-parsing

Implements CLI argument parsing for .NET console apps and global tools using System.CommandLine 2.0 GA.

2|Updated Aug 2, 2026
One-click install
npx skills add https://github.com/Arasz/ai-raccoon --skill dotnet-cli-parsing-arasz
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: dotnet-cli-parsing
Source: https://github.com/Arasz/ai-raccoon/tree/main/.ai-badger/skills/learned/uncategorized/dotnet-cli-parsing
Command: npx skills add https://github.com/Arasz/ai-raccoon --skill dotnet-cli-parsing-arasz

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill requires System.CommandLine, and includes references (resource) components.

What problem does it solve? Adding command-line argument parsing to .NET console apps and global dotnet tools is full of traps: the System.CommandLine 2.0 GA API differs sharply from the beta API most blog posts show, help text leaks into stdout and corrupts stdio MCP/JSON-RPC protocol streams, and parse-first entry points break WebApplicationFactory-based E2E tests. This Skill provides empirically verified, version-pinned guidance so these mistakes are avoided. ## Core Features & Use Cases - Parser selection guidance: Compares System.CommandLine 2.0.x GA, Spectre.Console.Cli, Microsoft.Extensions.Configuration.CommandLine, Cocona (archived), and McMaster.Extensions.CommandLineUtils with verified version and status data. - Pinned System.CommandLine 2.0.10 GA idioms: Parse-first patterns, help/version action detection, instance-based option reads via GetValue<T>(Option<T>), Option.Validators for custom value grammars, duplicate-alias handling, and the two-root pattern for optional subcommands. - Protocol-stream and test-host traps: Routes all CLI output to stderr for stdio MCP servers, declares hidden no-op options for WebApplicationFactory's injected flags, and covers secrets policy, wildcard shell-expansion diagnostics, and config-verb trees. - Use Case: When adding a serve subcommand with --port and --idle-timeout options to a .NET MCP server, use this Skill to wire parse-first argument handling, validate values with Option.Validators, keep help off stdout, and keep WebApplicationFactory E2E tests green. ## Quick Start Use the dotnet-cli-parsing skill to add System.CommandLine 2.0 GA argument parsing with stderr-safe help rendering to my .NET console app.

Frequently Asked Questions about dotnet-cli-parsing

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I parse command-line arguments in a .NET console app?

Use System.CommandLine 2.0.x GA, the default choice for flat option sets. Call root.Parse(args, new ParserConfiguration { EnablePosixBundling = true }) directly — the beta CommandLineBuilder and UseDefaults() APIs no longer exist in GA.

System.CommandLine vs Spectre.Console.Cli — which should I use?

System.CommandLine 2.0.x is GA, MIT-licensed, dependency-free on net8.0, and used by the dotnet CLI itself, making it the default for flat option sets. Spectre.Console.Cli is a full command framework with DI and nested commands, which is overkill for roughly ten flat options.

Why does System.CommandLine help output break my stdio MCP server?

System.CommandLine renders help to stdout by default, which corrupts a JSON-RPC protocol stream on stdout. Fix it by invoking with parseResult.Invoke(new InvocationConfiguration { Output = writer, Error = writer }) where both writers are Console.Error, and pin it with a test asserting zero bytes reach stdout.

Why does WebApplicationFactory fail after switching to parse-first CLI parsing?

WebApplicationFactory invokes the real entry point with --environment, --contentRoot, and --applicationName arguments, which a parse-first entry point rejects as unknown options. Declare the three as hidden no-op options on the root command so the triplet parses with zero errors.

How do I validate custom option values in System.CommandLine 2.0 GA?

Option.Validators is the only native parse-error hook in GA — there is no ParseArgument or ErrorMessage property. Add a validator delegate that reads the raw token with result.GetValueOrDefault<string>() and reports failures via result.AddError("...").

Can a root command with subcommands be invoked without a verb?

No — a RootCommand with subcommands cannot be invoked bare in 2.0.10 GA; parsing flags without a verb yields "Required command was not provided." The working pattern builds two roots over the same options: a full tree for help and verbs, and a launch-only root for verb-less flag sets.