MCP 系列 1:MCP 协议、架构与通信机制


从本文开始进入 MCP 系列,讨论如何把工具、资源和提示词变成可以被不同语言、进程和 Agent 客户端复用的标准能力。

MCP 解决的是能力标准化和跨应用复用问题。服务端按照统一协议公开工具、资源和提示词,支持 MCP 的客户端就能发现并调用这些能力,而不需要理解服务端使用 Python、Java 还是其他语言实现。

1. MCP 是什么

MCP 的全称是 Model Context Protocol,即模型上下文协议。它定义了 AI 应用与外部能力之间的通信方式。

MCP 不是模型,也不是 Agent 框架。它不负责决定什么时候调用工具,也不负责生成最终回答。它负责描述和传输能力,让客户端能够完成下面这些操作:

  • 发现服务端提供了哪些 Tool。
  • 读取服务端公开的 Resource。
  • 获取服务端维护的 Prompt。
  • 按统一 Schema 传入参数并得到结果。
  • 在初始化阶段协商双方支持的能力。

协议只规定通信规则,不限制实现语言。因此,Python Agent 可以调用 Java MCP Server,桌面应用也可以调用同一个网络 MCP Server。

2. Agent 外部能力接入方式对比

这几个概念经常同时出现,但职责不同。

本地 Tool 是应用进程中的可调用函数;Function Calling 是模型生成结构化工具请求的能力;普通 HTTP API 是系统之间通过 HTTP 约定的网络接口;MCP 则是在 JSON-RPC 基础上建立的标准协议,统一能力发现、调用、通知、生命周期和传输方式。

下表按照性质、范围、实现、复杂度、复用性和扩展方式进行比较。这里的复杂度是相对趋势,不是绝对结论:只有一个简单工具时,本地 Tool 或 Function Calling 往往最省事;当同一批能力需要被多个 AI 客户端复用时,MCP 的标准化优势才会更加明显。

对比项 本地 Tool Function Calling HTTP API MCP
性质 应用内部的函数或可调用对象 模型输出工具名称和结构化参数的能力 系统之间约定的网络接口 面向 AI 应用与外部能力的标准协议
覆盖范围 当前进程或当前项目中的具体能力 一次模型请求中声明的一个或多个工具 一个服务可以提供一个或多个业务端点 一个或多个 Server 可公开 Tools、Resources、Prompts 等能力
主要目标 让 Agent 执行应用内代码 让模型决定调用什么,并生成调用参数 让不同系统通过网络交换数据和执行操作 让不同 AI Host 以统一方式发现、连接和调用外部能力
实现方式 普通函数、装饰器和框架 Tool Schema 在模型请求中提供工具 Schema,再由应用执行模型返回的调用 使用 URL、HTTP Method、Header、请求体和响应体;可使用 OpenAPI 描述 使用 MCP SDK 或自行实现协议;消息遵循 JSON-RPC,可通过 stdio 或 Streamable HTTP 传输
能力发现 由应用启动时注册,通常不能跨进程自动发现 工具列表由应用传给模型,模型本身不负责发现服务 通常依赖文档、OpenAPI 或服务注册中心,不是统一的模型工具发现机制 Client 可以按协议列出能力,并在初始化时协商双方支持的功能
谁负责执行 Agent 所在应用直接执行函数 模型只提出调用请求,应用负责校验参数、执行代码并返回结果 HTTP Server 执行业务逻辑,调用方负责发起请求 MCP Server 执行 Tool 或访问底层数据,Host 负责授权和编排
开发复杂度 少量本地能力时较低;跨语言、跨进程复用时需要额外封装 少量工具时较低;工具增多后需要维护 Schema、执行映射和调用循环 取决于认证、错误处理、重试、版本管理和网络部署 初次接入需要实现 Client/Server 和协议生命周期;多客户端复用时可减少重复适配
复用性 通常局限于当前代码库和运行时 Schema 和执行代码常与应用及模型接口绑定,迁移时可能需要适配 跨语言复用性高,但每个 AI 应用通常仍需编写 API Client 和 Tool 包装 在支持 MCP 的 Host 之间复用性高,同一个 Server 可以被多个客户端接入
扩展方式 增加函数并重新注册、发布应用 增加工具 Schema 和对应执行逻辑 增加或修改 Endpoint,并同步更新接口文档和客户端 Server 增加能力后由 Client 动态获取;可通过能力协商和通知逐步扩展

