MCP 是什么

MCP(Model Context Protocol,模型上下文协议)是由 Anthropic 推出的一种开放标准,旨在统一大型语言模型(LLM)与外部数据源和工具之间的通信协议。

也就是 Claude 所属的公司推出的,为了补充大模型无法联网搜索网络上的资料而生,个人理解。

MCP 采用 client-server 架构,由 Host、Client 和 Server 三个基本组件构成。

有啥优势呢?

统一标准:创建一个通用标准,使 AI 应用程序的开发和集成变得更加简单和统一。
灵活性:支持多种语言的 SDK,便于开发者快速构建和调试。
网络效应:随着越来越多的服务器和工具支持 MCP,其影响力在不断扩大。

MCP 传输机制(Transport)是 MCP 客户端与 MCP 服务器通信的一个桥梁,定义了客户端与服务器通信的细节,帮助客户端和服务器交换消息。

MCP 协议使用 JSON-RPC 来编码消息。

JSON-RPC 消息必须使用 UTF-8 编码。

MCP 协议目前定义了三种传输机制用于客户端-服务器通信:

1、stdio:通过标准输入和标准输出进行通信

2、SSE:通过 HTTP 进行通信,支持流式传输。(协议版本 2024-11-05 开始支持,即将废弃)

3、Streamble HTTP:通过 HTTP 进行通信,支持流式传输。(协议版本 2025-03-26 开始支持,用于替代 SSE)MCP 协议要求客户端应尽可能支持 stdio。

MCP 协议的传输机制是可插拔的,也就是说,客户端和服务器不局限于 MCP 协议标准定义的这几种传输机制,也可以通过自定义的传输机制来实现通信。

stdio 传输stdio 即 standard input & output(标准输入 / 输出)。

是 MCP 协议推荐使用的一种传输机制,主要用于本地进程通信。

在 stdio 传输中:客户端以子进程的形式启动 MCP 服务器。

服务器从其标准输入(stdin)读取 JSON-RPC 消息,并将消息发送到其标准输出(stdout)。

消息可能是单个 JSON-RPC 请求、通知、响应,或者包含多个请求、通知、响应的 JSON-RPC 批处理。消息由换行符分隔,且不得包含嵌套的换行符。

服务器可以将其 UTF-8 字符串写入标准错误(stderr)以进行日志记录。

客户端可以捕获、转发或忽略此日志。

服务器不得向 stdout 写入无效的 MCP 消息内容。

客户端不得向服务器的 stdin 写入无效的 MCP 消息内容。

stdio 通信流程

客户端以子进程的方式启动服务器

客户端往服务器的 stdin 写入消息

服务器从自身的 stdin 读取消息

服务端往自身的 stdout 写入消息

客户端从服务器的 stdout 读取消息

客户端终止子进程,关闭服务器的 stdin

服务器关闭自身的 stdout

stdio 传输的利弊

stdio 传输机制主要依靠本地进程通信实现。

主要的优势是:

无外部依赖,实现简单

无网络传输,通信速度快

本地通信,安全性高

也有一些局限性:单进程通信,无法并行处理多个客户端请求进程通信的资源开销大,很难在本地运行非常多的服务

stdio 传输的适用场景

stdio 传输适用于要操作的数据资源位于本地计算机,且不希望暴露外部访问的场景。

比如,你希望通过一个聊天客户端,来总结你的微信消息,微信消息文件存储在你的本地电脑,外部访问不了,也不应该访问。这种情况,你可以实现一个 MCP 服务器来读取你电脑上的微信消息文件,通过 stdio 传输接收 MCP 客户端的访问请求。

如果你要访问的是一个远程服务器上的文件,也可以使用 stdio 传输,流程会复杂一些:先写一个 API 服务,部署在远程服务器,操作远程服务器上的资源,暴露公网访问写一个 MCP 服务器,对接远程 API,再通过 stdio 传输与客户端本地通信

既然 stdio 传输访问远程资源这么麻烦,是不是应该有一种更适合远程资源访问的传输机制?

当然有。可以使用 SSE 传输。

SSE 传输

MCP 协议使用 SSE(Server-Sent Events) 传输来解决远程资源访问的问题。底层是基于 HTTP 通信,通过类似 API 的方式,让 MCP 客户端直接访问远程资源,而不用通过 stdio 传输做中转。

在 SSE 传输中,服务器作为一个独立进程运行,可以处理多个客户端连接。

