Releases: modelcontextprotocol/csharp-sdk
v0.1.0-preview.5
This release extends progress notification support, adds JsonSerializerOptions parameters for tool and prompt operations, adds initial OpenTelemetry observability, and reorganizes ASP.NET Core extension methods into the standard namespace.
Breaking Changes
Refer to the C# SDK Versioning documentation for details on versioning and breaking change policies.
- Extend progress notification support #163
IMcpClientbase interface changed toIMcpEndpointSamplingCapability.SamplingHandlerdelegate signature gainedIProgress<ProgressNotificationValue>parameter
- Put MapMcp in Microsoft.AspNetCore.Builder namespace #171
McpEndpointRouteBuilderExtensionsmoved fromModelContextProtocol.AspNetCoretoMicrosoft.AspNetCore.Buildernamespace
- Split StdioClient/ServerTransports into Stdio : Stream #172
StdioServerTransportstream-based constructor removed; base class changed fromTransportBasetoStreamServerTransport;StdioClientStreamTransportreplaced byStdioClientSessionTransportand newStreamClientTransport- Migration: Use
StreamServerTransportfor custom stream-based servers; updateStdioServerTransportconstructor calls
- Allow JsonSerializerOptions parameters #182
- New
JsonSerializerOptions?parameter inserted beforecancellationTokeninListToolsAsync,EnumerateToolsAsync,GetPromptAsync SendNotificationAsyncextension method removed fromMcpClientExtensions
- New
- Remove McpServerConfig.Arguments property #192
McpServerConfig.Argumentsproperty removed- Migration: Use
McpServerConfig.TransportOptions["arguments"]instead
What's Changed
- Put MapMcp in Microsoft.AspNetCore.Builder namespace #171 by @halter73
- Split StdioClient/ServerTransports into Stdio : Stream #172 by @stephentoub
- Fixing WithPromptsFromAssembly #174 by @aaronpowell
- Enable IsAotCompatible for ModelContextProtocol.AspNetCore #175 by @stephentoub
- Configure hosted stdio servers to log to stderr #173 by @halter73
- Fix pagination handling in McpServer #177 by @stephentoub
- Extend progress notification support #163 by @Tyler-R-Kendrick (co-authored by @stephentoub)
- Make supposedly unreachable code less reachable #178 by @halter73
- Add initial Activity / Metric support #183 by @stephentoub
- Allow JsonSerializerOptions parameters for user-defined inputs and hardcode everything else to the source generator #182 by @eiriktsarpalis
- Write "event: message" to SSE response #192 by @halter73
- Changed the name of the ActivitySource and Metric to clarify that the semantic conventions have not been ratified yet #194 by @samsp-msft (co-authored by @stephentoub)
- Allow override of name and description of McpClientTool #165 by @PederHP
- Hardcode the source generator in one remaining location and simplify McpJsonUtilities #204 by @eiriktsarpalis
- Reduce dependencies to 8.x versions of packages #195 by @stephentoub
- Mark samples as AOT compatible #184 by @agocke (co-authored by @stephentoub)
Documentation Updates
Test Improvements
- Expand a few DI-related tests #201 by @stephentoub
- Add more unit tests #139 by @stvansolano (co-authored by @stephentoub)
Repository Infrastructure Updates
- Bump package version #169 by @eiriktsarpalis
Acknowledgements
- @Tyler-R-Kendrick made their first contribution in #163
- @agocke made their first contribution in #184
- @samsp-msft made their first contribution in #194
- @stvansolano made their first contribution in #139
- @zh6335901 submitted issue #154 (resolved by #165)
- @AArnott @JamesNK @lmolkova @WeihanLi reviewed pull requests
Full Changelog: v0.1.0-preview.4...v0.1.0-preview.5
v0.1.0-preview.4
This release introduces the ModelContextProtocol.AspNetCore package for hosting MCP servers in ASP.NET Core applications with SSE transport support.
Breaking Changes
Refer to the C# SDK Versioning documentation for details on versioning and breaking change policies.
- Add ModelContextProtocol.AspNetCore #160
HttpListenerSseServerTransportremovedIServerTransportinterface removedMapMcpSserenamed toMapMcpand moved to the newModelContextProtocol.AspNetCorepackage
What's Changed
- Add ModelContextProtocol.AspNetCore #160 by @halter73 (co-authored by @eiriktsarpalis @jeffhandley)
Repository Infrastructure Updates
- Bump package version #167 by @eiriktsarpalis
Acknowledgements
- @stephentoub reviewed pull requests
Full Changelog: v0.1.0-preview.3...v0.1.0-preview.4
v0.1.0-preview.3
This release overhauls the resource system, refactors transports for graceful shutdown, introduces prompt support with McpServerPrompt and McpClientPrompt, and adds progress reporting and annotation support.
Breaking Changes
Refer to the C# SDK Versioning documentation for details on versioning and breaking change policies.
- Add ToolAnnotations support #124
McpServerToolAttributeconstructor no longer accepts a positional string; must useName = "..."instead
- Overhaul of Resources #125
ResourceContentschanged to an abstract class;TextandBlobproperties removed- Must use
TextResourceContentsorBlobResourceContentssubclasses instead
- Add [McpServerPrompt] support #126
ListPromptsAsyncreturn type changedGetPromptAsyncparameter type changedIMcpServerBuildernamespace moved- All
With*Handlerextension methods deleted
- Add missing Annotations #138
Annotatedabstract record base class deletedAnnotationsproperty inlined intoContent,Resource, andResourceTemplate
- Refactor transports to help enable graceful shutdown #142
McpServerHostedServicedeletedIClientTransport.ConnectAsyncnow returnsITransportinstead of the previous typeStartAsyncreplaced byRunAsync
- Improve progress reporting #145
OperationNamesclass deleted; replaced byRequestMethods
What's Changed
- Fix some issues with Native AOT #130 by @stephentoub
- Add ToolAnnotations support #124 by @stephentoub
- Add missing Annotations #138 by @stephentoub
- Remove Assembly.GetCallingAssembly #133 by @stephentoub
- Refactor transports to help enable graceful shutdown #142 by @halter73 (co-authored by @stephentoub)
- Overhaul of Resources #125 by @aaronpowell (co-authored by @stephentoub @PederHP)
- Fix binding to wrong overload in WithTools #152 by @stephentoub
- Improve progress reporting #145 by @stephentoub
- Add
[McpServerPrompt]support #126 by @stephentoub - Implement cancellation notifications #146 by @stephentoub
Documentation Updates
- Fix sample in README #136 by @BrennanConroy
Repository Infrastructure Updates
- Bump version to 0.1.0-preview.3 #162 by @jeffhandley
Acknowledgements
- @BrennanConroy made their first contribution in #136
- @stvansolano reviewed pull requests
Full Changelog: v0.1.0-preview.2...v0.1.0-preview.3
v0.1.0-preview.2
This release overhauls tool handling, makes options types fully mutable, adds logging capability, and improves serialization.
Breaking Changes
Refer to the C# SDK Versioning documentation for details on versioning and breaking change policies.
- Overhaul tool handling #89
McpToolAttributerenamed toMcpServerToolAttribute;McpToolTypeAttributerenamed toMcpServerToolTypeAttributeWithTools()renamed toWithToolsFromAssembly()ListToolsAsyncreturn type changed fromIAsyncEnumerable<Tool>toTask<IList<McpClientTool>>CallToolAsyncparameter changed fromDictionary<string, object>toIReadOnlyDictionary<string, object?>
- Make options types fully mutable #107
McpClientOptions,Implementation, and all capability types changed fromrecordtoclassinit-only setters changed toset;withexpressions on these types will no longer compile
- Fix enum serialization #61
Role,LoggingLevel, andContextInclusionenums now useJsonStringEnumConverterwith[JsonStringEnumMemberName]instead of[JsonPropertyName]- This is a serialization format change; any code depending on the previous serialized form needs to be updated
- List tools from DI once #115
ServerInstructionsproperty removed fromMcpServerMcpServerHostedServiceis no longer public
What's Changed
- Logging Capability #53 by @PederHP (co-authored by @stephentoub)
- Fix enum serialization #61 by @zaevi (co-authored by @eiriktsarpalis)
- Make client config optional to McpClientFactory.CreateAsync #65 by @stephentoub (co-authored by @eiriktsarpalis)
- Fix stdio encoding issue: Enforce explicit UTF-8 for correct Unicode handling #73 by @willibrandon (co-authored by @stephentoub)
- Overhaul tool handling #89 by @stephentoub
- Avoid race starting SseResponseStreamTransport #91 by @halter73
- Adding a base class for request params that exposes the progressToken #99 by @aaronpowell (co-authored by @stephentoub)
- Add
[McpServerTool]support for instance methods #100 by @stephentoub - complete fix for SampleLlmTool discovery #102 by @NeverMorewd (co-authored by @stephentoub)
- Make options types fully mutable #107 by @halter73
- Configurable messages endpoint for SSE transport #109 by @edis-uipath
- Use different logger categories for client and server in McpJsonRpcEndpoint #110 by @halter73
- List tools from DI once #115 by @halter73
- Adding support for returning collections from tools #116 by @aaronpowell
Documentation Updates
- Add nuget badge to README #58 by @stephentoub
- docs: update McpToolAttribute name comment #63 by @WeihanLi
- docs: add McpServerOptionsSetup code comment #77 by @JaneConan
- Update documentation configuration #86 by @localden (co-authored by @eiriktsarpalis)
- Add acknowledgements to README #94 by @mikekistler (co-authored by @stephentoub)
- Add links to API docs from README.md #96 by @eiriktsarpalis
- Add package installation to README #101 by @timheuer
- Samples for quickstart docs #104 by @aaronpowell
Test Improvements
- Run integration test SSE server in process #56 by @halter73
- Remove reflection from Connect test #57 by @jaredpar (co-authored by @stephentoub)
- Fix private reflection #60 by @jaredpar
- Add XunitLoggerProvider #81 by @halter73
Repository Infrastructure Updates
- Adding code coverage to tests in workflow #75 by @aaronpowell (co-authored by @stephentoub @eiriktsarpalis)
- Adding merge files to gitignore #78 by @aaronpowell
- Add gitattributes #98 by @halter73
- Set up package publishing for daily, manual, and release builds #118 by @jeffhandley (co-authored by @Copilot)
Acknowledgements
- @PederHP made their first contribution in #53
- @jaredpar made their first contribution in #57
- @zaevi made their first contribution in #61
- @WeihanLi made their first contribution in #63
- @willibrandon made their first contribution in #73
- @aaronpowell made their first contribution in #75
- @JaneConan made their first contribution in #77
- @localden made their first contribution in #86
- @timheuer made their first contribution in #101
- @NeverMorewd made their first contribution in #102
- @edis-uipath made their first contribution in #109
- @colombod @Meir017 reviewed pull requests
Full Changelog: v0.1.0-preview.1.25171.12...v0.1.0-preview.2
v0.1.0-preview.1.25171.12
MCP C# SDK
https://www.nuget.org/packages/ModelContextProtocol/0.1.0-preview.1.25171.12
The official C# SDK for the Model Context Protocol, enabling .NET applications, services, and libraries to implement and interact with MCP clients and servers.
Note
This is a preview release. Breaking changes can be introduced without prior notice.
About MCP
The Model Context Protocol (MCP) is an open protocol that standardizes how applications provide context to Large Language Models (LLMs). It enables secure integration between LLMs and various data sources and tools.
For more information about MCP:
Getting Started (Client)
To get started writing a client, the McpClientFactory.CreateAsync method is used to instantiate and connect an IMcpClient
to a server, with details about the client and server specified in McpClientOptions and McpServerConfig objects.
Once you have an IMcpClient, you can interact with it, such as to enumerate all available tools and invoke tools.
McpClientOptions options = new()
{
ClientInfo = new() { Name = "TestClient", Version = "1.0.0" }
};
McpServerConfig config = new()
{
Id = "everything",
Name = "Everything",
TransportType = TransportTypes.StdIo,
TransportOptions = new()
{
["command"] = "npx",
["arguments"] = "-y @modelcontextprotocol/server-everything",
}
};
var client = await McpClientFactory.CreateAsync(config, options);
// Print the list of tools available from the server.
await foreach (var tool in client.ListToolsAsync())
{
Console.WriteLine($"{tool.Name} ({tool.Description})");
}
// Execute a tool (this would normally be driven by LLM tool invocations).
var result = await client.CallToolAsync(
"echo",
new() { ["message"] = "Hello MCP!" },
CancellationToken.None);
// echo always returns one and only one text content object
Console.WriteLine(result.Content.First(c => c.Type == "text").Text);You can find samples demonstrating how to use ModelContextProtocol with an LLM SDK in the samples directory, and also refer to the tests project for more examples. Additional examples and documentation will be added as in the near future.
Clients can connect to any MCP server, not just ones created using this library. The protocol is designed to be server-agnostic, so you can use this library to connect to any compliant server.
Tools can be exposed easily as AIFunction instances so that they are immediately usable with IChatClients.
// Get available functions.
IList<AIFunction> tools = await client.GetAIFunctionsAsync();
// Call the chat client using the tools.
IChatClient chatClient = ...;
var response = await chatClient.GetResponseAsync(
"your prompt here",
new()
{
Tools = [.. tools],
});Getting Started (Server)
Here is an example of how to create an MCP server and register all tools from the current application.
It includes a simple echo tool as an example (this is included in the same file here for easy of copy and paste, but it needn't be in the same file...
the employed overload of WithTools examines the current assembly for classes with the McpToolType attribute, and registers all methods with the
McpTool attribute as tools.)
using ModelContextProtocol;
using ModelContextProtocol.Server;
using Microsoft.Extensions.Hosting;
using System.ComponentModel;
var builder = Host.CreateEmptyApplicationBuilder(settings: null);
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithTools();
await builder.Build().RunAsync();
[McpToolType]
public static class EchoTool
{
[McpTool, Description("Echoes the message back to the client.")]
public static string Echo(string message) => $"hello {message}";
}More control is also available, with fine-grained control over configuring the server and how it should handle client requests. For example:
using ModelContextProtocol.Protocol.Transport;
using ModelContextProtocol.Protocol.Types;
using ModelContextProtocol.Server;
using Microsoft.Extensions.Logging.Abstractions;
McpServerOptions options = new()
{
ServerInfo = new() { Name = "MyServer", Version = "1.0.0" },
Capabilities = new()
{
Tools = new()
{
ListToolsHandler = async (request, cancellationToken) =>
{
return new ListToolsResult()
{
Tools =
[
new Tool()
{
Name = "echo",
Description = "Echoes the input back to the client.",
InputSchema = new JsonSchema()
{
Type = "object",
Properties = new Dictionary<string, JsonSchemaProperty>()
{
["message"] = new JsonSchemaProperty() { Type = "string", Description = "The input to echo back." }
}
},
}
]
};
},
CallToolHandler = async (request, cancellationToken) =>
{
if (request.Params?.Name == "echo")
{
if (request.Params.Arguments?.TryGetValue("message", out var message) is not true)
{
throw new McpServerException("Missing required argument 'message'");
}
return new CallToolResponse()
{
Content = [new Content() { Text = $"Echo: {message}", Type = "text" }]
};
}
throw new McpServerException($"Unknown tool: '{request.Params?.Name}'");
},
}
},
};
await using IMcpServer server = McpServerFactory.Create(new StdioServerTransport("MyServer"), options);
await server.StartAsync();
// Run until process is stopped by the client (parent process)
await Task.Delay(Timeout.Infinite);License
This project is licensed under the MIT License.