这几种机制不是互斥关系。一个本地 Tool 内部可以调用 HTTP API,MCP Server 也可以把已有 HTTP API 包装成 MCP Tool。MCP 的 Streamable HTTP 虽然使用 HTTP 传输,但 MCP 不等于普通 HTTP API:HTTP 解决网络请求如何传输,MCP 还规定了初始化、能力协商、发现、调用和通知等上层语义。

一次完整调用可能同时使用它们:

用户问题
→ 模型通过 Function Calling 选择工具
→ Agent 找到工具的执行实现
  ├─ 直接执行本地 Tool
  └─ 调用 MCP Client
     → MCP Server 执行 Tool
     → Tool 内部可以继续调用 HTTP API
→ Tool 结果返回 Agent
→ 模型生成最终回答

所以,MCP 不取代 Function Calling,Function Calling 也不负责执行函数。模型仍然需要生成工具调用请求,Agent 负责校验和编排,具体能力可以来自本地 Tool、HTTP API,也可以来自独立 MCP Server。

3. 组件介绍

MCP 使用 Host、Client、Server 三层架构。

下图中的蓝色虚线框表示同一个 Host 进程。Host 在内部创建多个 Client 实例,每个 Client 只维护与一个 Server 的独立会话。

Host 进程、多个 MCP Client 与独立 Server 的架构

Client 与 Server 之间传输的是双向 JSON-RPC 消息,不是单向函数调用。Host 负责跨 Server 编排,Server 之间没有直接通信通道。

3.1 Host

Host 是用户直接使用的 AI 应用,例如 IDE、桌面助手或 Agent 应用。它负责:

  • 创建和管理 MCP Client。
  • 控制哪些 Server 可以连接。
  • 管理授权、用户同意和安全策略。
  • 把 MCP 返回的能力交给模型或 Agent。
  • 决定哪些上下文可以发送给服务端。

3.2 Client

Client 由 Host 创建,负责与某一个 Server 建立连接、协商能力和收发协议消息。

一个 Client 在一个会话中对应一个 Server。Host 如果连接三个 Server,通常会维护三个彼此隔离的 Client 连接。这样,一个 Server 不能直接查看另一个 Server 的通信内容。

3.3 Server

Server 提供具体能力。它可以是客户端临时启动的本地子进程,也可以是独立运行的网络服务。

Server 只应该获得完成当前调用所需的信息。它不会因为接入 MCP 就自动看见完整聊天记录,也不能直接访问其他 MCP Server。跨服务编排仍由 Host 或 Agent 负责。

4. MCP 编码消息

MCP 使用 JSON-RPC 2.0 编码消息。常见消息分为请求、响应、通知和错误。

一个请求包含方法、参数和请求 ID:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {}
}

响应使用相同 ID 与请求配对:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": []
  }
}

通知没有 id,发送方不等待对应响应。错误响应则包含错误代码和说明。

业务代码通常不需要手写这些 JSON。MCP SDK 会完成编码、请求 ID 管理和结果转换,但理解底层结构有助于排查初始化失败、方法不存在和参数不匹配。

5. MCP 连接的生命周期

一次 MCP 会话不是连接成功后立即调用 Tool,而是经过明确的初始化过程。

MCP 初始化、运行与关闭生命周期

