news 2026/7/3 8:15:52

ModelContextProtocol CSharp 中提供了三种 Transport ,其核心代码在三个类中:

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ModelContextProtocol CSharp 中提供了三种 Transport ,其核心代码在三个类中:
  • StdioClientTransport
  • SseClientTransport
  • StreamClientTransport

下面笔者将会详细讲解 stdio、sse 两种 Transport。

stdio

通过本地进程间通信实现,客户端以子进程形式启动 MCP Server 程序,双方通过stdin/stdout交换 JSON-RPC 消息,传输每条消息时以换行符分隔。

本节示例项目参考 TransportStdioServer、TransportStdioClient。


当使用 stdio 时,McpServer 只需要实现静态方法并配置特性注解即可,然后需要将该程序编译为.exe

TransportStdioServer 添加 Tool :

后面讲解 Tool ,这里先跳过。

[McpServerToolType] public class EchoTool { [McpServerTool, Description("Echoes the message back to the client.")] public static string Echo(string message) => $"hello {message}"; }

然后创建 MCP Server 服务,并使用WithStdioServerTransport()暴露接口能力。

using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using TransportStdioServer; var builder = Host.CreateApplicationBuilder(args); builder.Services.AddMcpServer() .WithStdioServerTransport() .WithTools<EchoTool>(); builder.Logging.AddConsole(options => { options.LogToStandardErrorThreshold = LogLevel.Trace; }); await builder.Build().RunAsync();

编译 TransportStdioServer 项目,在 Windows 下会生成.exe文件,复制.exe文件的绝对路径,在编写 Client 时要用。

C# 编写 Client 时,需要通过命令行参数导入.exe文件,示例如下:

