dotnet-mcp-server

Implement and test MCP servers in .NET using the ModelContextProtocol C# SDK.

2|Updated Jul 18, 2026
One-click install
npx skills add https://github.com/Arasz/ai-badger --skill dotnet-mcp-server-arasz
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: dotnet-mcp-server
Source: https://github.com/Arasz/ai-badger/tree/main/features/dotnet/skills/dotnet-workload/references/dotnet-mcp-server
Command: npx skills add https://github.com/Arasz/ai-badger --skill dotnet-mcp-server-arasz

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes scripts (resource) and references (resource) components.

What problem does it solve? Building a Model Context Protocol server in .NET involves non-obvious SDK behaviors, transport wiring traps, and testing gaps that only surface at runtime, such as dropped tool registrations, stdout pollution on stdio transports, and DI failures invisible to unit tests. ## Core Features & Use Cases - Tool and prompt implementation patterns: Attribute-based tools with [McpServerTool], DI-injected typed HttpClients, Task<string> return contracts, and SDK 2.x specifics like McpException error signaling and tool-name derivation. - Transport and host wiring: stdio, Streamable HTTP, and dual-mode servers with case-insensitive transport selection, CLI argument handling that never corrupts the JSON-RPC stream, and dotnet tool packaging guidance. - Testing at every layer: MockHttpHandler unit tests, host-level tool-inventory tests that assert the registered surface, and E2E tests over HTTP with WebApplicationFactory plus a stdio handshake probe script. - Use Case: When adding a new MCP tool backed by a REST API, follow the TDD sequence to write mock-HTTP tests first, register the typed HttpClient and WithTools<T>() in Program.cs, and verify the shipped binary exposes the full tool set. ## Quick Start Ask the agent to scaffold a new .NET MCP server with one REST-backed tool, wired for stdio transport, including unit tests and a tool-registration inventory test.

Frequently Asked Questions about dotnet-mcp-server

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

FAQPage Schema
How do I create an MCP server tool in C#?

Create an internal sealed class with methods annotated [McpServerTool] and [Description], inject a typed HttpClient via the constructor, and register it with AddMcpServer().WithTools<T>() in Program.cs. Return Task<string> with serialized JSON rather than Task<object> to avoid JsonElement boxing issues.

How do I test .NET MCP tools that call REST APIs?

Use a mock HttpMessageHandler that captures the request method, URI, and JSON body while returning a canned response. Construct the tool class directly with an HttpClient wrapping that handler, and cover non-success status codes with a single [Theory] using InlineData.

Does the MCP C# SDK support HTTP transport as well as stdio?

Yes, the ModelContextProtocol.AspNetCore package adds Streamable HTTP via WithHttpTransport and MapMcp, requiring the Web SDK. A dual-mode server selects transport from an env var with a case-insensitive comparison, since a bare == "http" check silently falls back to stdio for HTTP or Http.

Why does my MCP server ship fewer tools than the tool class defines?

A dropped .WithTools<T>() registration in Program.cs removes tools at runtime while class-level reflection tests stay green. Guard against this with a host-level test that enumerates the actually registered tool names, plus a live tools/list probe against the published binary after an initialize handshake.

Why does my MCP tool error message not reach the client?

The SDK only includes the exception message in the error result when the exception is McpException; other exceptions surface as a generic message. Throw McpException with a coded message or return a CallToolResult with IsError = true and explicit TextContentBlock content.

Can I add command-line arguments to a stdio MCP server?

Yes, but parse-first with System.CommandLine and never invoke default actions, because help renders to stdout and would corrupt the JSON-RPC stream. Detect help via parseResult.Action is HelpAction and render to stderr with your own renderer.