主要阶段如下:

  1. Client 发送 initialize,声明协议版本和自身能力。
  2. Server 返回支持的协议版本、Server 信息和能力。
  3. Client 发送 notifications/initialized 初始化完成通知。
  4. 双方进入正常通信,可以列出或调用能力。
  5. 使用底层传输关闭连接;有状态 HTTP Session 还可以通过 DELETE 请求显式终止。

能力协商很重要。Server 只有声明支持 Tools,Client 才能按照协议使用工具相关方法;Resources、Prompts、Sampling 等能力也遵循相同原则。

MCP 没有定义专用的关闭协议消息。stdio 通过关闭输入流并结束 Server 子进程完成关闭,HTTP 则关闭相关连接。每个请求还应该设置超时;超时后停止等待,并在适用时发送取消通知,避免连接长期占用资源。

6. MCP Server 的三类核心能力

6.1 Tools

Tool 表示可以执行的操作,例如计算、查询数据库或读取业务系统。Tool 包含名称、说明和参数 Schema,通常由模型或 Agent 决定是否调用。

Tool 可能产生副作用。删除文件、发送消息或修改数据库之前,Host 应该进行权限控制或用户确认。

6.2 Resources

Resource 表示可以读取的数据,例如配置说明、文件内容或固定知识。它通过 URI 标识,例如:

guide://mcp

Resource 更接近“读取什么”,Tool 更接近“执行什么”。具体由客户端决定怎样把 Resource 放入模型上下文。

6.3 Prompts

Prompt 是服务端公开的可复用提示词模板。客户端可以列出 Prompt,并传入参数获得消息内容。

Prompt 不会自动执行模型,也不是系统提示词的唯一来源。它只是 MCP Server 提供的一种可发现能力。

7. MCP Client 能力

MCP Client 具有 Roots、Sampling 和 Elicitation 等功能。

  • Roots:客户端向 Server 声明允许访问的文件系统根目录。
  • Sampling:Server 请求 Host 使用模型生成内容,最终控制权仍在 Host。
  • Elicitation:Server 请求用户补充信息或确认操作。

本文只明确这些能力的位置,不编写实现。它们也不是每个 MCP Client 和 Server 都必须支持的功能,是否可用取决于初始化阶段的能力协商。

8. 通信机制

MCP 的基础协议负责定义 JSON-RPC 消息、生命周期和各种能力,传输层负责把这些消息送到通信的另一端。同一条 tools/call 请求无论通过标准输入输出还是 HTTP 发送,其 JSON-RPC 结构和语义都不应该改变。

需要先说明版本关系。当前 MCP 规范正式定义两种标准传输:

  1. stdio。

  2. Streamable HTTP。

  3. HTTP+SSE 是 旧标准传输,已经被 Streamable HTTP 取代。

本文仍将它作为第三种方式介绍,是因为部分 SDK、客户端和已有服务仍然需要兼容,后续实战也会运行旧 SSE 服务。它不应该作为网络新项目的首选。

三种传输的定位如下:

对比项 stdio HTTP+SSE Streamable HTTP
当前状态 当前标准传输 已废弃,仅用于兼容旧实现 当前标准网络传输
Server 形态 Client 启动的本地子进程 预先运行的独立 HTTP 服务 预先运行的独立 HTTP 服务
Client → Server 写入子进程 stdin 向服务端给出的消息端点发送 HTTP POST 每条消息向同一个 MCP 端点发送 HTTP POST
Server → Client 从子进程 stdout 读取 独立 SSE 长连接 POST 响应或可选的 SSE 流
端点数量 不使用网络端点 SSE 接收端点和 POST 发送端点 单一 MCP 端点
多客户端 通常每个 Client 启动独立进程 一个 Server 可以服务多个 Client 一个 Server 可以服务多个 Client
会话管理 由子进程生命周期天然隔离 通常由两个端点关联的连接状态管理 可无状态,也可使用 MCP-Session-Id
适用场景 桌面应用、CLI、本机工具 兼容旧客户端或旧 Server 远程服务、多用户和网络部署

