ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

MCP Streamable HTTP 传输的 SSE 轮询机制:SEP-1699 服务端主动断开(Server-Side Disconnect)规范解读

MCP Streamable HTTP 传输的 SSE 轮询机制:SEP-1699 服务端主动断开(Server-Side Disconnect)规范解读 人工智能AI Agent工具调用【免费下载链接】specificationSpecification and documentation for the Model Context Protocol项目地址https://gitcode.com/gh_mirrors/specification2/specification点击查看免费下载导读SEP-1699Status: FinalStandards Track作者 Jonathan Hefner创建于 2025-10-22针对 MCP 的 Streamable HTTP 传输提出了一组连接语义变更核心是允许服务端在已向客户端发送 SSE 事件 ID 之后随时主动断开连接由客户端依照 SSE 标准携带Last-Event-ID轮询重连从而缓解长连接占用与流可恢复性resumability问题。读完本文你将掌握 SEP-1699 定义的 MUST/MAY/SHOULD 规则、SSE 的id/data/retry字段语义、该设计在 2025-11-25 修订版中的具体落地条款以及 2026-07-28 修订版对轮询与恢复机制的后续调整。背景与动机长连接之痛SEP-1699 的出发点非常直接在当时的 Streamable HTTP 传输规范中服务端不允许在计算一个结果的过程中关闭连接。也就是说除非客户端主动断开服务端必须一直维持可能持续很久的连接原文称 barring client-side disconnection, servers must maintain potentially long-running connections。这种只能由客户端断开的不对称设计带来三类问题资源占用服务端必须为每个未完成的请求挂起一条 HTTP 连接请求量大时连接数会失控容易触发代理、负载均衡器或操作系统的空闲/超时策略恢复困难一旦网络抖动导致连接中断客户端无法区分服务端还在算与连接已死更无法从断点续传尚未送达的 JSON-RPC 响应实现负担服务端被迫对每条请求做长连接保活keep-alive增加了中间层反向代理等的配置复杂度。SEP-1699 的解决方案是把断开从服务端的禁区变成一种受控的轮询信号——服务端先给出一个事件 ID之后想断就断客户端把断开当作网络故障处理并携带该 ID 重连从而把长连接转化为可恢复的短连接轮询。核心规范变更先发事件 ID再随时断开SEP-1699 对 Streamable HTTP 传输规范做了三处关键改动全部围绕 SSEServer-Sent Events标准语义展开。改动一启动 SSE 流时必须立即发送带id的空事件MUSTWhen a server starts an SSE stream, itMUSTimmediately send an SSE event consisting of anidand an emptydatastring in order to prime the client to reconnect with that event ID as theLast-Event-ID.即服务端一旦开始 SSE 流必须立刻发送一个形如id: 事件ID 空data的事件。这个事件的唯一作用是预置prime重连游标——让客户端记住该事件 ID以便将来断开后用它作为Last-Event-ID重连。改动二发出事件 ID 后服务端可随时断开SHOULD NOT → MAY原规范条款The serverSHOULD NOTclose the SSE stream before sending the JSON-RPCresponsefor the received JSON-RPCrequest被修改为The serverMAYclose the connection before sending the JSON-RPCresponseif it has sent an SSE event with an event ID to the client注意这里是从SHOULD NOT强烈禁止放宽为MAY允许但附带前置条件必须先发送过带事件 ID 的 SSE 事件。换句话说事件 ID 是服务端断开的许可证——先给客户端一个恢复点然后才允许断开。改动三用retry字段约束重连节奏SHOULD MUSTIn order to prevent clients from reconnecting / polling excessively, the serverSHOULDsend an SSE event with aretryfield indicating how long the client should wait before reconnecting. ClientsMUSTrespect theretryfield.服务端断开前应当发送带retry字段的 SSE 事件告知客户端等待多少毫秒再重连客户端必须遵守该值防止对服务端造成狂轰滥炸式的过度轮询。关于空data的标准语义SEP-1699 特别强调SSE 标准明确允许data为空字符串且此时客户端正确的处理方式是一边记录id用于Last-Event-ID一边忽略该事件本身即不调用事件处理器回调。这是因为在 WHATWG HTML 标准的 SSE 事件流解析算法中空data缓冲区的事件在派发dispatch阶段会被直接丢弃但id字段在解析阶段就已写入最后事件 ID 缓冲区两者互不干扰。SSE 标准语义详解id、data、retry与Last-Event-IDSEP-1699 的设计完全建立在 SSEServer-Sent EventsWHATWG HTML 标准之上理解下列字段语义是读懂本 SEP 的前提SSE 字段/机制语义在 SEP-1699 中的作用id: value将最后事件 ID 缓冲区设为该值客户端重连时作为Last-Event-ID头发送构成恢复游标data:空数据缓冲区为空字符串事件被记录 ID 后忽略、不派发回调用于预置游标而不会干扰业务事件retry: ms设置客户端重连等待时间仅接受 ASCII 数字否则忽略防止客户端断开后立即、高频重连Last-Event-ID请求头客户端重连时回传它最后收到的事件 ID服务端据此判断客户端已消费到哪个事件可做断点续传在 2025-11-25 修订版规范中这些机制被进一步明确事件 ID 在同一会话session内的所有流中必须全局唯一且事件 ID应当编码足够的流身份信息使服务端能把Last-Event-ID关联回正确的流无论原始流是通过 POST 还是 GET 建立的恢复resumption一律通过 HTTP GET 携带Last-Event-ID进行。相关条款见 2025-11-25 Streamable HTTP 传输规范。协议落地2025-11-25 修订版中的实现细节SEP-1699 被接受后进入协议在 2025-11-25 修订版的 Streamable HTTP 传输规范中体现为一系列可执行条款见 transports.mdx服务端开启 SSE 流后应当立即发送一个事件 ID 空data事件预置客户端重连第 106-108 行连接 vs 流服务端在已发送事件 ID 后可以随时关闭连接而不终止SSE 流第 109-111 行——这是 SEP-1699 引入的关键概念区分流是逻辑实体连接是承载它的物理通道轮询行为连接被服务端关闭后客户端应当通过尝试重连来轮询该 SSE 流第 112 行retry约束服务端在关闭连接前应当发送带retry字段的事件客户端必须尊重该字段、等待指定毫秒数后再重连第 113-116 行断开不等于取消任何时刻的断开含网络原因都不应被解读为客户端取消请求客户端要取消必须显式发送CancelledNotification第 126-129 行可恢复性为避免断开导致消息丢失服务端可以使流可恢复resumable通过Last-Event-ID重放断点之后的消息第 130-131 行及 Resumability and Redelivery 一节。规范的变更日志也明确记录了这两笔账2025-11-25 变更日志 第 6 条写明支持 SSE 流轮询允许服务端随时断开SEP-1699第 7 条进一步澄清 SEP-1699 的细节——GET 流同样支持轮询、恢复一律走 GET、事件 ID 应编码流身份、断开包括服务端主动关闭对应 Issue #1847。这印证了 SEP-1699 落地时并非简单放宽限制而是连同恢复语义一起设计。另外值得注意SEP-1699 原文在 Additional Information 中注明它部分取代了 SEP-1335该 SEP 提出了相关的早期方案。这也是理解其历史脉络的一条线索——轮询式 SSE 设计并非一蹴而就。兼容性分析新旧组合矩阵SEP-1699 自带完整的向后兼容性分析组合矩阵如下组合影响结论新客户端 旧服务端无变化无向后不兼容旧客户端 新服务端客户端应把服务端随时断开视为网络故障retry字段本就属于 SSE 标准只要客户端已实现正确的 SSE 恢复逻辑即无向后不兼容核心论断是retry字段与断开即网络故障的解读都来自 SSE 标准本身因此一个符合 SSE 标准的旧客户端天然能与启用新行为的新服务端协作——这保证了协议演进的安全性。演进2026-07-28 修订版的变化需要特别说明的是SEP-1699 的轮询/恢复设计主要作用于协议版本 2025-03-26 至 2025-11-25 的 Streamable HTTP。在 draft对应 2026-07-28修订版 中传输层发生了结构性调整移除 GET 流端点客户端不再通过 HTTP GET 打开独立 SSE 流移除协议级 session不再有MCP-Session-Id与 HTTP DELETE 终止会话的机制Last-Event-ID恢复不再支持规范明确写着 Resumable SSE streams viaLast-Event-IDare not supported服务端应忽略Last-Event-ID请求头断开的语义反转新规范规定关闭 SSE 响应流必须被服务端视为该请求的取消cancellation——这与 2025-11-25 版本断开不等于取消、需显式发送 CancelledNotification的语义正好相反。也就是说在最新修订中服务端边算边断、客户端轮询续传的模式被每条请求独立 POST、响应流即生命周期的模型取代长生命周期变更通知改由subscriptions/listen的专用流承载服务端对客户端交互sampling、elicitation、roots则通过 MRTRMulti Round-Trip RequestsSEP-2322内嵌到结果中。因此阅读 SEP-1699 时务必结合协议版本语境它的价值在 2025-11-25 及之前的实现中体现得最完整而新修订通过另一种方式解决了长连接问题。面向实现者的实践建议结合 SEP-1699 原文与 2025-11-25 规范的条款给实现者梳理可落地的行为清单。服务端Server要点开启 SSE 流后立即发送首个事件id: stream-1-event-0 data:其中id在同一会话的所有流中保持全局唯一并编码流身份信息便于服务端把后续的Last-Event-ID关联回正确的流。计算耗时可能很长时可以主动断开连接释放通道但必须在断开前发送带retry字段的事件例如retry: 5000毫秒指导客户端等待 5 秒再重连。保留流的逻辑状态在客户端携带Last-Event-ID重连时从断点之后的消息开始重放且不得重放本应投递到其他流上的消息。断开 ≠ 取消在 2025-11-25 语义下服务端不应把客户端重连当作取消只有显式的CancelledNotification才是取消信号。客户端Client要点收到空data事件时记录其id为最后事件 ID但不触发任何事件处理器回调SEP-1699 特别强调的标准行为。服务端断开后按网络故障处理并尝试重连重连请求携带Last-Event-ID头2025-11-25 版本中恢复一律走 HTTP GET。必须尊重retry字段按指定毫秒数等待后再重连避免对服务端形成重连风暴。一次完整的轮询时序示例--- 第一次 POST服务端返回 SSE 流 --- HTTP/1.1 200 OK Content-Type: text/event-stream id: stream-1-event-0 data: retry: 5000 服务端断开连接计算仍在后台进行 --- 客户端等待 5 秒后轮询重连 --- GET /mcp HTTP/1.1 Accept: text/event-stream Last-Event-ID: stream-1-event-0参考依据SEP-1699 原始提案本文章的直接依据Abstract / Motivation / Specification / Rationale / Backward Compatibility / Additional InformationSEP-1699 站点渲染版Mintlify 渲染后的同文档案2025-11-25 Streamable HTTP 传输规范SEP-1699 的落地条款轮询、retry、Resumability and Redelivery、会话管理2025-11-25 修订版变更日志SEP-1699 及澄清 Issue #1847 的官方记录draft2026-07-28Streamable HTTP 传输规范展示后续修订对 GET 流、Last-Event-ID恢复与取消语义的调整。赞分享人工智能AI Agent工具调用【免费下载链接】specificationSpecification and documentation for the Model Context Protocol项目地址https://gitcode.com/gh_mirrors/specification2/specification点击查看免费下载相关推荐TypeScript SDK 实战基于 SEP-1699 的 SSE 服务端主动断开与 Last-Event-ID 重连恢复机制TypeScript SDK 实战基于 SEP 1699 的 SSE 服务端主动断开与 Last Event ID 重连恢复机制 导读 在 typescrip人工智能MCP 服务MCP Clients用 python-sdk 实现 SSE Polling服务器主动关闭流的长任务轮询模式实战SEP-1699用 python sdk 实现 SSE Polling服务器主动关闭流的长任务轮询模式实战SEP 1699 本文以仓库中的官方示例 examples/se人工智能MCP 服务MCP ClientsMCP传输协议详解Stdio、SSE与Streamable HTTPMCP传输协议详解Stdio、SSE与Streamable HTTP 本文深入解析Model Context Protocol MCP 的三种核心传输机制标人工智能MCP 服务MCP Clients上一篇5步掌握Zephyr RTOSwest构建系统终极指南下一篇symfony/debug职位空缺核心开发工程师招聘创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表