MCP 的三种数据传输模式教程(stdio / SSE / Streamable HTTP)

适用日期:2026-03-25
术语说明:本文的“SSE 模式”指 旧版 HTTP+SSE 传输(legacy),不是 Streamable HTTP 中可选的 SSE 流式响应。


1. 优先级

如果你现在在做新项目,优先级应该是:

  1. 本地单机场景:stdio
  2. 远程服务化场景:streamable-http
  3. HTTP+SSE(旧版)仅用于兼容历史客户端/服务端

原因很简单:

  • MCP 最新规范(2025-11-25)标准传输是 stdio + streamable-http
  • HTTP+SSE 已被替代,保留主要是向后兼容

1.1 版本时间线

  1. 2024-11-05:规范里有 stdio 与旧 HTTP+SSE 传输
  2. 2025-03-26:规范开始将远程 HTTP 方向切到 streamable-http
  3. 2025-11-25streamable-http 成为当前主方案,旧 HTTP+SSE 进入兼容语义

如果你在文档里看到 “SSE transport”,先确认是哪个版本的规范,不要混在一起解读。


2. 三种模式总览对比

维度 stdio HTTP+SSE(旧) streamable-http(新)
连接形态 客户端拉起子进程 远程 HTTP 双端点 远程 HTTP 单端点
标准状态 当前标准 已废弃(兼容) 当前标准
通信方式 stdin/stdout 行分隔 JSON-RPC SSE 收消息 + POST 发消息 POST 发消息,响应可 JSON 或 SSE;也可 GET 打开 SSE
典型部署 本机工具、IDE 插件 历史系统 云服务、网关、多客户端
复杂度 中-高
关键风险 stdout 混入日志 端点管理复杂 鉴权、会话、重连

3. 模式一:stdio

3.1 适合什么场景

  • MCP Server 与客户端部署在同一台机器
  • 你希望最小化网络、鉴权、反向代理复杂度
  • 开发调试阶段先跑通能力

3.2 通信模型

Client 启动 Server 子进程
Client -> (stdin) -> Server
Server -> (stdout) -> Client
stderr 仅用于日志

规范关键点:

  • JSON-RPC 消息按“每行一条”分隔
  • 消息不能包含内嵌换行
  • stdout 只能输出合法 MCP 消息
  • 日志写 stderr,不要写 stdout

3.3 最小示例(配置思路)

[mcp_servers.my_local_stdio]
command = "python"
args = ["/path/to/server.py"]

3.4 优缺点

优点:

  • 简单、稳定、延迟低
  • 不涉及 HTTP 暴露面

缺点:

  • 不能天然做远程多客户端共享
  • 进程生命周期由客户端托管,运维能力较弱

3.5 常见坑

  1. Server 把日志打印到 stdout,导致 JSON-RPC 解析失败
  2. 某些库输出 banner 到 stdout
  3. 子进程环境变量不完整,导致认证失败

4. 模式二:HTTP+SSE(旧版,legacy)

这是历史方案,常见于老 MCP 客户端。新系统建议迁移到 streamable-http

4.1 它是怎么工作的

旧模式需要两个端点:

  1. SSE 端点:客户端建立事件流、接收服务端消息
  2. POST 端点:客户端把 JSON-RPC 发给服务端

建立连接后,服务端先在 SSE 流发一个 endpoint 事件,告诉客户端“后续 POST 发到哪个 URL”。

4.2 典型时序

GET /sse  (打开 SSE)
<- event: endpoint  data: {"uri":"/messages?..."}
POST /messages?... (发送 JSON-RPC)
<- event: message   data: {...JSON-RPC...}

4.3 为什么被替代

  • 模型简单但端点分裂,集成成本高
  • 与现代 API 网关和统一路由模型不够一致
  • 新规范将远程通信统一到 streamable-http

4.4 什么时候还会用到

  • 你的客户端仍停留在老协议栈
  • 你在做历史系统迁移期双栈兼容

5. 模式三:streamable-http(推荐)