8.1 stdio 传输

stdio 使用操作系统的标准输入和标准输出传输 UTF-8 编码的 JSON-RPC 消息。它不监听 TCP 端口,也不要求 MCP Server 预先作为守护进程启动。

它的真实进程关系是:Client 根据配置中的命令、参数和环境变量启动一个独立 MCP Server 子进程,然后通过管道与子进程通信。两者不是同一个进程,也不是在应用内直接调用普通函数。

Host 进程
    MCP Client
       启动 MCP Server 子进程
            stdin  接收 Client 发来的 JSON-RPC 消息
            stdout 向 Client 发出 JSON-RPC 消息
            stderr 输出日志

通信方向如下:

  • Client 把 JSON-RPC 请求、响应或通知写入 Server 的 stdin
  • Server 从 stdin 逐条读取消息,并把需要返回给 Client 的请求、响应或通知写入 stdout
  • Client 持续读取 stdout,再根据 JSON-RPC ID 把响应与请求对应起来。

这里不应把 stdout 简单理解为“响应通道”。MCP 是双向协议,Server 也可以主动向 Client 发送请求或通知,例如发起 Sampling 请求。因此,stdin 和 stdout 上都可能出现请求、响应和通知,差别只是发送方向。

每条 JSON-RPC 消息以换行符作为边界,消息中不能包含未转义的物理换行。发送方通常将一个 JSON 对象序列化为一行,写入管道后再追加换行符。接收方读到完整一行后才能进行 JSON 解析。

stdio 对输出内容有严格要求:

  • Server 的 stdout 只能包含合法 MCP 消息,不能使用 print() 输出启动提示、调试信息或普通日志。
  • Client 写入 Server stdin 的内容也必须是合法 MCP 消息。
  • Server 应该把普通日志写入 stderr。Client 可以显示、转发或忽略 stderr,不能因为 stderr 有输出就直接判断 Server 执行失败。

stdio 的生命周期通常由 Client 管理:

  1. Client 启动 Server 子进程。
  2. 双方完成 MCP initialize 和能力协商。
  3. Client 和 Server 通过标准流持续交换消息。
  4. Client 关闭输入流或终止子进程,结束本次连接。

如果 Server 进程意外退出,stdio 会话也随之结束。Client 即使重新启动相同命令,也需要重新完成 initialize,不能把新进程当作旧会话直接继续使用。

stdio 的优点是部署简单、没有端口暴露,也不需要处理 HTTP 路由、跨域或网络认证。它适合桌面应用、IDE、命令行工具和本机单用户场景。它的限制是 Client 和 Server 必须运行在同一台机器上,而且子进程会继承当前操作系统用户能够访问的文件、环境变量和网络权限。因此,本地进程仍然需要最小权限控制,不能因为没有监听端口就把任意 Server 当作可信程序。

8.2 HTTP+SSE 传输

HTTP+SSE 定义网络传输。它在后续规范中已经被标记为废弃,但理解它有助于维护旧项目,也能看清 Streamable HTTP 为什么改变了端点设计。

SSE 即 Server-Sent Events,是服务器通过一个长期 HTTP 连接持续向客户端发送事件的机制。SSE 本身只有 Server → Client 方向,所以旧版 MCP 需要两个端点共同组成双向通信:

  1. SSE 端点:Client 使用 HTTP GET 建立长连接,用来接收 Server 消息。
  2. 消息端点:Client 使用 HTTP POST 向 Server 发送消息。

建立连接时,Client 首先向 Server 的 SSE 端点发送 GET 请求,例如 GET /sse。Server 保持这个 HTTP 连接不关闭,并将响应类型设置为 text/event-stream,后续通过这条长连接持续向 Client 推送事件。

SSE 连接建立后,Server 首先发送一个类型为 endpoint 的事件。该事件的 data 中包含 Client 发送消息时应使用的 HTTP POST 地址,例如 /messages?session_id=...。这个地址可能携带用于关联当前 SSE 连接的会话参数,因此 Client 必须使用 Server 返回的地址,不能自行拼接。

