Client和Server如何通信?

  Cilent和Server的通信可以说是MCP架构最关键的部分。通过前文我们知道构成MCP完整架构的三个部分:MCP Host、MCP Client、MCP Host。

  MCP Host服务就是我们常说的开发一个AI应用,而MCP Server一般是别人的程序,MCP Client非独立服务,包含在MCP Host服务里。因此,MCP的Client和Server之间通信其实是MCP Host和MCP Server两个服务之间的通信。

  C和S之间通信可以类比服务端编程领域的RPC(远程进程调用)通信,如gRPC、Dubbo、JSON-RPC。RPC通信有几个重要部分包括数据格式、传输协议、服务发现。下面从这三个方面来看下MCP的C/S通信细节:数据格式:MCP的C/S的数据格式是标准的JSON-RPC 2.0传输协议:Stdio:C/S都在同一个机器上,Server作为子进程启动,通过操作系统的标准stdin输入和stdout输出进行数据交互SSE:Server-Send-Event,基于HTTP协议、利用 HTTP 长连接实现服务器向客户端单向持续推送内容Streamable Http:基于HTTP协议,以普通 HTTP 请求为基础,服务器可按需将响应升级为 SSE 流,支持无状态服务器服务发现:

  Stdio:不涉及网络调用,Client仅通过进程名称找到Server

  Streamable Http:通过域名发现,Server通过通知类型消息(notification)告知Client其状态变化,比如Server上的工具列表更新

  三种传输协议怎么选?简单来说,本地通信用Stdio(比如在安全隐私要求高的设备上如汽车、手机,离线环境下的CI/CD脚本、工具链、插件等),远程网络通信用Streamable Http和SSE,但Streamable Http可以替代SSE且更具优势,官方已经不建议再使用SSE。

  为什么MCP会推荐Steamable Http而弃用SSE?

  Streamable Http和SSE都是基于HTTP协议的,前者是http短连接、后者是http长连接事件流协议(格式为text/event-stream),因此MCP推荐用前者的大部分理由都是因为短连接和长连接的区别带来的。

  大部分我们接触到的网络请求都是客户端(Client)发起一次性请求并从服务端(Server)获取结果的短连接形式,数据是从服务端单方向传输到客户端。长连接适合客户端和服务端两个方向都可以发起请求,传输数据。但长连接会带来高得多的开发难度和运维成本。

  从3个方面回答为什么MCP推荐用Streamable Http?

  1、合理评估长耗时任务

  我们知道大模型厂商的API绝大多数默认采用SSE协议的。因为大模型的推理和生成往往耗时比较久,为了让调用方尽快看到一部分内容,只能一批一批地返回,也叫流式输出。换句话说SSE是长耗时任务的常见选型。但MCP server大多承担工具执行角色,返回给MCP client的内容其实大部分不是长耗时的。从八二法则来看,采用Streamable Http会更合算。

  当然遇到server需要给client推送内容时(即notification消息),Streamable Http内部会临时升级为SSE。

  2、长连接的有状态。用SSE意味着server是有连接状态的。做服务端开发的,特别是负责系统运维的同学,一定特别不喜欢“有状态”这个词。这意味着你会遇到很多不顺心的事。

  SSE长连接会拖慢响应时间、消耗额外服务器资源、增加部署硬件成本。部署的时候也要求在负载均衡反向代理层需要特殊的配置,带来运维复杂度。应对请求流量变化时也不利于弹性扩缩容。

  3、双端点的不便。SSE需要维护两个通信通道(/see的GET用于接受响应,/messaged的POST用于发送请求),双端点带来复杂性。

  当然MCP Streamable Http传输协议毕竟不是简单的REST API这种简单的请求-响应型。其实服务端也维护了session会话,断连后的续连就是靠会话ID来做到。

  下面结合代码示例进一步理解三种协议是如何工作的。注:本篇示例代码采用Go语言,基于开源mcp sdk:github.com/mark3labs/mcp-go

  如何开发MCP Server?

  假设MCP Server叫mcp-server-demo,定义了一个工具hello_world,可以给传入的名字name打招呼。代码示例如下(完整的Server代码可以在github上查看:https://github.com/kobelv/mcp-server-demo):server启动:通过mcp官方Inspector工具测试:

  使用mcp官方的inspector工具,可以不用自己编写client程序很方便测试mcp server。server启动:通过Inspector测试:

  通过Claude Desktop测试:

  有很多桌面版的大模型工具都可以很方便地安装mcp server,比如claude desktop、cursor等。下面以claude desktop举例。

  在测试之前,让我们把上面的hello_world工具能力变强一点,可以接受三个参数:打招呼的人名、内容、日期。

  如何开发MCP Client?

  上面都是MCP Server侧的代码,下面我们自己来开发一个Host,用MCP Client来连接Server。(完整的Host代码可以在github上查看:https://github.com/kobelv/mcp-host-demo)

  client连接server示例代码:

  注意:client在调用server之前必须先初始化才能做调用工具、提示词和资源,接收server通知等后续操作。

  MCP Host主流程代码如下

  整个host模块是个完整的web服务端程序,运行起来后可以跟它问:“给Kobe带句话,就说“你的曼巴精神一直都在,R.I.P!!!”,经过上面一系列步骤后最后会调用hello_world工具返回“你好 Kobe, 今天是 2025/09/06, 你的曼巴精神一直都在,R.I.P!!!”。

  当然你也可以问上面Claude Desktop示例中的问题,获得和上面Claude Desktop示例调用hello_world工具一样的返回结果。如果大模型表现正常的话,即使你换些类似的问法,大概率也能获得一样的答案,这就属于大模型的理解能力范畴了。

  结语

  MCP协议里server除了提供tools,还有prompt和resource,其技术本身没有区别所以本次就略过了。文中示例代码属于演示用途,实际项目里的tools数量更多,入参更多,涉及的server也更多,带来的工程复杂也高得多,属于本篇未尽事宜。

  回头看MCP架构,就像我们说的冰山,水面以下才是大头。MCP架构其实也是,90%是软件工程,10%是AI。这个结论甚至可以推广到目前大家用到的其他AI应用的AI和工程的关系。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