using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using ModelContextProtocol.Client; using ModelContextProtocol.Protocol.Transport; var builder = Host.CreateApplicationBuilder(args); builder.Configuration .AddEnvironmentVariables() .AddUserSecrets<Program>(); var clientTransport = new StdioClientTransport(new() { Name = "Demo Server", // 要使用绝对路径,这里笔者省略了 Command = "E:/../../TransportStdioServer.exe" }); await using var mcpClient = await McpClientFactory.CreateAsync(clientTransport); var tools = await mcpClient.ListToolsAsync(); foreach (var tool in tools) { Console.WriteLine($"Connected to server with tools: {tool.Name}"); }

启动 TransportStdioClient,控制台会打印 TransportStdioServer 中的所有 Mcp tool。


StdioClientTransport 原理是基于命令行参数启动 TransportStdioServer,StdioClient 会将命令行参数拼接起来,然后以子进程方式启动 MCP Server,命令行示例:

cmd.exe/c E:/../TransportStdioServer.exe

StdioClientTransport 核心代码启动子进程:

SSE

本节参考示例项目:TransportSseServer、TransportSseClient。

SSE 是通过 HTTP 长连接实现远程通信的,在使用各种 AI 对话应用时,AI 会像打字机一样逐个输出字符,这种通过 HTTP 长连接、由 HTTP Server 服务器持续推送内容的方式就叫 sse。

SSE Server 需提供两个端点:

  • /sse(GET请求):建立长连接,接收服务器推送的事件流。
  • /messages(POST请求):客户端发送请求至该端点。


在 TransportSseServer 实现简单的 EchoTool。

[McpServerToolType] public sealed class EchoTool { [McpServerTool, Description("Echoes the input back to the client.")] public static string Echo(string message) { return "hello " + message; } }


配置 MCP Server 支持 SSE:

using TransportSseServer.Tools; var builder = WebApplication.CreateBuilder(args); builder.Services.AddMcpServer() .WithHttpTransport() .WithTools<EchoTool>() .WithTools<SampleLlmTool>(); var app = builder.Build(); app.MapMcp(); app.Run("http://0.0.0.0:5000");

TransportSseClient 实现客户端连接 Mcp Server,其代码非常简单,连接到 MCP Server 后将对方支持的 Tool 列出来。

using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using ModelContextProtocol.Client; using ModelContextProtocol.Protocol.Transport; var defaultOptions = new McpClientOptions { ClientInfo = new() { Name = "IntegrationTestClient", Version = "1.0.0" } }; var defaultConfig = new SseClientTransportOptions { Endpoint = new Uri($"http://localhost:5000/sse"), Name = "Everything", }; // Create client and run tests await using var client = await McpClientFactory.CreateAsync( new SseClientTransport(defaultConfig), defaultOptions, loggerFactory: NullLoggerFactory.Instance); var tools = await client.ListToolsAsync(); foreach (var tool in tools) { Console.WriteLine($"Connected to server with tools: {tool.Name}"); }
Streamable
  • Streamable HTTP 是 SSE 的升级方案,完全基于标准 HTTP 协议,移除了专用 SSE 端点,所有消息通过/message端点传输。

本节不讲解 Streamable 。

MCP Tool 说明

目前社区有两大主流 LLM 开发框架,分别是 Microsoft.SemanticKernel、LangChain,它们都支持 Plugin ,能够将本地函数、Swagger 等转换为函数,将 Function 提交给 LLM,AI 返回要调用的 Function 后,由框架引擎实现动态调用,这样功能叫 Function call。

注意,MCP 有很多功能,其中一个叫 MCP Tool,可以视为跟 Plugin 实现类似功能的东西。

MCP Tool 对标 Plugin ,MCP 不止包含 Tool 这一功能。

但是每个 LLM 框架的 Plugin 实现方式不一样,其使用和实现机制跟语言特性深度绑定,不能实现跨服务跨平台使用,所以出现了 MCP Tool, MCP Tool 是对标 Plugin 的一类功能,主要目的跟 Plugin 一样提供 Function,但是 MCP 有统一协议标准,跟语言无关、跟平台无关,但是 MCP 也不是完全替换 Plugin ,Plugin 依然具有很大的用武之地。

MCP Tool、Plugin 最后都是转换为 Function call 的,有很多人会把 MCP 、MCP Tool 和 Function call 搞混,认为 MCP 是替换 Function call 的,所以要注意,对标 Plugin 的是 MCP Tool,而两者都是转换为 Function 给 AI 使用的。

MCP Tool

以 TransportSseClient 为例,如果要在 Client 调用 TransportSseServer 的 Tool,需要指定 Tool 名字和参数。

后续将会讲解如何通过 SK 将 mcp tool 提供给 AI 模型。

var echoTool = tools.First(x => x.Name == "Echo"); var result = await client.CallToolAsync("Echo", new Dictionary<string, object?> { { "message","痴者工良"} }); foreach (var item in result.Content) { Console.WriteLine($"type: {item.Type},text: {item.Text}"); }

让我们再回顾 MCP Server 是怎么提供 Tool 的。

首先服务端需要定义 Tool 类和函数。

[McpServerToolType] public sealed class EchoTool { [McpServerTool, Description("Echoes the input back to the client.")] public static string Echo(string message) { return "hello " + message; } }

Mcp server 可以通过以下两种方式暴露 tool。

// 直接指定 Tool 类 builder.Services .AddMcpServer() .WithHttpTransport() .WithTools<EchoTool>() .WithTools<SampleLlmTool>(); // 扫描程序集 builder.Services .AddMcpServer() .WithHttpTransport() .WithStdioServerTransport() .WithToolsFromAssembly();

Client 识别服务端的 Tool 列表时,可以使用McpClientTool.ProtocolTool.InputSchema获取 tool 的输入参数格式:

其内容格式示例如下:

Annotations: null Description: "Echoes the input back to the client." Name: "Echo" InputSchema: "{"title":"Echo","description":"Echoes the input back to the client.","type":"object","properties":{"message":{"type":"string"}},"required":["message"]}"

[McpServerToolType]用于将包含应该作为ModelContextProtocol.Server.McpServerTools公开的方法的类型属性化。

[McpServerTool]用于指示应该将方法视为 ModelContextProtocol.Server.McpServerTool。

[Description]则用于添加注释。

依赖注入

在实现 Tool 函数时,服务端是可以通过函数实现依赖注入的。

参考示例项目 InjectServer、InjectClient。

添加一个服务类并注册到容器中。

public class MyService { public string Echo(string message) { return "hello " + message; } }
builder.Services.AddScoped<MyService>();

在 Tool 函数中注入该服务:

[McpServerToolType] public sealed class MyTool { [McpServerTool, Description("Echoes the input back to the client.")] public static string Echo(MyService myService, string message) { return myService.Echo(message); } }

将 MCP Tool 提交到 AI 对话中

前面提到,MCP Tool 和 Plugin 都是实现 Function call 的一种方式,当在 AI 对话中使用 Tool 时,其主要过程如下:

当你提出问题时:

  1. client 将你的问题发送给 LLM ;
  2. LLM 分析可用的 tools 并决定使用哪些 tool;
  3. client 通过 MCP server 执行选择的 tool
  4. 结果被发回给 LLM;
  5. LLM 制定自然语言响应;
  6. 响应显示给你;

这个过程并不是只有一两次,可能发生多次,具体细节将会在高德地图 MCP 实战中讲解,这里只是简单提及。

将 Tool 提交到对话上下文的伪代码

// 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 实战

聊了这么久,终于到了实战对接环节,本节将会通过高德地图案例讲解 MCP Tool 的逻辑细节和对接使用方式。

代码参考示例项目 amap。

高德地图 MCP Server 目前主要提供的功能:

  • 地理编码
  • 逆地理编码
  • IP 定位
  • 天气查询
  • 骑行路径规划
  • 步行路径规划
  • 驾车路径规划
  • 公交路径规划
  • 距离测量
  • 关键词搜索
  • 周边搜索
  • 详情搜索

其 Tool 名称如下:

maps_direction_bicycling maps_direction_driving maps_direction_transit_integrated maps_direction_walking maps_distance maps_geo maps_regeocode maps_ip_location maps_around_search maps_search_detail maps_text_search maps_weather

高德地图每天都给开发者提供了免费额度,所以做该实验时,不需要担心需要付费。

打开 我的应用 | 高德控制台 创建一个新的应用,然后复制应用 key。

高德 mcp 服务器地址:

https://mcp.amap.com/sse?key={在高德官网上申请的key}

在 amap 项目的appsettings.json添加以下 json,替换里面的部分参数。

笔者注,除了 gpt-4o 模型,其它注册 Function call 的模型也可以使用。

"McpServers": { "amap-amap-sse": { "url": "https://mcp.amap.com/sse?key={在高德官网上申请的key}" } }, "AIModel": { "ModelId": "gpt-4o", "DeploymentName": "gpt-4o", "Endpoint": "https://openai.com/", "Key": "aaaaaaaa" }

导入配置并创建日志:

var configuration = new ConfigurationBuilder() .AddJsonFile("appsettings.json") .AddJsonFile("appsettings.Development.json") .Build(); using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
第一步:创建 mcp 客户端

连接高德 MCP Server,并获取 Tool 列表。

var defaultOptions = new McpClientOptions { ClientInfo = new() { Name = "地图规划", Version = "1.0.0" } }; var defaultConfig = new SseClientTransportOptions { Endpoint = new Uri(configuration["McpServers:amap-amap-sse:url"]!), Name = "amap-amap-sse", }; await using var client = await McpClientFactory.CreateAsync( new SseClientTransport(defaultConfig), defaultOptions, loggerFactory: factory); var tools = await client.ListToolsAsync(); foreach (var tool in tools) { Console.WriteLine($"Connected to server with tools: {tool.Name}"); }

第二步:连接 AI 模型和配置 MCP
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/3 8:15:32

防火门隐藏消防指标大揭秘

消防验收、第三方检测扣分、批量返工&#xff0c;绝大多数问题不在肉眼可见的外观&#xff0c;而是藏在钢板内部、门框空腔、胶条材质、五金参数、缝隙密闭、铭牌一致性、烟密量化指标里的隐蔽强制条款。市场低价非标产品普遍在隐蔽指标偷工减料&#xff0c;外观无法分辨&#…

作者头像 李华
网站建设 2026/7/3 8:08:34

暗黑破坏神2存档编辑器完整指南:5分钟学会可视化修改角色与装备

暗黑破坏神2存档编辑器完整指南&#xff1a;5分钟学会可视化修改角色与装备 【免费下载链接】d2s-editor 项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor 你是否曾经为暗黑破坏神2中某个角色的装备不理想而烦恼&#xff1f;或者想要测试新的技能组合却不想重…

作者头像 李华
网站建设 2026/7/3 8:07:33

实验7-3 自媒体运营分析-可视化分析

1 实验目的 基于实验7-1、实验7-2 输出的目标表&#xff0c;使用助睿BI完成多维度可视化分析&#xff0c;搭建综合仪表盘&#xff0c;并撰写数据驱动的运营优化报告。 通过本实验&#xff0c;学生应掌握&#xff1a; 使用助睿BI的聚合功能&#xff08;计数、求和、平均、分组…

作者头像 李华