获得消息地址后,Client 向该地址发送 HTTP POST 请求,并在请求体中放入 JSON-RPC 消息。第一次发送的通常是 initialize 请求,用于协商协议版本和双方支持的能力。

Server 接收并处理 POST 请求后,不通过该 POST 请求的 HTTP 响应体返回 MCP 结果,而是将 JSON-RPC 响应封装成类型为 message 的 SSE 事件,再通过之前建立的 SSE 长连接推送给 Client。后续请求、响应和通知也沿用相同模式:Client 通过 POST 发送消息,Server 通过 SSE 连接向 Client 发送消息。

Client 连接 SSE 端点后,Server 首先发送一个 endpoint 事件。该事件的 data 包含 Client 后续发送消息时应使用的 URI。Client 不应该自行猜测 POST 地址,也不应该把 SSE URL 直接当成消息地址。之后,Client 的每条 JSON-RPC 消息通过 POST 发送;Server 发给 Client 的 JSON-RPC 消息则编码在 SSE message 事件的 data 中。

这种设计允许一个独立 Server 同时服务多个 Client,也可以通过网络部署。但是,两个端点带来了额外的连接关联和运维负担:

  • Server 需要知道某个 POST 请求属于哪条 SSE 连接。
  • 网关和反向代理必须允许 SSE 长连接,并避免缓冲事件流。
  • 负载均衡时需要正确处理会话状态,否则 POST 可能到达无法识别对应 SSE 连接的实例。
  • 网络空闲超时可能断开 SSE,Client 和 Server 都需要处理重连及资源清理。

旧 HTTP+SSE 与 Streamable HTTP 都可能使用 SSE,但它们不是同一种传输。判断旧版传输的关键不是“是否看到了 SSE”,而是是否存在独立 SSE 端点,并由 endpoint 事件告诉 Client 另一个 POST 消息地址。

新项目不应该主动选择旧 HTTP+SSE。只有需要兼容旧版 Client、旧版 Server 或尚未升级的 SDK 时才使用它。兼容型 Client 通常先尝试向用户提供的 URL 发送 Streamable HTTP initialize;如果收到 400、404 或 405,再使用 GET 尝试建立旧 SSE 连接,并等待 endpoint 事件。

8.3 Streamable HTTP 传输

Streamable HTTP 从 MCP 2025-03-26 版本开始取代旧 HTTP+SSE,是当前用于网络部署的标准传输。Server 作为独立进程运行,可以同时处理多个 Client 连接。与旧方案最大的结构差异是:它只公开一个 MCP 端点,例如:

http://127.0.0.1:18100/mcp

8.3.1 Client 使用 POST 发送消息

Client 发给 Server 的每一条 JSON-RPC 消息都使用一次新的 HTTP POST 请求。以 initialize 为例,请求形态类似:

POST /mcp HTTP/1.1
Content-Type: application/json
Accept: application/json, text/event-stream

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{...}}

Accept 同时声明 application/jsontext/event-stream,因为 Server 可以根据当前请求选择两种返回方式:

  • 返回 Content-Type: application/json,响应体中直接包含一个 JSON-RPC 响应。
  • 返回 Content-Type: text/event-stream,为这次 POST 打开 SSE 流。Server 可以先发送与当前请求相关的通知或请求,最终再发送对应的 JSON-RPC 响应,然后结束该流。

如果 Client 发送的是 JSON-RPC 通知或响应,而不是需要 Server 回答的请求,Server 接受后通常返回 202 Accepted,响应体为空。HTTP 状态码表示传输层是否接收成功,JSON-RPC result 或 error 才表示协议方法的执行结果,排查问题时不应该混淆这两层错误。

如果 POST 返回 SSE,网络断开不代表 Client 已经取消原请求。明确取消应该发送 MCP 的取消通知。否则 Server 可能仍在继续执行耗时 Tool。

