{
  "schema": "https://ai-atoms.com/schemas/skill-v1.json",
  "type": "skill",
  "id": "skill/mcp-csharp-debug",
  "version": "1.0.1",
  "name": "mcp-csharp-debug",
  "description": "Run, debug, and interactively test C# MCP servers. Covers local execution, IDE debugging with breakpoints, MCP Inspector for protocol-level testing, and GitHub Copilot Agent Mode integration.",
  "system_prompt_fragment": "# C# MCP Server Debugging\n\nRun, debug, and interactively test C# MCP servers. Covers local execution, IDE debugging with breakpoints, MCP Inspector for protocol-level testing, and GitHub Copilot Agent Mode integration.\n\n## When to Use\n\n- Running an MCP server locally for the first time\n- Configuring VS Code or Visual Studio to debug an MCP server\n- Testing tools interactively with MCP Inspector\n- Verifying tools appear in GitHub Copilot Agent Mode\n- Diagnosing issues: tools not discovered, protocol errors, server crashes\n- Setting up `mcp.json` or `.mcp.json` configuration\n\n## Stop Signals\n\n- **No project yet?** → Use `mcp-csharp-create` first\n- **Need automated tests?** → Use `mcp-csharp-test`\n- **Production deployment issue?** → Use `mcp-csharp-publish`\n\n## Inputs\n\n| Input | Required | Description |\n|-------|----------|-------------|\n| Project path | Yes | Path to the `.csproj` file or project directory |\n| Transport type | Recommended | `stdio` or `http` — detect from `.csproj` if not specified |\n| IDE | Recommended | VS Code or Visual Studio — detect from environment if not specified |\n\n**Agent behavior:** Detect transport type by checking the `.csproj` for a `PackageReference` to `ModelContextProtocol.AspNetCore`. If present → HTTP, otherwise → stdio.\n\n## Workflow\n\n### Step 1: Run the server locally\n\n**stdio transport:**\n```bash\ncd <ProjectDir>\ndotnet run\n```\nThe process starts and waits for JSON-RPC messages on stdin. No output on stdout means it's working correctly.\n\n**HTTP transport:**\n```bash\ncd <ProjectDir>\ndotnet run\n# Server listens on http://localhost:3001 (or configured port)\n```\n\n### Step 2: Generate MCP configuration\n\nDetect the IDE and transport, then create the appropriate config file.\n\n**For VS Code** — create `.vscode/mcp.json`:\n\nstdio:\n```json\n{\n  \"servers\": {\n    \"<ProjectName>\": {\n      \"type\": \"stdio\",\n      \"command\": \"dotnet\",\n      \"args\": [\"run\", \"--project\", \"<path/to/ProjectFile.csproj>\"]\n    }\n  }\n}\n```\n\nHTTP:\n```json\n{\n  \"servers\": {\n    \"<ProjectName>\": {\n      \"type\": \"http\",\n      \"url\": \"http://localhost:3001\"\n    }\n  }\n}\n```\n\n**For Visual Studio** — create `.mcp.json` at solution root (same JSON structure).\n\n**For detailed IDE-specific configuration** (launch.json, environment variables, secrets), see [references/ide-config.md](references/ide-config.md).\n\n### Step 3: Test with MCP Inspector\n\nThe MCP Inspector provides a UI for testing tools, viewing schemas, and inspecting protocol messages.\n\n**stdio server:**\n```bash\nnpx @modelcontextprotocol/inspector dotnet run --project <path/to/ProjectFile.csproj>\n```\n\n**HTTP server:**\n1. Start your server: `dotnet run`\n2. Run Inspector: `npx @modelcontextprotocol/inspector`\n3. Connect to `http://localhost:3001`\n\n**For detailed Inspector capabilities, usage, and troubleshooting**, see [references/mcp-inspector.md](references/mcp-inspector.md).\n\n### Step 4: Test with GitHub Copilot Agent Mode\n\n1. Open GitHub Copilot Chat → switch to **Agent** mode\n2. Click **Select Tools** (wrench icon) → verify your server and tools are listed\n3. Test with a prompt that should trigger your tool\n4. Approve tool execution when prompted\n\n**If tools don't appear — troubleshoot tool discovery:**\n\n1. **Rebuild first** — stale builds are the #1 cause:\n   ```bash\n   dotnet build\n   ```\n   Then restart the MCP server (click Stop → Start in VS Code, or restart `dotnet run`).\n\n2. **Check attributes and registration:**\n   - Verify `[McpServerToolType]` on the class and `[McpServerTool]` on each public method\n   - Methods can be `static` or instance (instance types need DI registration)\n   - Verify `.WithTools<T>()` or `.WithToolsFromAssembly()` in Program.cs\n\n3. **Check `mcp.json`** points to the correct project path\n\n4. If still not appearing, reference the tool explicitly: `Using #tool_name, do X`\n\n### Step 5: Set up breakpoint debugging\n\n1. Set breakpoints in your tool methods\n2. Launch with the debugger:\n   - **VS Code:** F5 (requires `launch.json` — see [references/ide-config.md](references/ide-config.md))\n   - **Visual Studio:** F5 or right-click project → Debug → Start\n3. Trigger the tool (via Inspector, Copilot, or test client)\n4. Execution pauses at breakpoints\n\n**Critical:** Build in Debug configuration. Breakpoints won't hit in Release builds.\n\n### Diagnosing Tool Errors\n\nWhen a tool works standalone but fails through MCP, work through these checks:\n\n1. **Check the MCP output channel** — In VS Code: View → Output → select your MCP server name. Shows protocol errors and server stderr. In Visual Studio: check the Output window for MCP-related messages.\n2. **Attach a debugger** — Set a breakpoint in the failing tool method and step through execution (see Step 5). Check for exceptions being swallowed or unexpected parameter values.\n3. **Test with MCP Inspector** — Call the tool directly through Inspector to isolate whether the issue is in the tool code or the client integration: `npx @modelcontextprotocol/inspector dotnet run --project <path>`\n4. **Check stdout contamination (stdio only)** — Any `Console.WriteLine()` or logging to stdout corrupts the JSON-RPC protocol. Redirect all output to stderr (see Step 6).\n5. **Check common culprits:**\n   - **Serialization errors** — Return types must be JSON-serializable. Avoid circular references.\n   - **DI registration** — Missing service registrations cause runtime exceptions. Check `Program.cs`.\n   - **Parameter binding** — Ensure parameter names and types match the tool schema.\n   - **Unhandled exceptions** — Wrap tool logic in try-catch and log to stderr or a file.\n6. **Enable file logging** — For post-mortem analysis, log to a file:\n   ```csharp\n   builder.Logging.AddFile(\"mcp-debug.log\"); // or use Serilog/NLog\n   ```\n\n### Step 6: Configure logging\n\n**Critical for stdio transport:** Any output to stdout (including `Console.WriteLine`) **corrupts the MCP JSON-RPC protocol** and causes garbled responses or crashes. All logging and diagnostic output must go to stderr.\n\n**stdio transport** — log to stderr only:\n```csharp\nbuilder.Logging.AddConsole(options =>\n    options.LogToStandardErrorThreshold = LogLevel.Trace);\n```\n\n**HTTP transport** — For HTTP transport logging configuration, see [references/ide-config.md](references/ide-config.md).\n\n**In tool methods** — inject `ILogger<T>` via constructor and use `logger.LogDebug()` / `logger.LogError()`. Logging through `ILogger` respects the stderr configuration above.\n\n## Validation\n\n- [ ] Server starts without errors via `dotnet run`\n- [ ] MCP Inspector connects and lists all expected tools\n- [ ] Tool calls via Inspector return expected results\n- [ ] Breakpoints hit when debugging in IDE\n- [ ] Tools appear in GitHub Copilot Agent Mode tool list\n- [ ] stdio: no logging output on stdout (stderr only)\n\n## Common Pitfalls\n\n| Pitfall | Solution |\n|---------|----------|\n| Tools not appearing or stale after changes | **Rebuild first:** `dotnet build`, then restart the server. If still missing, verify `[McpServerToolType]` on class, `[McpServerTool]` on methods, and `WithTools<T>()` or `WithToolsFromAssembly()` in Program.cs |\n| stdio server produces garbled output | `Console.WriteLine()` or logging is writing to stdout. All output **must** go to stderr. Set `LogToStandardErrorThreshold = LogLevel.Trace` on the console logger |\n| HTTP server returns 404 at MCP endpoint | Missing `app.MapMcp()` in Program.cs |\n| Breakpoints not hit | Building in Release mode. Rebuild in Debug: `dotnet build -c Debug`, then restart |\n| Environment variables not passed to server | Add `\"env\"` section to `mcp.json`. For secrets in VS Code, use `\"${input:var_id}\"` syntax |\n| MCP Inspector can't connect to HTTP server | Server not running, or wrong port. Check `dotnet run` output for the listening URL |\n\n## Related Skills\n\n- `mcp-csharp-create` — Create a new MCP server project\n- `mcp-csharp-test` — Automated tests and evaluations\n- `mcp-csharp-publish` — NuGet, Docker, Azure deployment\n\n## Reference Files\n\n- [references/mcp-inspector.md](references/mcp-inspector.md) — Detailed MCP Inspector usage: installation, connecting to servers, feature walkthrough, troubleshooting. **Load when:** user needs detailed Inspector guidance or is having connection issues.\n- [references/ide-config.md](references/ide-config.md) — Complete VS Code and Visual Studio configuration: mcp.json templates, launch.json, environment variables, conditional breakpoints. **Load when:** setting up IDE debugging or configuring environment-specific settings.\n\n## More Info\n\n- [MCP Inspector](https://www.npmjs.com/package/@modelcontextprotocol/inspector/v/0.21.1) — Interactive debugging tool for MCP servers\n- [VS Code MCP documentation](https://code.visualstudio.com/docs/copilot/chat/mcp-servers) — Configuring MCP servers in VS Code",
  "applicable_domains": [
    "code",
    "dotnet",
    "engineering"
  ],
  "invocation": [
    "/mcp-csharp-debug"
  ],
  "tags": [
    "dotnet-ai",
    "dotnet",
    "csharp",
    "microsoft"
  ],
  "authored_by": "anthropics",
  "source_url": "https://github.com/dotnet/skills/blob/main/plugins/dotnet-ai/skills/mcp-csharp-debug/SKILL.md",
  "lifecycle": "stable",
  "category": "dotnet",
  "provenance": {
    "source": "dotnet/skills",
    "source_url": "https://github.com/dotnet/skills/blob/main/plugins/dotnet-ai/skills/mcp-csharp-debug/SKILL.md",
    "author": "Microsoft / .NET Foundation",
    "license": "MIT",
    "notes": "Imported by scripts/import-anthropic-skills.py. Description taken from the fragment's first paragraph: the original SKILL.md description was a mangled YAML indicator and the upstream file no longer exists at its recorded path."
  }
}