Model Context Protocol (MCP) 是一种为 AI 应用设计的客户端-服务器通信协议。它通过标准化的消息格式和生命周期管理,让客户端(如 IDE 插件、聊天界面)和服务器(如 AI 模型后端)能够高效、可靠地交互。要实现这种交互,双方必须依赖一个共同的“传输层”,它定义了消息如何被实际发送和接收。
MCP 目前定义了两种标准的传输机制:stdio 和 Streamable HTTP。stdio 主要用于客户端启动和管理服务器子进程的场景,通信通过标准输入输出进行。而 Streamable HTTP 则为网络环境设计,允许客户端和服务器作为独立进程通过 HTTP 进行通信。本文将重点介绍 Streamable HTTP 是什么,以及如何使用它。

MCP 的通信基础:JSON-RPC 与生命周期
在深入了解 HTTP 传输之前,需要先明白 MCP 通信的两个基本前提:消息格式和交互流程。
MCP 规定所有消息都必须使用 JSON-RPC 2.0 格式进行编码。JSON-RPC 是一种轻量级的远程过程调用协议,它将每一次通信都封装成一个 JSON 对象,其中包含了方法名 method、参数 params、请求 ID id 等字段。这使得通信内容结构化,易于解析。
MCP 的交互流程遵循一个严格的生命周期,分为三个阶段:初始化(Initialization)、操作(Operation)和关闭(Shutdown)。
- 初始化:这是客户端与服务器的第一次交互。客户端发送
initialize请求,双方交换并协商协议版本、功能支持等信息。 - 操作:初始化成功后,连接进入操作阶段。客户端和服务器可以根据协商好的功能,自由地交换各类 JSON-RPC 消息。
- 关闭:当通信结束时,通过关闭底层连接来终止会话。
理解这个生命周期至关重要,因为它规定了通信的“先后顺序”,比如客户端必须在发送任何业务请求之前先完成初始化。
MCP 的两种标准传输方式
有了统一的消息格式和交互流程,接下来就是选择一种方式来“搬运”这些 JSON-RPC 消息。MCP 官方定义了两种传输方式。
| 特性 | stdio | Streamable HTTP |
|---|---|---|
| 进程关系 | 客户端启动服务器作为子进程 | 客户端和服务器是独立进程 |
| 通信方式 | 标准输入(stdin)和标准输出(stdout) | HTTP POST 和 GET 请求 |
| 适用场景 | 本地集成工具,如 IDE 插件 | 网络服务,远程或本地服务器 |
| 连接管理 | 客户端管理子进程的生命周期 | 可处理多个客户端连接 |
| 流式传输 | 天然支持 | 通过 Server-Sent Events (SSE) 实现 |
stdio 方式简单直接,适合本地环境。但当客户端和服务器需要解耦、独立部署并通过网络通信时,Streamable HTTP 就成了必然选择。它不仅提供了标准 HTTP 的灵活性,还通过 Server-Sent Events (SSE) 实现了高效的服务端推送能力。
深入 Streamable HTTP 传输
Streamable HTTP 的核心设计是提供一个单一的 HTTP 端点路径(例如 https://example.com/mcp),该路径同时支持 POST 和 GET 请求,以满足不同的通信需求。
POST 请求主要用于客户端向服务器发送消息,而 GET 请求则用于客户端建立一个持久的连接,以接收来自服务器的主动推送。这种推送通常通过 Server-Sent Events (SSE) 实现,它允许服务器在一个长效的 HTTP 连接上向客户端单向流式传输数据。
安全性:不可忽视的前提
在网络环境中暴露服务,安全性是第一要务。MCP 规范明确提出了在实现 Streamable HTTP 传输时必须遵守的安全准则:
- 验证 Origin 头:服务器必须检查所有请求的
OriginHTTP 头,以防止 DNS 重绑定攻击。这种攻击可能让恶意网站冒充合法来源,与本地运行的 MCP 服务器进行交互。 - 绑定本地主机:在本地开发或运行服务时,服务器应仅绑定到
localhost(127.0.0.1),而不是所有网络接口 (0.0.0.0)。这可以防止局域网内的其他设备意外访问到你的服务。 - 实现身份验证:所有连接都应该有适当的认证机制,确保只有授权的客户端才能访问服务器。
忽略这些保护措施会给应用带来严重的安全风险。
客户端向服务器发送消息:POST 请求
当客户端需要向服务器发送一个 JSON-RPC 消息(无论是请求、通知还是响应)时,它必须发起一个 HTTP POST 请求到 MCP 端点。
这个 POST 请求的主体部分就是一个完整的 JSON-RPC 消息。同时,请求头中必须包含 Accept 字段,声明客户端能够同时接受 application/json 和 text/event-stream 两种响应类型。
服务器收到 POST 请求后的行为取决于收到的 JSON-RPC 消息类型:
- 如果消息是 通知 (
notification) 或 响应 (response),服务器在成功处理后应返回HTTP 202 Accepted状态码,且响应体为空。这表示服务器已经收到并接受了该消息。 - 如果消息是 请求 (
request),服务器有两种响应方式。它可以返回Content-Type: application/json,将单个 JSON-RPC 响应作为 HTTP 响应体返回;或者,它可以返回Content-Type: text/event-stream,开启一个 SSE 流,在该流上逐步发送一个或多个消息,并最终包含对该请求的响应。
当服务器选择开启 SSE 流来响应一个请求时,它可以在发送最终的 JSON-RPC 响应之前,先推送一些相关的通知或中间状态。这种机制非常适合执行时间较长的任务,客户端可以实时收到进度更新。
客户端监听服务器消息:GET 请求
除了通过 POST 请求触发通信,客户端还可以主动发起 HTTP GET 请求来打开一个专门用于监听服务器消息的通道。这允许服务器在没有任何客户端请求的情况下,主动向客户端推送消息,例如配置更新、全局通知等。
客户端发起 GET 请求时,必须在 Accept 头中指明支持 text/event-stream。服务器如果支持此功能,就会返回 Content-Type: text/event-stream 并建立一个 SSE 连接。
需要注意的是,通过 GET 请求建立的 SSE 流,其用途与 POST 请求响应的流不同。它主要用于承载与特定客户端请求无关的、由服务器主动发起的通信。因此,服务器不应该在这个流上发送 JSON-RPC 响应,除非是为了恢复一个之前中断的连接。
将生命周期应用于 HTTP 传输
了解了 POST 和 GET 的基本用法后,我们来看看 MCP 的生命周期是如何在 Streamable HTTP 上具体实现的。
初始化与会话建立
所有通信始于初始化。客户端通过向 MCP 端点发送一个 POST 请求来启动这个过程,请求体是一个 initialize 方法的 JSON-RPC 消息。
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {
"name": "ExampleClient",
"version": "1.0.0"
}
}
}
服务器收到后,会返回一个包含其自身能力和信息的 JSON-RPC 响应。对于 Streamable HTTP 传输,这个响应中还有一个非常关键的部分:Mcp-Session-Id HTTP 头。
这个头字段包含一个由服务器生成的唯一会话 ID。客户端在收到后,必须在后续所有请求中都带上这个 ID。这标志着一个有状态的会话正式建立。
会话管理与版本控制
一旦会话建立,客户端的每一次后续请求都必须包含两个重要的 HTTP 头:Mcp-Session-Id 和 MCP-Protocol-Version。
Mcp-Session-Id: 用于标识客户端属于哪个会话,让服务器能够管理和隔离不同客户端的状态。MCP-Protocol-Version: 告知服务器客户端当前使用的协议版本,该版本是在初始化阶段协商确定的。
一个典型的后续请求(例如,一个 initialized 通知)看起来像这样:
POST /mcp HTTP/1.1
Host: example.com
Content-Type: application/json
Accept: application/json, text/event-stream
Mcp-Session-Id: 1868a90c-a57d-4879-881b-90f7d58f4f3c
MCP-Protocol-Version: 2025-06-18
{
"jsonrpc": "2.0",
"method": "notifications/initialized"
}
如果服务器收到一个缺少有效会话 ID 的请求(初始化请求除外),它应该返回 HTTP 400 Bad Request。如果一个会话 ID 已过期或被服务器终止,服务器则会返回 HTTP 404 Not Found,此时客户端需要重新发起初始化流程来建立新会话。
客户端也可以通过发送一个带 Mcp-Session-Id 头的 DELETE 请求来主动终结一个会话。
提升通信的可靠性
网络是不稳定的,连接随时可能中断。Streamable HTTP 传输机制也考虑到了这一点,提供了连接恢复的能力。
连接中断与恢复
当服务器通过 SSE 推送消息时,它可以为每个事件附加一个唯一的 id 字段。这个 ID 在会话内是全局唯一的,可以看作是消息流中的一个“光标”。
如果客户端的 SSE 连接意外断开,它可以重新发起一个 GET 请求,并在请求头中加入 Last-Event-ID 字段,其值为它收到的最后一个事件的 ID。
服务器收到这个头后,便可以从那个断开点开始,重发所有丢失的消息,然后继续正常推送。这确保了即使在不稳定的网络下,客户端也能收到完整的消息序列,极大地提升了通信的可靠性。
通过 POST 和 GET 请求的组合,辅以会话管理和连接恢复机制,MCP Streamable HTTP 为构建健壮、灵活的 AI 应用通信架构提供了坚实的基础。
开发必备:API 全流程管理神器 Apifox
介绍完上文的内容,我想额外介绍一个对开发者同样重要的效率工具 —— Apifox。作为一个集 API 文档、API 调试、API 设计、API 测试、API Mock、自动化测试等功能于一体的 API 管理工具,Apifox 可以说是开发者提升效率的必备工具之一。
如果你正在开发项目需要进行接口调试,不妨试试 Apifox。注册过程非常简单,你可以直接在这里注册使用。

注册成功后可以先看看官方提供的示例项目,这些案例都是经过精心设计的,能帮助你快速了解 Apifox 的主要功能。
使用 Apifox 的一大优势是它完全兼容 Postman 和 Swagger 数据格式,如果你之前使用过这些工具,数据导入会非常方便。而且它的界面设计非常友好,即使是第一次接触的新手也能很快上手,快去试试吧!