服务器必须提供两个端点:

一个 SSE 端点,供客户端建立连接并从服务器接收消息

一个常规 HTTP POST 端点,供客户端向服务器发送消息

当客户端连接时,服务器必须发送一个包含客户端用于发送消息的 URL 的端点事件。所有后续客户端消息必须作为 HTTP POST 请求发送到该端点。

服务器消息作为 SSE 消息事件发送,消息内容以 JSON 格式编码在事件数据中。

SSE 通信流程

客户端向服务器的 /sse 端点发送请求(一般是 GET 请求),建立 SSE 连接

服务器给客户端返回一个包含消息端点地址的事件消息

客户端给消息端点发送消息

服务器给客户端响应消息已接收状态码

服务器给双方建立的 SSE 连接推送事件消息

客户端从 SSE 连接读取服务器发送的事件消息

客户端关闭 SSE 连接

SSE 安全防护

当使用 SSE 传输时,服务器一方需要实现一些必要的安全防护措施:

服务器必须验证所有传入连接的 Origin 头,以防止 DNS 重绑定攻击

在本地运行时,服务器应仅绑定到 localhost(127.0.0.1),而不是所有网络接口(0.0.0.0)

服务器应对所有连接实施适当的身份验证

如果没有这些保护措施,攻击者可能会使用 DNS 重绑定从远程网站与本地 MCP 服务器交互。

SSE 传输的适用场景

SSE 传输适用于 MCP 客户端与 MCP 服务器不在同一个网络下的通信场景。

比如,你希望在本地电脑,通过对话的方式,查询你云服务器上的数据库。你就可以在你的云服务器上部署一个 MCP 服务器,去读取数据库,再跟你本地电脑上的 MCP 客户端建立连接通信。

当然,所有用 SSE 传输实现的 MCP 服务器,理论上都可以通过 stdio 传输 + API 的方式实现。

区别在于:

用 SSE 传输,MCP 客户端直接与 MCP 服务器通信,而不用通过本地的 stdio 传输调用 API 进行中转。

用 SSE 传输,在 MCP 客户端只需要一个 URL 即可接入,对本地环境无要求,也无需在本地运行 MCP 服务器,用户侧的使用门槛更低。

SSE 传输的利弊

SSE 传输主要解决远程资源访问的问题,依靠 HTTP 协议实现底层通信。

SSE 传输的主要优势:

支持远程资源访问,让 MCP 客户端可以直接访问远程服务,解决了 stdio 传输仅适用于本地资源的局限

基于标准 HTTP 协议实现,兼容性好,便于与现有 Web 基础设施集成

服务器可作为独立进程运行,支持处理多个客户端连接

相比 WebSocket 实现简单,是普通 HTTP 的扩展,不需要协议升级

SSE 传输的主要劣势与问题:

连接不稳定:在无服务器(serverless)环境中,SSE 连接会随机、频繁断开,影响 AI 代理需要的可靠持久连接

扩展性挑战:SSE 不是为云原生架构设计的,在扩展平台时会遇到瓶颈

浏览器连接限制:每个浏览器和域名的最大打开连接数很低(6 个),当用户打开多个标签页时会出现问题

代理和防火墙问题:某些代理和防火墙会因为缺少 Content-Length 头而阻止 SSE 连接,在企业环境部署时造成挑战

复杂的双通道响应机制:MCP 中的 SSE 实现要求服务器在接收客户端消息后,既要给当前请求响应,也要给之前建立的 SSE 连接发送响应消息

无法支持长期的无服务器部署:无服务器架构通常自动扩缩容,不适合长时间连接,而 SSE 需要维持持久连接

需要大量会话管理:需要为每个 SSE 连接分配唯一标识(sessionId)来防止数据混淆,增加了实现复杂度

需要额外的连接检测和超时关闭机制:需要实现心跳检测和超时机制来避免资源泄露

正因为这些问题,MCP 协议已经引入了新的 Streamable HTTP 传输机制(2025-03-26 版本)来替代 SSE,并计划废弃 SSE 传输。新的传输机制保留了 HTTP 的基础,但支持更灵活的连接方式,更适合现代云架构和无服务器环境。

Streamable HTTP 传输

Streamable HTTP 传输是 MCP 协议在 2025-03-26 版本中引入的新传输机制,用于替代之前的 SSE 传输。