8.3.2 Client 可以使用 GET 接收 Server 主动消息

Client 可以向同一个 MCP 端点发送 GET,并声明:

GET /mcp HTTP/1.1
Accept: text/event-stream

如果 Server 支持独立的服务端消息流,就返回 Content-Type: text/event-stream,并通过该连接发送与某个正在执行的 POST 无直接关系的请求或通知。如果 Server 不提供这种能力,应返回 405 Method Not Allowed

因此,GET SSE 是可选能力,不是每个 Streamable HTTP Server 都必须长期维持一条 SSE 连接。最简单的无状态 Server 可以只通过 POST 接收消息,并直接返回 JSON。需要进度通知、Server 主动请求或流式结果时,再使用 SSE。

这也是 Streamable HTTP 名称中“Streamable”的含义:它可以流式传输,但不强制所有响应都使用流。它不是 WebSocket,每条 Client → Server 消息仍然是独立的 HTTP POST。

8.3.3 会话管理

Streamable HTTP 同时支持无状态和有状态 Server。需要保存会话状态时,Server 可以在 initialize 响应中返回:

MCP-Session-Id: <session-id>

Session ID 应当不可预测并且全局唯一。Client 收到后,必须在这个会话的后续 POST、GET 和 DELETE 请求中继续携带该 Header。Server 如果要求会话 ID,而后续请求没有携带,可以返回 400 Bad Request

Server 结束或找不到该会话时,对携带旧 Session ID 的请求返回 404 Not Found。Client 收到这种响应后,应重新发送不带旧 Session ID 的 initialize,建立新会话,不能只重试原业务请求。

Client 不再需要会话时,可以向同一 MCP 端点发送 DELETE,并携带 Session ID,请求 Server 释放资源。Server 如果不允许 Client 主动终止会话,可以返回 405 Method Not Allowed

8.3.4 协议版本与断线恢复

完成 initialize 后,Client 的后续 HTTP 请求应该携带协商出的协议版本:

MCP-Protocol-Version: 2025-11-25

这使 Server 能够按照双方协商的版本解析请求。版本值无效或不受支持时,Server 应返回 400 Bad Request

使用 SSE 时,Server 可以为事件设置唯一 ID。连接中断后,Client 可以通过 GET 重新连接,并使用 Last-Event-ID 告诉 Server 自己最后收到的位置。支持恢复的 Server 可以从这个位置继续投递遗漏消息。断线恢复是可选能力,Client 不能假设所有 Server 都会保存和重放事件。

一个 Client 也可能同时打开多条 SSE 流。Server 对一条 JSON-RPC 消息只能选择其中一条流发送,不能把同一条消息广播到多个流,否则 Client 会重复处理。

8.3.5 安全与适用场景

Streamable HTTP 适合远程 MCP Server、多用户服务、容器部署和需要独立扩缩容的场景。相对于 stdio,它需要承担完整的网络安全责任:

  • 校验 Origin,防止网页通过 DNS Rebinding 访问本机 MCP Server;Origin 无效时返回 403 Forbidden
  • 本机开发服务优先绑定 127.0.0.1,不要默认监听 0.0.0.0
  • 公网服务使用 TLS、认证和授权,并限制每个身份可以发现和调用的能力。
  • 把 Session ID 当作敏感凭据保护,防止会话劫持。
  • 为 HTTP 请求和 SSE 连接设置合理的超时、并发和消息大小限制。

8.4 HTTP+SSE 与 Streamable HTTP 对比

HTTP+SSE 和 Streamable HTTP 都使用 HTTP,也都可能出现 SSE 事件流,但两者的通信模型并不相同。对比如下