5.1 核心特征

  • 使用一个 MCP endpoint(如 /mcp
  • 该端点必须支持 POST,可选支持 GET
  • POST 发送 JSON-RPC,响应可为:
  1. application/json(单次返回)
  2. text/event-stream(SSE 流式返回)

5.2 关键请求要求

客户端 POST 必须带:

  • Accept: application/json, text/event-stream
  • Body 是单个 JSON-RPC request/notification/response

如果输入是 request,服务端必须返回 JSON 或 SSE 之一。

5.3 会话与版本头

常见生产实现会用这两个头:

  • MCP-Session-Id:初始化后由服务端分配,会话级状态
  • MCP-Protocol-Version:后续请求携带协商版本(如 2025-11-25

如果携带的 session 失效,服务端可回 404,客户端应重新 initialize

5.4 最小时序

POST /mcp  initialize
POST /mcp  notifications/initialized
POST /mcp  tools/list
POST /mcp  tools/call

5.5 为什么它更适合新系统

  • 单端点模型,路由与网关更清晰
  • 同时覆盖“简单 JSON 返回”与“流式 SSE 返回”
  • 更利于标准化认证、审计、会话管理

6. 一个容易混淆的点:SSE 有两种语境

很多团队会把“支持 SSE”理解错。这里明确区分:

  1. 旧传输:HTTP+SSE(legacy transport)
  • 它本身是一套旧传输协议模型
  1. 新传输里的 SSE 流:streamable-http + text/event-stream
  • 这是新传输中的“响应形态”之一
  • 不等于你在使用旧 transport

7. 选型建议(按场景)

7.1 本机工具链(CLI / IDE / 自动化脚本)

优先 stdio

原因:低成本、快启动、好调试。

7.2 团队共享服务 / 云端 Agent 平台

优先 streamable-http

原因:多客户端、鉴权、网关、可观测性都更自然。

7.3 老系统平滑迁移

短期双栈:legacy SSE + streamable-http

做法:

  1. 先让服务端同时支持新旧
  2. 客户端优先尝试新传输
  3. 新传输失败再回退旧传输
  4. 完成客户端升级后下线旧端点

8. 迁移路线(SSE -> streamable-http)

8.1 服务端迁移

  1. 新增 /mcp 单端点
  2. 保留旧 SSE+POST 端点一段时间
  3. 统一认证、日志与 trace id
  4. 监控新旧流量比例

8.2 客户端迁移

  1. 对用户输入的 URL 先 POST initialize(按新传输)
  2. 若返回 400/404/405,再尝试旧 SSE 握手
  3. 一旦新传输成功,固定走新传输

8.3 下线标准

  • 旧端点调用量低于阈值(例如 <1%)
  • 一段观察期内无关键告警
  • 所有核心客户端版本均完成升级

9. 调试与排障清单

9.1 stdio 模式

  1. 看 server 日志是否误写到 stdout
  2. 检查是否有非法前缀输出(banner、彩色日志)
  3. 检查换行分隔是否正确

9.2 streamable-http 模式

  1. URL 必须包含 MCP endpoint(例如 /mcp
  2. Accept 头是否正确
  3. 是否携带了正确的 MCP-Session-Id
  4. 返回 404 是否触发了重新初始化
  5. 代理是否剥离了 SSE 相关 header

9.3 WSL/本机网络

如果在 Windows + WSL 里出现:

  • localhost 可用但 127.0.0.1 不可用(或反过来)

优先使用实际可通地址,并检查:

  1. 服务绑定地址(127.0.0.1 / 0.0.0.0
  2. 端口转发与防火墙策略
  3. Host 与 WSL 的回环映射行为

10. 你可以直接复用的“团队规范”

建议在团队内统一这 5 条:

  1. 新项目默认 streamable-http,本地开发可 stdio
  2. 所有新服务都必须支持 initialize -> initialized
  3. 强制记录 trace_id / request_id / server_name / method / latency
  4. 高风险工具必须有鉴权和确认门禁
  5. HTTP+SSE 只作为迁移兼容,不新增依赖

11. 一页总结

  • stdio:本地最稳,开发最快
  • HTTP+SSE(旧):历史兼容,逐步下线
  • streamable-http:当前远程标准方案

判断标准很务实:

  • 单机调试优先 stdio
  • 远程共享优先 streamable-http
  • 能不用旧 SSE 就不要再新增旧 SSE

12. 官方参考(建议收藏)

  • 最新传输规范(2025-11-25):https://modelcontextprotocol.io/specification/2025-11-25/basic/transports
  • 旧版传输规范(2024-11-05):https://modelcontextprotocol.io/specification/2024-11-05/basic/transports
  • 生命周期(initialize / initialized):https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle

13. 三种模式的最小上手示例

13.1 stdio(本地子进程)

Codex CLI 配置示例:

[mcp_servers.local_stdio]
command = "python"
args = ["/abs/path/to/server.py"]

13.2 streamable-http(新)

Codex CLI 配置示例:

[mcp_servers.remote_http]
url = "http://localhost:8000/mcp"

最小连通性测试(initialize):

curl -i -X POST http://localhost:8000/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{"tools":{}},"clientInfo":{"name":"manual","version":"0.1"}}}'

13.3 旧 HTTP+SSE(legacy)

建立 SSE:

curl -N http://localhost:8000/sse

再按 endpoint 事件给出的 URL 发 POST JSON-RPC 请求。

Logo

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

更多推荐