夜航船 NightShip · 返回主页 · 博客

MCP 三种传输模式选型:stdio、被废弃的 SSE、Streamable HTTP

2026-10-16 · 林一舟

现在去搜 MCP 教程,有个现象值得警惕:排在前面的文章里,相当一部分还在教你写 SSEServerTransport——这套写法在 2025 年 6 月的规范里已经被正式废弃了。代码能跑,方向是错的,等你照着它上线,改造成本会翻倍。

这篇把三种传输模式一次讲透:它们各自解决什么问题、SSE 为什么死掉、以及 2026 年今天你应该怎么选。不重复入门内容,默认你已经跑通过第一个 server。

一、stdio:被低估的默认答案

stdio 模式下,客户端(Claude Desktop、Cursor)把你的 server 当作本地子进程拉起,通过标准输入输出交换 JSON-RPC 消息。

它的优点经常被"本地"两个字低估:

什么时候 stdio 是永久正确答案而不是权宜之计?当你的工具依赖本地环境——本机文件、内网系统、用户自己的凭据。这类工具做成远端反而是错的:数据不出本机,本身就是卖点。

对应的纪律是:stdio server 拥有用户本机的全部权限,你每注册一个 tool,就是授权模型动一次用户的机器。参数校验(zod)和最小权限不是最佳实践,是底线。

二、SSE 是怎么死的

最初的远程方案叫 HTTP+SSE:两个端点,一个挂 SSE 长连接收服务端推送,一个 POST 收客户端请求。它在单机 demo 里工作得很好,然后在大规模部署时暴露了三个致命伤:

  1. 长连接与水平扩展天然冲突:连接粘在单个实例上,扩容要么做 sticky session,要么把消息路由复杂化
  2. 基础设施不友好:大量代理、网关、Serverless 平台对长连接超时处理各异,部署像扫雷
  3. 断线恢复糟糕:连接断了,会话状态也丢了

所以 2025-06 规范用 Streamable HTTP 取代了它:单个端点(/mcp),客户端全部走 POST,服务端可选把响应升级为 SSE 流。需要推送才有流,不需要就是普通请求——长连接从"必选项"变成了"可选项",上面三个问题随之瓦解。旧的 /sse 端点模式退出历史。

判断标准很简单:2025 年中以后的教程/模板还在以 SSEServerTransport 为核心的,直接关掉。

三、Streamable HTTP:无状态是新的默认

Streamable HTTP 有两种部署形态,这是选型的真正分水岭:

有状态(stateful):服务端为每个会话生成 mcp-session-id,后续请求带这个头,会话粘在单实例上。适合需要跨请求记忆、服务端推送的长交互场景。代价:多实例部署需要 sticky session。

无状态(stateless):每个请求独立处理,不保留会话。2026-07 规范修订把它推到台前——无状态的 server 天然可缓存、可路由、可水平扩展,放在任何 CDN/网关后面都不别扭。对"工具调用"这类请求-响应型负载,无状态几乎总是更好的默认。

无状态模式的核心代码出乎意料地短(express):

app.post("/mcp", async (req, res) => {
  const transport = new StreamableHTTPServerTransport({
    sessionIdGenerator: undefined,   // 无会话
    enableJsonResponse: true,        // 纯 JSON 响应,不升级 SSE
  });
  res.on("close", () => void transport.close());
  const server = createServer();     // 你的工具注册,与 stdio 完全同一份
  await server.connect(transport);
  await transport.handleRequest(req, res, req.body);
});

注意第三行注释的含义:双传输共用一套能力注册是工程上最重要的设计决策。你的工具写在 createServer() 里,stdio 和 HTTP 只是两种"插座"——改工具永远只改一处,这是模板设计里我最坚持的一条。

四、三问决策树

  1. 工具依赖本地环境或用户本机凭据? → stdio,别犹豫
  2. 要对外提供服务/收费/给团队共享? → Streamable HTTP,默认无状态模式
  3. 需要服务端主动推送或长会话记忆? → 才考虑有状态模式(并准备好吃 sticky session 的复杂度)

一个常见误判:开发者为了"显得正式"把个人工具也做成远端 HTTP。代价是多出来的部署、鉴权、证书、监控,换来的功能一项都用不上。stdio 到 HTTP 的迁移成本很低(能力注册不动),从 stdio 起步、需要时再上远端,几乎总是最优路径。

五、从旧 SSE 教程迁移的三个坑


把这套双传输+鉴权+无状态默认的工程结构直接拿走:我做了一个生产就绪的 MCP Server 模板(TypeScript,含真协议测试、CI/CD、npm 发布流和容器部署配置),配合《MCP 开发速查手册》食用,改三处当天发布。入口在我主页。

关于作者:林一舟,夜航船(NightShip)主理人。白天泊岸,夜里出航。

我是林一舟,「夜航船 NightShip」——一个只在夜里发布产品的独立开发者。这篇是夜航手记的原创文章。

🛠 免费工具:MCP 配置生成器 · JSON 转 Schema · MCP 端点测试器

📖 完整《MCP 开发速查手册》(v2 基线 + 迁移速查):淘宝搜「夜航船NightShip」,海外 Gumroad