对比项 HTTP+SSE Streamable HTTP
端点模型 必须提供两个端点:GET 建立 SSE 连接,POST 发送消息 只提供一个 MCP 端点,同时处理 POST、可选的 GET 和会话终止 DELETE
Client → Server Client 向 endpoint 事件返回的地址发送 POST 每条 JSON-RPC 消息都向同一个 MCP 端点发送新的 POST
Server → Client 所有消息都通过预先建立的 SSE 长连接发送 可以在 POST 中直接返回 JSON,也可以在 POST 响应或可选 GET 中使用 SSE
长连接要求 必须为每个活跃 Client 维护 SSE 连接 不强制长期连接;简单 Server 可以只用 POST,需要流式传输时再使用 SSE
会话关联 POST 地址需要与对应 SSE 连接关联,旧实现常把会话标识放在消息 URI 中 既可以完全无状态,也可以在有状态模式下使用 MCP-Session-Id Header
扩缩容 SSE 连接与 POST 请求需要被路由到能够识别同一会话的实例 无状态模式容易按请求扩缩容;有状态或 SSE 模式仍需共享状态、会话路由或断线恢复机制
断线恢复 SSE 断开后需要重新连接,并重新处理连接与 POST 端点的关联 可以为 SSE 事件设置 ID,并通过 Last-Event-ID 恢复和重放遗漏消息;该能力是可选的
网关与代理 始终要求代理支持 SSE 长连接、关闭响应缓冲并正确设置空闲超时 仅使用 JSON 响应时更接近普通 HTTP API;启用 SSE 后仍然需要处理缓冲和超时
适用场景 维护旧版 Client、Server 或 SDK 新建远程服务、多用户服务、容器和 Serverless 部署

相较于旧 HTTP+SSE,Streamable HTTP 的改进可以归纳为五点:

  1. 通信模型更简单:旧传输需要先建立 SSE 连接,再从 endpoint 事件中取得另一个 POST 地址;Streamable HTTP 将发送和接收能力收敛到同一个 MCP 端点,减少了路由与连接关联逻辑。
  2. 同时支持无状态和有状态服务:不需要跨请求保存状态时,Server 可以不创建 Session ID,每次 POST 独立处理;需要连续会话时,再通过 MCP-Session-Id Header 关联请求。无状态不是强制要求,而是新的可选部署方式。
  3. 更容易扩缩容:纯 POST、直接返回 JSON 的无状态模式不必为每个 Client 保留常驻连接,适合负载均衡、容器自动扩容和短生命周期的 Serverless 实例。不过,只要业务启用了会话或 SSE,仍然需要相应的状态存储和连接治理。
  4. 错误处理与恢复路径更清晰:HTTP 状态码可以表达传输层结果,JSON-RPC error 表达协议或业务执行结果;使用 SSE 时,还可以通过事件 ID 和 Last-Event-ID 实现可选的断点续传,降低网络闪断造成的消息丢失风险。
  5. 更适合企业网络环境:仅使用 POST 和 JSON 响应时,大多数网关、鉴权组件、日志系统和可观测平台都能按照普通 HTTP 请求处理。需要流式输出时仍可切换到 SSE,但此时代理缓冲、连接超时和并发上限等配置依然不能省略。

因此,Streamable HTTP 的核心优势不是“彻底取消 SSE”,而是把 SSE 从旧协议中的必需长连接,变成按需启用的流式能力。简单请求可以使用短连接完成,只有在进度通知、流式结果或 Server 主动消息等场景下才建立事件流。

综上,传输方式可以按照部署边界选择:

  • Server 只服务于同一台机器上的一个 Host,优先选择 stdio。
  • Server 需要被远程或多个 Client 访问,优先选择 Streamable HTTP。
  • 只有为了版本兼容时,才使用旧 HTTP+SSE。

下图只比较当前规范定义的两种标准传输。它们承载相同的 JSON-RPC 和生命周期,差别在于进程关系、消息边界、连接方式和会话管理。

stdio 与 Streamable HTTP 标准传输对比


文章作者: hnbian
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 hnbian !
评论
  目录