MCP C# SDK
Model Context Protocol 的官方 C# SDK,可让 .NET 应用程序、服务和库实现 MCP 客户端与服务端及两者的交互。有关可用功能的更多详细信息,请访问我们的 API 文档。
包
该SDK包含三个核心包:
- ModelContextProtocol NuGet 预览版 - 包含托管和依赖注入扩展的主要软件包。适用于大多数不需要 HTTP 服务器功能的项目。本 README 文件即为此软件包的文档。
- ModelContextProtocol.AspNetCore NuGet 预览版 - 用于基于 HTTP 的 MCP 服务端的库。
- ModelContextProtocol.Core NuGet 预览版 - 适用于仅需使用客户端或底层服务端 API,且希望依赖项最少的用户
备注
该项目处于预览阶段,可能会在没有事先通知的情况下引入破坏性变更。
关于MCP
模型上下文协议(Model Context Protocol,简称 MCP)是一种开放协议,用于规范应用程序向大语言模型(LLMs)提供上下文的方式。它实现了 LLM 与各种数据源和工具之间的安全集成。
有关 MCP 的更多信息:
安装
请从NuGet安装该程序包以开始使用。
dotnet add package ModelContextProtocol --prerelease
客户端快速入门
要开始编写客户端,需使用 McpClientFactory.CreateAsync
方法来实例化 IMcpClient
并将其连接到服务端。获得 IMcpClient
实例后,即可通过其进行交互操作,例如枚举所有可用工具并调用这些工具。
var clientTransport = new StdioClientTransport(new StdioClientTransportOptions
{
Name = "Everything",
Command = "npx",
Arguments = ["-y", "@modelcontextprotocol/server-everything"],
});
var client = await McpClientFactory.CreateAsync(clientTransport);
// Print the list of tools available from the server.
foreach (var tool in await 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 Dictionary<string, object?>() { ["message"] = "Hello MCP!" },
cancellationToken:CancellationToken.None);
// echo always returns one and only one text content object
Console.WriteLine(result.Content.First(c => c.Type == "text").Text);
您可以在 samples 目录中找到展示如何将 ModelContextProtocol 与 LLM SDK 结合使用的示例,也可以参考 tests 项目获取更多实例。更多示例和文档将在近期陆续添加。
客户端可连接至任何 MCP 服务端,而不仅限于使用本库创建的服务端。该协议设计为与服务端实现无关,因此您可以使用本库连接任何符合规范的服务端。
工具可轻松暴露给 IChatClients 即时调用,因为 McpClientTool 继承自 AIFunction。
// Get available functions.
IList<McpClientTool> tools = await client.ListToolsAsync();
// Call the chat client using the tools.
IChatClient chatClient = ...;
var response = await chatClient.GetResponseAsync(
"your prompt here",
new() { Tools = [.. tools] },
服务端快速入门
以下示例演示如何创建MCP服务端并注册当前应用程序中的所有工具。示例包含一个简单的回声工具(为便于复制粘贴,此处将其与主代码置于同一文件,但实际无需放在同一文件中...所使用的WithTools重载方法会扫描当前程序集,查找带有McpServerToolType特性的类,并将所有具有McpTool特性的方法注册为工具。)
dotnet add package ModelContextProtocol --prerelease
dotnet add package Microsoft.Extensions.Hosting
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 =>
{
// Configure all logs to go to stderr
consoleLogOptions.LogToStandardErrorThreshold = LogLevel.Trace;
});
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
await builder.Build().RunAsync();
[McpServerToolType]
public static class EchoTool
{
[McpServerTool, Description("Echoes the message back to the client.")]
public static string Echo(string message) => $"hello {message}";
}
工具可通过方法形参注入代表服务端的IMcpServer实例,并借助该实例与连接的客户端进行交互。同样地,实参也可通过依赖注入方式注入。例如:以下工具将使用注入的IMcpServer向客户端发起采样请求,从而通过依赖注入的HttpClient从指定URL下载内容并进行汇总。
[McpServerTool(Name = "SummarizeContentFromUrl"), Description("Summarizes content downloaded from a specific URI")]
public static async Task<string> SummarizeDownloadedContent(
IMcpServer thisServer,
HttpClient httpClient,
[Description("The url from which to download the content to summarize")] string url,
CancellationToken cancellationToken)
{
string content = await httpClient.GetStringAsync(url);
ChatMessage[] messages =
[
new(ChatRole.User, "Briefly summarize the following downloaded content:"),
new(ChatRole.User, content),
];
ChatOptions options = new()
{
MaxOutputTokens = 256,
Temperature = 0.3f,
};
return $"Summary: {await thisServer.AsSamplingChatClient().GetResponseAsync(messages, options, cancellationToken)}";
}
提示词可以使用 [McpServerPrompt] 特性以类似的方式公开,例如:
[McpServerPromptType]
public static class MyPrompts
{
[McpServerPrompt, Description("Creates a prompt to summarize the provided message.")]
public static ChatMessage Summarize([Description("The content to summarize")] string content) =>
new(ChatRole.User, $"Please summarize this content into a single sentence: {content}");
}
还可实现更精细的控制,对服务端的配置及其处理客户端请求的方式进行细粒度的管理。例如:
using ModelContextProtocol;
using ModelContextProtocol.Protocol;
using ModelContextProtocol.Server;
using System.Text.Json;
McpServerOptions options = new()
{
ServerInfo = new Implementation { Name = "MyServer", Version = "1.0.0" },
Capabilities = new ServerCapabilities
{
Tools = new ToolsCapability
{
ListToolsHandler = (request, cancellationToken) =>
ValueTask.FromResult(new ListToolsResult
{
Tools =
[
new Tool
{
Name = "echo",
Description = "Echoes the input back to the client.",
InputSchema = JsonSerializer.Deserialize<JsonElement>("""
{
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "The input to echo back"
}
},
"required": ["message"]
}
"""),
}
]
}),
CallToolHandler = (request, cancellationToken) =>
{
if (request.Params?.Name == "echo")
{
if (request.Params.Arguments?.TryGetValue("message", out var message) is not true)
{
throw new McpException("Missing required argument 'message'");
}
return ValueTask.FromResult(new CallToolResult
{
Content = [new TextContentBlock { Text = $"Echo: {message}", Type = "text" }]
});
}
throw new McpException($"Unknown tool: '{request.Params?.Name}'");
},
}
},
};
await using IMcpServer server = McpServerFactory.Create(new StdioServerTransport("MyServer"), options);
await server.RunAsync();
