跳到主要内容
版本:4.2

MCP 服务器

一、说明

MCP(Model Context Protocol,模型上下文协议)是 Anthropic 提出的一套开放协议,用于标准化 AI 模型与外部工具、资源之间的交互方式。TouchSocket 提供了完整的 MCP 服务器实现,支持以下两种传输方式:

  • Stdio:通过标准输入/输出流进行通信,适用于本地进程间调用(如 Claude Desktop、Cursor 等工具集成)。
  • Streamable HTTP:基于 HTTP 协议进行通信,适用于网络服务场景。

MCP 服务器可以向 AI 客户端暴露三类能力:

能力特性说明
Tools(工具)[McpTool]可被 AI 模型主动调用的函数,支持参数描述和类型推断
Resources(资源)[McpResource]通过 URI 访问的数据资源,支持精确匹配和 URI 模板
Prompts(提示模板)[McpPrompt]预定义的提示消息模板,可接受参数

二、特点

  • 特性驱动:通过 [McpTool][McpResource][McpPrompt] 特性标注即可完成注册,无需手动配置路由。
  • 自动 JSON Schema 生成:工具参数的类型和描述信息会自动生成标准 JSON Schema,无需手动编写。
  • 双传输支持:同一套服务定义,可同时以 Stdio 和 HTTP 两种方式发布。
  • 基于 RPC 体系:完全集成 TouchSocket 的 Rpc 框架,支持单例、瞬态、区域等生命周期,以及 AOP 拦截、依赖注入等高级功能。
  • URI 模板资源:资源支持 RFC 6570 风格的 URI 模板(如 config://server/{key}),实现动态参数匹配。

三、安装

<PackageReference Include="TouchSocket.Mcp" Version="最新版本" />

四、定义 MCP 服务

4.1 基本概念

MCP 服务类需要继承 SingletonRpcServer(或实现 IRpcServer 接口),然后通过特性标注将方法注册为工具、资源或提示模板。

4.2 定义服务类

下面展示了一个包含工具、资源和提示模板的完整 MCP 服务示例:

🔄 正在加载代码...
参数描述

使用 System.ComponentModel.DescriptionAttribute 为方法和参数添加描述,框架会自动将其注入到 JSON Schema 中,供 AI 模型理解参数含义。

4.3 工具(Tools)

工具使用 [McpTool] 特性标注,可以返回任意可序列化的类型:

  • 返回 stringint 等基础类型:框架自动包装为文本内容。
  • 返回 McpContent 或其派生类(McpTextContentMcpImageContent):直接作为内容返回。
  • 返回 IEnumerable<McpContent>:返回多条内容。
  • 返回 McpCallToolResult:完全自定义结果。

4.4 资源(Resources)

资源使用 [McpResource(uriPattern)] 特性标注,uriPattern 支持两种形式:

  • 精确 URI:如 config://server/info,客户端通过完整 URI 访问。
  • URI 模板:如 config://server/{key},框架自动提取 {key} 参数并传入方法。

资源方法支持的返回类型:

  • 返回 string:自动包装为文本资源内容。
  • 返回 byte[]:自动包装为二进制资源内容(Base64 编码)。
  • 返回 McpResourceContent:直接使用。
  • 返回 McpReadResourceResult:完全自定义结果。

4.5 提示模板(Prompts)

提示模板使用 [McpPrompt] 特性标注,方法参数作为提示模板的参数(均为字符串类型):

  • 返回 McpPromptMessage:单条消息。
  • 返回 IEnumerable<McpPromptMessage>:多条消息。
  • 返回 McpGetPromptResult:完全自定义结果。

McpPromptMessageRole 字段可取 "user""assistant"

五、创建 Stdio 服务器

Stdio 传输方式是 MCP 的标准本地集成方式,适用于 Claude Desktop、Cursor 等工具直接启动子进程进行通信。

🔄 正在加载代码...
说明

McpStdioServer 通过读取 Console.In(标准输入)接收 MCP 消息,通过写入 Console.Out(标准输出)发送响应。因此在 Stdio 模式下,不应在程序中向标准输出打印日志,否则会污染 MCP 通信流。

可通过 McpStdioServerOptions.ReaderMcpStdioServerOptions.Writer 自定义输入输出流。

5.1 Claude Desktop 集成示例

在 Claude Desktop 的 claude_desktop_config.json 中配置:

{
"mcpServers": {
"my-mcp-server": {
"command": "dotnet",
"args": ["run", "--project", "路径/McpServerConsoleApp"]
}
}
}

六、创建 HTTP 服务器

Streamable HTTP 传输方式适用于网络远程访问场景,基于 TouchSocket 的 HttpService 通过插件方式集成。

🔄 正在加载代码...
默认路径

McpHttpPlugin 默认监听路径为 /mcp,可通过 options.Path 自定义。

6.1 会话管理

HTTP 模式下,每个 MCP 客户端通过 Mcp-Session-Id 请求头标识会话。服务器自动为首次连接的客户端分配会话 ID,并在 DELETE 请求时销毁会话。

七、注册服务

7.1 注册服务类

使用 AddRpcStore 方法注册 MCP 服务类,与 TouchSocket 其他 RPC 框架(JsonRpc、WebApi 等)共享同一套注册机制:

.ConfigureContainer(a =>
{
a.AddRpcStore(store =>
{
store.RegisterServer<MyMcpService>();
});
})
更多注册方式

更多注册 RPC 服务的方法请参考:注册 Rpc 服务

7.2 服务生命周期

  • SingletonRpcServer:单例,所有请求共享同一个实例。
  • TransientRpcServer:瞬态,每次请求创建新实例。
  • ScopedRpcServer:区域,在 Scoped IOC 容器中按区域单例。

八、高级配置

8.1 自定义服务器信息

通过 McpServerOptions.ServerInfo 设置服务器名称和版本,该信息会在 initialize 握手时返回给客户端:

options.ServerOptions.ServerInfo = new McpImplementationInfo
{
Name = "MyMcpServer",
Version = "1.0.0"
};

8.2 设置使用说明

通过 McpServerOptions.Instructions 设置服务器的使用说明,该信息会在初始化响应中返回:

options.ServerOptions.Instructions = "这是一个演示服务器,提供加法计算和服务器信息查询功能。";

8.3 获取调用上下文

MCP 服务方法可以通过参数注入 IMcpCallContext 获取调用上下文,从而获取 MCP 请求 ID 等信息:

[McpTool]
[Description("带上下文的工具示例")]
public string ToolWithContext(IMcpCallContext callContext, string input)
{
var requestId = callContext.McpRequestId;
return $"请求 ID:{requestId},输入:{input}";
}

8.4 使用依赖注入

服务方法参数可以通过 [FromServices] 特性从 IOC 容器中注入依赖:

[McpTool]
[Description("使用依赖注入的工具")]
public string ToolWithDI([FromServices] ILog logger, string message)
{
logger.Info(message);
return "已记录日志";
}