ModelContextProtocol (MCP) SDK for .NET
MCP Servers in .NET
Creating MCP servers is fairly straightforward in .NET. You can use the NuGet packages ModelContextProtocol
and ModelContextProtocol.AspNetCore
. And its GitHub repo.
ModelContextProtocol
will be sufficient if you use stdio transport.
The libraries also support sampling (making calls back to the LLM from your tool implementation). You can build clients and servers using these libraries.
Getting your MCP server AOT ready
In order to get your MCP server AOT ready, (at least) the following steps are required
Registering Tools
Get rid of the .WithToolsFromAssembly()
call which registers all tools from the assembly. This call uses reflection. Replace with one call per class which contains your [McpServerTool]
annotated methods.
.WithTools<MyCustomMcpServerTool>()
JSON Serialization for structured data
If you return any classes/structs/records from your tools which require JSON serialization, first declare a JsonSerializerContext
derived type annotated with the types which require serialization. This type will be source-generator implemented (this is standard .NET, not MCP specific).
[JsonSerializable(typeof(PackageVersion))]
[JsonSerializable(typeof(List<PackageVersion>))]
[JsonSerializable(typeof(IEnumerable<PackageVersion>))]
[JsonSourceGenerationOptions(WriteIndented = true)]
internal partial class CustomJsonSerializerContext : JsonSerializerContext;
Add this CustomJsonSerializerContext to the TypeInfoResolverChain of the JsonSerializerOptions. Custom JsonSerializerOptions can be passed to the .WithTools<MyCustomMcpServerTool>()
call:
var customJsonSerializerOptions = new JsonSerializerOptions(McpJsonUtilities.DefaultOptions);
customJsonSerializerOptions.TypeInfoResolverChain.Add(CustomJsonSerializerContext.Default);
hostBuilder.Services.AddMcpServer()
...
.WithTools<MyCustomMcpServerTool>(serializerOptions: customJsonSerializerOptions)
Dotnet template
Microsoft released set of project templates which also includes a project template for MCP servers.
Install using
dotnet new install Microsoft.Extensions.AI.Templates
Then create a new project using
dotnet new mcpserver
Short intro blog post on MSDN Building Your First MCP Server with .NET
Packaging as NuGet tool
MCP Servers are similar to .NET tools when it comes to packaging.
NuGet is currently introduding a new PackagType=McpServer
in order to annotate NuGet packages containing MCP servers, and to facilitate discovery of MCP servers using the NuGet search apis.
Note: support for this package type requires recent versions of the .NET SDK. Even if your .csproj has been annotated with <PackageType>McpServer</PackageType>
, this value might not propagate to the manifest of the NuGet package. I am currently using the Preview6 of the .NET 10 SDK for this.
Discovery
You can search for this PackageType on nuget.org like this
https://www.nuget.org/packages?q=mcpserver
AOT aka platform specific packages
Unfortunately, the support for platform specific packages for dotnet tools or MCP servers is not where it should be … but it’s getting better with .NET 10.
Basically, when AOT compiling your dotnet tool/MCP server and publishing as NuGet, you will most likely be ending up with separate NuGet packages, one per runtime identifier. Your packages will be named <Your.NuGet.Package>.<rid>.nupkg
, for example Cloudsiders.SampleMcpServer.linux-x64.nupkg
.
Chet Husk has a little sample project on GitHub which shows the properties you will be setting in your .csproj in order to use dotnet pack -r <rid>
. Be aware: dotnet pack only introduces the -r