在 Streamable HTTP 传输中,服务器作为一个独立进程运行,可以处理多个客户端连接。此传输使用 HTTP POST 和 GET 请求,服务器可以选择使用服务器发送事件(SSE)来流式传输多个服务器消息。

服务器必须提供一个同时支持 POST 和 GET 方法的单个 HTTP 端点。例如:https://api.mcp.com/mcp。

Streamable HTTP 通信流程

客户端给服务器的通信端点发消息

服务器给客户端响应消息

客户端根据服务器的响应类型,继续给服务器发消息

服务器继续响应客户端消息

跟 SSE 传输不同的点在于,Streamable HTTP 传输中,客户端与服务器的消息交互,基本上是“一来一回”的(单通道响应)。而这个“一来一回”的消息交互,可能会有很多种组合类型。

客户端发送 GET 请求给服务器,服务器返回 SSE 连接

客户端 POST JSON-RPC 编码的消息给服务器,服务器返回 JSON-RPC 编码的消息响应

客户端 POST JSON-RPC 编码的消息给服务器,服务器返回一个 SSE 连接

客户端给 SSE 连接发消息,服务器收到后给 SSE 连接响应消息

服务器响应的消息,可能包含状态标识:Mcp-Session-Id

客户端发消息时候需要带上状态标识:Mcp-Session-Id

Streamable HTTP 传输的利弊

Streamable HTTP 传输机制结合了 SSE 传输的远程访问能力和无状态 HTTP 的灵活性,同时解决了 SSE 传输中的许多问题。

主要优势:

兼容无服务器环境,可以在短连接模式下工作

灵活的连接模式,支持简单的请求-响应和流式传输

会话管理更加标准化和清晰

支持断开连接恢复和消息重传

保留了 SSE 的流式传输能力,同时解决了其稳定性问题

向后兼容,可以支持旧版客户端和服务器

主要劣势:

相比单纯的 stdio 传输实现复杂度更高

仍需处理网络连接断开和恢复的逻辑

会话管理需要服务器引入额外的组件(比如用 Redis 来存储 Session)

Streamable HTTP 传输的适用场景

Streamable HTTP 传输适用于:

需要远程访问服务的场景,特别是云环境和无服务器架构

需要支持流式输出的 AI 服务

需要服务器主动推送消息给客户端的场景

大规模部署需要高可靠性和可扩展性的服务

需要在不稳定网络环境中保持可靠通信的场景

与 SSE 传输相比,Streamable HTTP 传输是一个更全面、更灵活的解决方案,特别适合现代云原生应用和无服务器环境。

自定义传输

MCP 客户端和 MCP 服务器可以实现额外的自定义传输机制以满足其特定需求。MCP 协议与传输无关,可以在支持双向消息交换的任何通信通道上实现。

选择支持自定义传输的实现者必须确保他们保留由 MCP 定义的 JSON-RPC 消息格式和生命周期要求。自定义传输应记录其特定的连接建立和消息交换模式,以实现互操作性。

MCP 协议支持的三种标准传输机制以及自定义传输的实现方式:

stdio 传输:

通过标准输入/输出进行本地进程间通信

优势在于实现简单、通信速度快、安全性高

主要适用于本地数据访问场景

局限于单进程通信,资源开销较大

SSE 传输(即将废弃):

基于 HTTP 协议,支持远程资源访问

使用双通道响应机制(SSE 连接 + POST 端点)

存在连接不稳定、扩展性差、浏览器限制等问题

不适合无服务器(serverless)环境和云原生架构

Streamable HTTP 传输:

替代 SSE 的新传输机制,兼容现代云架构

更灵活的连接模式,支持简单请求-响应和流式传输

标准化的会话管理和断点恢复功能

适合远程访问、无服务器环境和大规模部署

自定义传输机制:

MCP 协议支持实现自定义传输以满足特定需求

可以针对特定部署环境和使用场景进行优化

示例中实现了一个 Rest Transport,适合无状态、短连接场景

传输机制的选择应基于具体应用场景:

本地数据访问优先选择 stdio 传输

远程资源访问优先选择 Streamable HTTP 传输

特殊需求场景可考虑实现自定义传输

MCP 协议的可插拔传输架构使其能够灵活适应不同的部署环境和通信需求,从简单的本地工具到复杂的云服务均可支持。随着技术发展,传输机制也在不断优化,以提供更好的性能、可靠性和可扩展性。

打赏作者

您将是第一位评论人!

提醒
avatar