Creating an MCP Server with .NET: A Complete Guide

Creating an MCP (Model Context Protocol) server with .NET involves several steps, from setting up your project environment to defining tools that expose functionalities to AI clients.
This guide walks you through the complete process of building a robust MCP server using C#, leveraging the official MCP C# SDK, and integrating best practices for development, debugging, and deployment.
What Is an MCP Server?
The Model Context Protocol (MCP) is a protocol that allows AI models—such as large language models (LLMs)—to interact with external tools and data sources securely and efficiently. An MCP server exposes a set of "tools" (functions or APIs) that AI clients can invoke to perform operations like fetching data, running computations, or accessing external services.
By building an MCP server in .NET, you create a backend service in C# that enables AI assistants to extend their capabilities by invoking tools from your server.
Prerequisites and Setup
1. Environment and Language
.NET (C#) is a great choice for developing MCP servers thanks to its performance, stability, and mature tooling. The MCP C# SDK is available on NuGet as a prerelease package.
2. Install MCP SDK and Dependencies
dotnet add package ModelContextProtocol --prerelease
dotnet add package Microsoft.Extensions.Hosting
dotnet add package Microsoft.Extensions.Logging
3. Create a New Project
dotnet new console -n MyMcpServer
cd MyMcpServer
Building the MCP Server
1. Configure the Server Host
In Program.cs
, set up logging, transport, and tool registration:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;
using System.ComponentModel;
var builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddConsole(consoleLogOptions =>
{
consoleLogOptions.LogToStandardErrorThreshold = LogLevel.Trace;
});
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
await builder.Build().RunAsync();
2. Define Your Tools
Tools are methods exposed to AI clients. Each tool must be decorated with the appropriate MCP attributes.
Example: Echo Tool
using System.ComponentModel;
using ModelContextProtocol.Server;
[McpServerToolType]
public static class EchoTool
{
[McpServerTool, Description("Echoes the message back to the client.")]
public static string Echo(string message) => $"Hello from C#: {message}";
[McpServerTool, Description("Echoes in reverse the message sent by the client.")]
public static string ReverseEcho(string message) => new string(message.Reverse().ToArray());
}
3. Build Advanced Tools
You can implement tools that call external services.
Example: Joke API Tool
using System.Net.Http;
using System.Threading.Tasks;
using System.ComponentModel;
using ModelContextProtocol.Server;
[McpServerToolType]
public class JokeTool
{
private readonly HttpClient _httpClient;
public JokeTool()
{
_httpClient = new HttpClient
{
BaseAddress = new Uri("https://v2.jokeapi.dev/joke/")
};
}
[McpServerTool, Description("Fetches jokes from a specified category.")]
public async Task<string> GetJoke(
[Description("Category of jokes (e.g., 'Programming', 'Misc', 'Christmas').")] string category,
[Description("Number of jokes to retrieve, default is 10.")] int amountOfJokes = 10)
{
try
{
var response = await _httpClient.GetAsync($"{category}?amount={amountOfJokes}");
return await response.Content.ReadAsStringAsync();
}
catch
{
return "Error fetching jokes.";
}
}
}
Running and Testing the Server
Run the Server
dotnet run
Your MCP server will start and communicate via standard input/output (studio).
Debugging Tips
- Use console logs for monitoring.
- Use MCP Inspector or Claude Developer Tools for debugging interactions.
- Enable Chrome DevTools in Claude Desktop for client-side inspection.
Advanced Configurations
1. Use HTTP Transport
To expose your MCP server via HTTP:
builder.Services
.AddMcpServer()
.WithHttpServerTransport()
.WithToolsFromAssembly();
Then, map the endpoint:
app.MapMcpSse(); // SSE endpoint for MCP
2. Containerize Your Server
Add the following to your .csproj
file:
<PublishContainer>true</PublishContainer>
<ContainerImageName>yourdockerhubusername/mcpserver</ContainerImageName>
<ContainerBaseImage>alpine</ContainerBaseImage>
<RuntimeIdentifiers>linux-x64;linux-arm64</RuntimeIdentifiers>
Publish the container:
dotnet publish /t:PublishContainer -p ContainerRegistry=docker.io
Best Practices
Security
- Protect tools with authentication (OAuth, API keys).
- Sanitize all input parameters.
- Limit local execution risks for stdio servers.
Performance
- Optimize tool logic and query paths.
- Paginate large results.
- Cache frequently accessed data.
Error Handling
- Use try/catch blocks to manage failures.
- Return helpful error messages.
- Log all critical issues.
Documentation
- Use
[Description]
attributes thoroughly. - Provide parameter examples for clarity.
- Use meaningful, action-based tool names.
Troubleshooting Common Challenges
AI Clients Don't Detect Tools
- Ensure tools are clearly named and described.
- Use proper attribute annotations and examples.
Handling Big Datasets
- Implement pagination and filtering.
- Limit result sizes and payloads.
Managing Tool Risk
- Group tools by risk category.
- Add confirmation flows for sensitive actions.
Complex Tool Queries
- Provide advanced filtering options.
- Build specific tools for specialized queries.
Summary
To build a fully functional MCP server in .NET:
- Set up a new .NET console app.
- Install the MCP SDK and configure the server.
- Register and expose tools to AI clients.
- Test, debug, and containerize your solution.
- Follow best practices for security, performance, and documentation.
This architecture empowers AI applications to call your server securely and intelligently making your systems more powerful, automated, and AI-ready.