Releases: modelcontextprotocol/csharp-sdk
v0.1.0-preview.8
What's Changed
- Bump version to 0.1.0-preview.8 by @eiriktsarpalis in #256
- AI seeded comments from robch and then edited by stephentoub by @robch in #238
- Fix CreateMessageRule.Role to be of type Role by @stephentoub in #264
- Disable STJ reflection for testing. by @eiriktsarpalis in #266
- Augment McpServerTool/Prompt docs with details of parameter/result marshaling by @stephentoub in #271
- Delete some dead methods from Log.cs by @stephentoub in #277
- Expose a JsonSerializerOptions setting in the prompts APIs by @eiriktsarpalis in #279
New Contributors
Full Changelog: v0.1.0-preview.7...v0.1.0-preview.8
v0.1.0-preview.7
What's Changed
- Everything server by @aaronpowell in #151
- Bump package version to 0.1.0-preview.7 by @eiriktsarpalis in #212
- Propagate fix from AIFunctionFactory to TemporaryAIFunctionFactory by @stephentoub in #215
- Allow notification handlers post-creation temporary registration by @stephentoub in #223
- Use Kestrel for all in-memory HTTP tests by @halter73 in #225
- Use strong-typing of params in most remaining McpClientExtensions methods by @stephentoub in #224
- Stop the host when the single session server service finishes by @stephentoub in #226
- Bump xunit.v3 to 2.0.0 by @eiriktsarpalis in #231
- Add server "completions" capability by @stephentoub in #232
- Fix race in KestrelInMemoryConnection by @halter73 in #233
- Enable servers to log to the clients via ILogger by @stephentoub in #229
- Fix api.weather.gov/points response handling in WeatherTools by @stvansolano in #134
- Remove
McpServerConfig
and haveMcpClientFactory
acceptIClientTransport
instances directly. by @eiriktsarpalis in #230 - Fix StdioServerTransport.DisposeAsync hang by @halter73 in #235
- Add SECURITY.md by @jeffhandley in #239
- Fix and enhance cancellation operations across MCP Sessions. by @Tyler-R-Kendrick in #179
- Update markdown-link-check to ignore external links causing 403 in CI by @jeffhandley in #246
- Avoid propagating server tool exception message to client by @stephentoub in #242
- Update M.E.AI to latest version by @stephentoub in #241
- Fixes #248 - Add CultureInfo.InvariantCulture to string interpolation… by @DGuhr in #249
- Improve SSE response handling and URI construction in SseClientSessio… by @239573049 in #251
- Use TryAddEnumerable for McpServerOptionsSetup by @halter73 in #252
- Fix race in TransportBase.SetConnected by @halter73 in #253
- Separate ASP.NET Core tests into a distinct project and make the main test project netfx compatible. by @eiriktsarpalis in #254
New Contributors
- @DGuhr made their first contribution in #249
- @239573049 made their first contribution in #251
Full Changelog: v0.1.0-preview.6...v0.1.0-preview.7
v0.1.0-preview.6
What's Changed
- Bump package version to 0.1.0-preview.6 by @eiriktsarpalis in #206
- Disable response buffering for SSE responses by @halter73 in #208
- Consolidate McpClientException/McpServerException into McpException by @stephentoub in #209
- Move notification handler registrations to capabilities by @stephentoub in #207
Full Changelog: v0.1.0-preview.5...v0.1.0-preview.6
v0.1.0-preview.5
What's Changed
- Fix AspNetCore README by @halter73 in #170
- Bump package version by @eiriktsarpalis in #169
- Put MapMcp in Microsoft.AspNetCore.Builder namespace by @halter73 in #171
- Split StdioClient/ServerTransports into Stdio : Stream by @stephentoub in #172
- Fixing WithPromptsFromAssembly by @aaronpowell in #174
- Enable IsAotCompatible for ModelContextProtocol.AspNetCore by @stephentoub in #175
- Configure hosted stdio servers to log to stderr by @halter73 in #173
- Fix pagination handling in McpServer by @stephentoub in #177
- Extend progress notification support by @Tyler-R-Kendrick in #163
- Make supposedly unreachable code less reachable by @halter73 in #178
- Add initial Activity / Metric support by @stephentoub in #183
- Allow JsonSerializerOptions parameters for user-defined and inputs and hardcode everything else to the source generator. by @eiriktsarpalis in #182
- Write "event: message" to SSE response by @halter73 in #192
- Changed the name of the ActivitySource and Metric to clarify that the semantic conventions have not been ratified yet. by @samsp-msft in #194
- Allow override of name and description of McpClientTool by @PederHP in #165
- Expand a few DI-related tests by @stephentoub in #201
- Hardcode the source generator in one remaining location and simplify McpJsonUtilities. by @eiriktsarpalis in #204
- Reduce dependencies to 8.x versions of packages by @stephentoub in #195
- Mark samples as AOT compatible by @agocke in #184
- [UnitTests] Add more UTs by @stvansolano in #139
New Contributors
- @Tyler-R-Kendrick made their first contribution in #163
- @samsp-msft made their first contribution in #194
- @agocke made their first contribution in #184
- @stvansolano made their first contribution in #139
Full Changelog: v0.1.0-preview.4...v0.1.0-preview.5
v0.1.0-preview.4
What's Changed
Full Changelog: v0.1.0-preview.3...v0.1.0-preview.4
v0.1.0-preview.3
What's Changed
- Fix some issues with Native AOT by @stephentoub in #130
- Add ToolAnnotations support by @stephentoub in #124
- Fix sample in README by @BrennanConroy in #136
- Add missing Annotations by @stephentoub in #138
- Remove Assembly.GetCallingAssembly by @stephentoub in #133
- Refactor transports to help enable graceful shutdown by @halter73 in #142
- Overhaul of Resources by @aaronpowell in #125
- Fix binding to wrong overload in WithTools by @stephentoub in #152
- Improve progress reporting by @stephentoub in #145
- Add [McpServerPrompt] support by @stephentoub in #126
- Implement cancellation notifications by @stephentoub in #146
- Bump version to 0.1.0-preview.3 by @jeffhandley in #162
New Contributors
- @BrennanConroy made their first contribution in #136
Full Changelog: v0.1.0-preview.2...v0.3.0-preview.3
v0.1.0-preview.2
What's Changed
- Logging Capability by @PederHP in #53
- Add nuget badge to README by @stephentoub in #58
- Run integration test SSE server in process by @halter73 in #56
- Remove reflection from Connect test by @jaredpar in #57
- Fix private reflection by @jaredpar in #60
- docs: update McpToolAttribute name comment by @WeihanLi in #63
- Adding merge files to gitignore by @aaronpowell in #78
- docs: add McpServerOptionsSetup code comment by @JaneConan in #77
- Fix enum serialization by @zaevi in #61
- Fix stdio encoding issue: Enforce explicit UTF-8 for correct Unicode handling by @willibrandon in #73
- Make client config optional to McpClientFactory.CreateAsync by @stephentoub in #65
- Add XunitLoggerProvider by @halter73 in #81
- Avoid race starting SseResponseStreamTransport by @halter73 in #91
- Add acknowledgements to README by @mikekistler in #94
- Adding code coverage to tests in workflow by @aaronpowell in #75
- Update documentation configuration by @localden in #86
- Add links to API docs from README.md by @eiriktsarpalis in #96
- Overhaul tool handling by @stephentoub in #89
- Add package installation to README by @timheuer in #101
- Add gitattributes by @halter73 in #98
- Adding a base class for request params that exposes the progressToken by @aaronpowell in #99
- Add [McpServerTool] support for instance methods by @stephentoub in #100
- Make options types fully mutable by @halter73 in #107
- Configurable messages endpoint for SSE transport by @edis-uipath in #109
- Use different logger categories for client and server in McpJsonRpcEndpoint by @halter73 in #110
- Samples for quickstart docs by @aaronpowell in #104
- Adding support for returning collections from tools by @aaronpowell in #116
- List tools from DI once by @halter73 in #115
- Set up package publishing for daily, manual, and release builds by @jeffhandley in #118
- complete fix for SampleLlmTool discovery by @NeverMorewd in #102
New Contributors
- @PederHP made their first contribution in #53
- @jaredpar made their first contribution in #57
- @WeihanLi made their first contribution in #63
- @aaronpowell made their first contribution in #78
- @JaneConan made their first contribution in #77
- @zaevi made their first contribution in #61
- @willibrandon made their first contribution in #73
- @localden made their first contribution in #86
- @timheuer made their first contribution in #101
- @edis-uipath made their first contribution in #109
- @NeverMorewd made their first contribution in #102
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 IChatClient
s.
// 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.