MCP 2026-07-28 无状态核心之后:身份、任务、幂等与审计状态到底放在哪里?

📅 2026/7/31 0:00:14 👁️ 阅读次数 📝 编程学习
MCP 2026-07-28 无状态核心之后:身份、任务、幂等与审计状态到底放在哪里?

MCP 无状态核心之后:身份、任务、幂等与审计状态到底放在哪里

发布边界:规范事实按 MCP 2026-07-28 稳定版核验;operation_id、operation ledger、outcome_unknown 与审计字段属于作者架构设计,Tasks 是可选扩展,发布前复核勘误和目标 SDK 支持。

摘要

MCP 2026-07-28 删除协议级 Session 和初始化握手,把核心改为自包含请求与逐请求能力协商。但业务状态并没有消失:身份、任务、幂等、副作用结果、缓存、订阅和审计必须迁移到显式承载位置。本文给出七类标识符、outcome_unknown 对账状态、MRTR/Tasks/业务 Handle 边界和迁移验收清单。

关键词

MCP 2026-07-28、Stateless、Idempotency、Tasks、Audit

目录

  • 一次响应丢失,为什么会创建两个发布
  • 协议真正删除的,是连接历史依赖
  • 旧 Session 的隐含职责,必须拆到不同承载位置
  • 先把七类标识符分开,否则所有重试都会变得危险
  • 重复副作用必须进入outcome_unknown,不能把超时当失败
  • MRTR、Tasks 与业务 handle 是三条不同的生命周期
  • 身份必须逐请求证明,OAuth/OIDC 不能被简化成 SDK 开关
  • 路由、缓存与订阅:基础设施可见,不代表基础设施拥有业务真相
  • Trace 负责关联,审计负责证明
  • 六类组件的迁移清单
  • 发布前兼容性验收矩阵
  • 弃用不等于立刻删除,但新设计不要继续加债
  • 最终判断:不再依赖连接,只是第一步

MCP2026-07-28已移除协议 Session 与旧式初始化握手。它让请求更容易被普通 HTTP 基础设施路由,却不会替应用消灭状态、授权风险或重复副作用。

一次响应丢失,为什么会创建两个发布

某个远程 MCP Server 暴露了create_release工具。客户端经负载均衡把请求交给实例 A。A 已在代码托管平台创建 Release,又触发了部署流水线;但最终结果返回前,SSE 响应流被中断。

在 MCP2026-07-28中,响应流不支持Last-Event-ID恢复。断开的在途调用已经丢失,客户端只能重新发起一个独立请求,而且必须使用新的 JSON-RPC request ID。第二次请求落到实例 B。B 没有 A 的进程内信息,也不存在可供恢复的Mcp-Session-Id。如果工具的实现逻辑仍是“每收到一次调用就执行一次”,系统便会再次创建 Release、重复触发流水线,甚至重复扣费或发送通知。[S03][S06]

问题不在负载均衡,也不在“无状态”本身。真正的问题是:旧系统曾把“同一次业务尝试”“当前用户是谁”“任务执行到哪一步”“前一次是否已经产生外部副作用”混装进连接、Session 或某个实例内存。协议把这个隐式容器移除后,业务合同没有自动补齐。

因此,MCP2026-07-28的核心工程结论不是“Server 从此没有状态”,而是:

协议层无状态不等于应用层无状态。协议核心变薄后,身份、业务对象、长任务、幂等对账、多轮交互和审计状态必须分别拥有显式标识、所有者、生命周期、授权规则与恢复语义。

本文用【规范事实】标注稳定规范直接要求,用【作者设计】标注可落地但并非 MCP 强制的工程方案。

协议真正删除的,是连接历史依赖

【规范事实】稳定版2026-07-28删除了initialize/notifications/initialized握手、协议级 Session 与Mcp-Session-Id。每个请求都必须自描述:请求_meta必须携带io.modelcontextprotocol/protocolVersionio.modelcontextprotocol/clientCapabilities;客户端还应携带io.modelcontextprotocol/clientInfo,服务端结果应携带io.modelcontextprotocol/serverInfo。后两者是自报的实现信息,不能作为安全身份。所有成功结果必须携带resultType;为兼容旧版本,Client 只在旧结果缺失该字段时将其解释为"complete"。[S02][S03][^S04]

Server 必须实现server/discover,返回支持的协议版本、能力和实现信息;Client 可以预先调用,也可以直接调用其他 RPC 并处理版本错误。协议不再进行连接级版本协商,同一条连接甚至同一个 stdio 进程都不能被解释为会话边界。[S04][S05][^S08]

Streamable HTTP 也变成单端点、逐消息 POST 的请求/响应模型。每个 POST 必须携带MCP-Protocol-Version,其值必须与正文_meta一致;所有请求必须携带Mcp-Methodtools/callresources/readprompts/get还必须携带Mcp-Name。Header 名比较不区分大小写,但方法名等 Header 值区分大小写。缺失、畸形或与正文不一致时,Server 返回 HTTP 400 与HeaderMismatch,稳定错误码是-32020。[^S06]

工具 schema 可以用x-mcp-header指定需要镜像为Mcp-Param-{Name}的参数。Server 使用该注解是可选的,但 Streamable HTTP Client 必须支持合法注解并生成 Header。注解只允许落在从 schema 根沿properties静态可达的stringintegerboolean参数上,number、数组路径、组合关键字或$ref路径不合法;Client 必须把含非法注解的工具排除出tools/list。参数缺失或值为null时必须省略 Header。非安全 ASCII 值使用精确、区分大小写的=?base64?{Base64EncodedValue}?=哨兵格式,Mcp-Name同样适用。任何处理正文的 Server 都必须解码后校验 Header 与正文一致;网关若基于 Header 做路由、限流或租户策略,也不能盲信来自旧版本或未经一致性校验的 Header。[S06][S07]

旧式 GET 事件流、DELETE Session、Mcp-Session-IdLast-Event-ID均不属于本版本。只支持新版本的 Server 对 MCP 端点上的 GET/DELETE 应返回 405;收到旧 Session Header 或Last-Event-ID时忽略,不创建、不回显,也不恢复事件。[S03][S06]

这些变化消除的是“必须先在同一连接上发生过什么”的协议状态。它们没有删除数据库中的购物车、外部平台上的 Release、正在运行的作业、授权策略或审计证据。

旧 Session 的隐含职责,必须拆到不同承载位置

下面这张表不是把 Session 换成一个新字段,而是把过去混在一起的职责重新归类。

旧 Session 中常见的隐含职责新的显式承载位置客户端携带什么权威状态在哪里关键边界
协议版本、客户端能力每请求_meta;预发现用server/discoverprotocolVersion、clientCapabilities当前请求与 Server 实现不从连接历史推断
客户端实现名称与版本每请求clientInfo;结果serverInfo实现元数据当前消息只用于显示、日志、兼容分析,不是认证身份
用户、租户、scope每请求认证与授权上下文HTTP Bearer token;stdio 环境凭证IdP、Authorization Server、策略引擎每次调用重新验证;不能从 handle 推断
连接内变化的工具/资源/提示列表按当前授权与时间计算;TTL 缓存;变更通知当前认证、查询参数Server 配置与领域权限可按授权变化,不可按连接或连接副作用变化
购物车、浏览器、沙箱、数据库上下文普通工具参数中的业务 handlebasket_idbrowser_id业务数据库或资源系统handle 不是 MCP 协议对象,也不是授权凭证
长时间执行与中途输入Tasks 扩展taskId持久 Task Store / 下游作业系统断线可查询;每次 get/update/cancel 鉴权
一次逻辑请求缺少输入MRTRinputResponses、原样requestState自包含受保护状态或短期恢复记录重试原方法;新 JSON-RPC ID;不是 Task
订阅与变更通知subscriptions/listen请求过滤条件;listen 请求 ID当前长响应流断线后重新 listen,不提供 replay
重复调用与未知执行结果工具级 operation ledger普通业务参数operation_id幂等/对账存储MCP 不定义通用幂等键,也不保证 Exactly Once
链路诊断与事后追责OpenTelemetry + 持久审计账本Trace Context;业务关联 IDTelemetry 后端与审计存储Trace 可采样,不能替代审计

显式 handle 是这里最容易被误解的一项。【规范事实】跨调用状态可以由 Server 创建普通字符串 ID,再由后续工具作为普通参数传回;协议没有handles/*方法,也没有通用 handle schema。列表也不能因“之前在这条连接上调用过某个工具”而改变,但可以因当前请求的授权或时间而改变。[^S12]

【作者设计】创建 handle 的工具应同时写明过期时间、可恢复方式和清理语义。Server 每次按(principal, tenant, handle)做 ACL 校验。对于无认证场景,handle 不可避免地接近 bearer token,应使用足够熵并缩短有效期;对于有认证场景,ID 再随机也不能替代权限检查。

先把七类标识符分开,否则所有重试都会变得危险

标识符正确用途生命周期重试时是否保持不能承担的职责
JSON-RPC request ID关联一个在途请求与响应单次请求否;新请求使用新 ID业务去重、审计主键、Task 恢复
Trace ID关联分布式执行路径一次或多次链路传播可按追踪策略变化幂等、授权、不可变审计证据
operation_id标识同一次业务尝试由工具合同定义这是作者设计的普通工具参数,不是 MCP 标准字段
taskId寻址一个持久异步执行分钟到天或更久查询同一任务时保持业务对象 ID、持有即授权
业务 handle寻址购物车、浏览器、沙箱等领域状态由领域定义操作同一对象时保持Task 状态、协议 Session、身份
requestState恢复一次 MRTR 逻辑调用的临时上下文通常秒到分钟原样回传通用 workflow ID、长期任务、幂等键
subscription ID标记一次subscriptions/listen流上的通知当前 listen 请求重连后改变事件 replay、业务会话

【规范事实】JSON-RPC request ID 只要求不与发送方尚未收到响应的请求冲突。MRTR 初始请求与重试必须使用不同 ID,SSE 断线后的重新调用也必须使用新 ID。[S03][S04][^S11]

【作者设计】有副作用的工具应额外定义稳定的operation_id。它代表“用户意图中的同一次业务尝试”,而不是网络请求。这个字段应进入工具 schema、日志和审计,但不能伪装成 MCP 的通用Idempotency-Key

重复副作用必须进入outcome_unknown,不能把超时当失败

继续使用create_release。客户端第一次调用:

{"name":"create_release","arguments":{"repository":"org/app","commit":"abc123","operation_id":"op_01K_RELEASE_7F2"}}

【作者设计】Server 以(principal_id, tool_name, operation_id)作为去重键,并保存规范化参数指纹。相同 key、相同参数可以复用进度或结果;相同 key、不同参数必须拒绝为冲突。推荐状态机如下:

RECEIVED └─校验身份、授权、参数指纹成功→ CLAIMED └─开始外部副作用→ EXECUTING ├─明确成功并持久化结果→ SUCCEEDED ├─明确未产生副作用→ FAILED_SAFE_TO_RETRY └─请求已发出但结果无法证明→ OUTCOME_UNKNOWN OUTCOME_UNKNOWN └─查询外部系统、业务唯一键、回调或流水线记录→ RECONCILING ├─发现目标副作用且参数一致→ SUCCEEDED ├─能够证明副作用未发生→ FAILED_SAFE_TO_RETRY └─证据冲突或无法判定→ MANUAL_REVIEW FAILED_SAFE_TO_RETRY └─使用同一 operation_id 重新抢占→ CLAIMED

关键点是OUTCOME_UNKNOWN不是普通失败。实例 A 向外部平台发送创建请求后超时,本地无法断言“没有创建”。实例 B 收到重试时,应先读取 operation ledger,再按仓库、commit、外部幂等键或预先设置的领域唯一约束对账。只有证明原副作用未发生,才允许重放。发现已经创建则复用原结果;证据不足则转人工或补偿流程。

如果外部服务原生支持幂等键,应优先把同一个operation_id传给它;如果支持按领域唯一键查询,应保存该键和下游请求 ID。单纯使用数据库唯一约束只能防止本地重复记录,不能自动消除已经发生在外部系统中的副作用。

MCP 本身不承诺 Exactly Once。RFC 9110 也不允许代理随意自动重试非幂等请求,除非已知业务语义可重放,或能够证明前一次请求没有生效。[^S18] 可实现的是一组可验证的较弱保证:同一主体与参数下复用结果;未知结果先对账;明确失败才重试;冲突进入人工处理。

更简单的替代方案也应保留。纯查询工具通常不需要 operation ledger;长耗时且天然可查询的动作可以直接返回 Task;外部平台已提供成熟幂等键时,不必再造第二套执行协调器;黏性会话可以作为迁移期降险手段,但不能成为正确性的唯一前提。

MRTR、Tasks 与业务 handle 是三条不同的生命周期

MRTR:同一次逻辑调用还缺少输入

【规范事实】当tools/callresources/readprompts/get还需要 elicitation、sampling 或 roots 输入时,Server 返回resultType: "input_required"。结果必须包含inputRequestsrequestState中至少一个。Client 完成输入后,以新的 JSON-RPC request ID 重试原方法,携带inputResponses,并在存在时原样回传requestState。[S03][S11]

requestState通过客户端往返,Server 必须把它视为攻击者可控输入。如果它影响授权、资源访问或业务逻辑,必须使用 HMAC、AEAD 或等价机制保护完整性;还应绑定当前 principal、短 TTL、原方法和关键参数摘要。密码学绑定只能限制跨用户和跨请求重放,不能自动保证一次性消费;需要 at-most-once 时仍要落 Server 侧记录。[^S11]

MRTR 重试及input_required结果不得缓存。它适合短暂补充输入,不适合承载几小时的工作流,也不应被拿来代替业务幂等键。[S09][S11]

Tasks:一个可持久寻址的长执行

【规范事实】Tasks 已从实验性核心移到官方扩展io.modelcontextprotocol/tasks,当前用于增强tools/call。Client 必须在当前请求的能力中声明该扩展,Server 才能返回resultType: "task"。不能因为客户端曾在上一个请求声明过能力,就在当前请求返回 Task。[S03][S13]

Task 包含taskId,状态可为workinginput_requiredcompletedfailedcancelled。扩展提供tasks/gettasks/updatetasks/cancel;没有tasks/list,旧的阻塞式tasks/result也被移除。经 Streamable HTTP 调用这三个 Task 方法时,Mcp-Name必须取params.taskId,供中间层路由。Task 必须在返回 handle 前完成持久创建,Client 也应持久保存taskIdtasks/cancel的空响应只表示取消意图已被接收,取消是协作式、可能最终一致,不能把 ack 解释为已经停止。[^S13]

每次tasks/get/update/cancel都必须按当前认证主体授权。taskId的持有不构成访问权。任务中的inputRequests通过tasks/get暴露、由tasks/update提交;它与“重试原方法”的 MRTR 结构相似,却是独立机制。需要在创建 Task 前补输入时,应先完成 MRTR,再返回 Task。[^S13]

业务 handle:对象存在,不等于执行仍在进行

deployment_idbasket_idbrowser_id表示领域对象或上下文;taskId表示一次执行;requestState表示一次 MRTR 重试的临时状态。一个部署对象可以由多个 Task 变更,一个 Task 也可能创建多个领域对象。把三者合成一个 ID,会导致取消、重试、TTL、所有权和审计全部失真。

身份必须逐请求证明,OAuth/OIDC 不能被简化成 SDK 开关

【规范事实】MCP Authorization 对整个协议是可选能力;使用 HTTP 且支持授权的实现应遵循该规范,stdio 则应从环境获取凭证。受保护的 MCP Server 充当 OAuth 2.1 resource server。Client 在每个 HTTP 请求中使用Authorization: Bearer ...,不得把 token 放入查询参数;Server 必须校验 token 是否面向自身资源和受众,失效或过期返回 401,权限不足返回 403。[^S14]

授权 Server 必须提供 RFC 8414 元数据或 OpenID Connect Discovery 中至少一种发现机制,Client 必须支持两者。这不等于每个 MCP 产品都必须采用“OIDC 登录”;OIDC Discovery 在这里是授权服务器元数据发现路径之一。MCP Server 必须发布 Protected Resource Metadata,Client 必须使用它定位授权 Server。[^S14]

Client 注册优先使用预注册或 Client ID Metadata Documents;Dynamic Client Registration 已弃用,只为兼容保留。使用 DCR 时,桌面、移动、CLI、localhost 类型应正确声明application_type。Client 凭证必须按 issuer 保存,不能复用于另一个授权 Server;授权响应若携带iss,Client 必须与先前记录的 issuer 做简单字符串比较,不能自行规范化后再比。[S03][S14]

【作者设计】认证中间件应为每个请求生成稳定的principal_idtenant_id、有效 scope 和策略版本。业务 handle、Task、operation ledger 与审计事件都绑定这些值,而不是绑定clientInfo、连接或 Header 中的工具名。MCP Server 调用上游服务时也不得转发客户端 token,应获取面向上游资源的独立凭证。

路由、缓存与订阅:基础设施可见,不代表基础设施拥有业务真相

【规范事实】Mcp-MethodMcp-Name与合法的Mcp-Param-*让代理在不深度解析 JSON 的情况下路由、限流和做安全策略;但任何处理正文的组件都必须验证 Header 与正文一致。HeaderMismatch的稳定错误码为-32020;缺失必需客户端能力为-32021;不支持协议版本为-32022。[S02][S03][^S06]

【规范事实】server/discovertools/listprompts/listresources/listresources/templates/listresources/readresultType: "complete"结果必须包含ttlMscacheScopettlMs是新鲜度提示,不是强制轮询周期;cacheScope: "private"只能在相同认证上下文中复用,public才可跨用户共享。缓存范围不是授权规则,命中缓存也不能跳过权限边界。分页结果逐页缓存,不保证形成一致快照。[S08][S09]

变更通知通过subscriptions/listen获取。第一次消息是确认,后续通知带io.modelcontextprotocol/subscriptionId,其值来自这次 listen 的 JSON-RPC ID。底层连接断开后,Client 重新发起 listen 并重新获取必要列表或资源;协议没有事件重放或 Session 级订阅恢复。[S03][S10]

【作者设计】反向代理可以用版本、方法、名称和镜像参数做粗粒度路由,但数据库分片、租户归属和 operation ledger 的权威判定仍应由应用层完成。Header 是可校验的索引,不是授权证明,也不是业务提交记录。

Trace 负责关联,审计负责证明

【规范事实】稳定版明确了_metatraceparenttracestatebaggage的 OpenTelemetry 传播约定。它们适合把 Host、Client、MCP Server、任务 Worker 和下游 API 串成一条可观测链路。[S03][S17]

【作者设计】审计必须独立持久化,因为 Trace 可能采样、丢弃或按短周期保留。一个可用的审计事件至少应保存:事件 ID、时间、principal/tenant、issuer/audience、有效 scope、策略版本、协议版本、客户端与 Server 版本、MCP method/name、参数指纹、operation ID、task ID、业务 handle、JSON-RPC ID、Trace ID、授权决定、重试原因、下游资源 ID、结果分类和补偿动作。

审计存储不能原样保存访问 token、密钥、敏感正文或可直接复用的 bearer handle。需要在入口做字段分级、脱敏、哈希和独立访问控制。JSON-RPC ID 用于一次请求,Trace ID 用于链路,operation ID 用于业务去重,audit event ID 用于持久证据;四者任何两个都不能互换。

六类组件的迁移清单

组件必做迁移验收证据
旧 Client每请求发送必需_meta;生成MCP-Protocol-VersionMcp-Method、适用时Mcp-Name;支持 JSON/SSE 两种响应;断流后用新 request ID;实现现代/旧时代探测;支持 MRTR;按需支持 Tasks 与x-mcp-header抓包、兼容测试、错误码断言、重试日志
Server删除对连接历史和 Session 的依赖;实现server/discover;每请求验证版本/能力;校验 Header 与正文;GET/DELETE 新端点返回 405;业务跨调用状态改显式 handle;列表不得按连接副作用变化无黏性负载均衡测试、Schema 校验、跨实例回归
SDK / 适配层明确所用版本与双时代策略;不要把 SDK 的“兼容”当成应用通过;核对 Tasks、MRTR、Header、缓存、错误码及弃用 API;锁定版本并运行 conformance 与业务回归SDK 版本清单、conformance 结果、应用级测试报告
网关 / 反向代理允许 POST JSON/SSE;保留未知Mcp-Param-*;按规范处理 Base64 sentinel;对受信路由 Header 做正文一致性校验;不自动重试有副作用 POST;正确传递 400/401/403/404/405网关集成测试、安全测试、重试策略配置
认证中间件每请求验证 token、issuer、audience、scope;输出 principal/tenant;按 issuer 隔离客户端凭证;handle/task/operation 逐次 ACL;禁止 token passthrough跨租户拒绝测试、issuer mix-up 测试、scope step-up 限次测试
状态存储把 Session 表拆成业务 handle、Task Store、operation ledger、MRTR 短期状态、认证事务和审计账本;分别定义 TTL、并发、加密、清理、恢复、所有者数据模型、迁移脚本、故障注入、清理与恢复演练

兼容旧时代时,责任不应含糊地落给“协议”。双时代 Client/Server 或 SDK 适配层必须实现明确探测与回退。现代 Server 必须实现server/discover;Client 是否调用是可选的。HTTP Client 应先发自描述的现代 POST,根据响应体是否为可识别的现代 JSON-RPC 错误判断是否修正版本或回退;stdio 双时代 Client 应以server/discover探测,识别到现代错误时不得误回退initialize。[S05][S08]

Tier 1 SDK 在稳定版发布时支持2026-07-28只是生态快照。Tier 代表维护、时效与 conformance 义务,不等于具体应用已经完成业务状态迁移,更不保证所有扩展都被采用;Tasks 等扩展也不能仅凭 SDK tier 推定可用。[S15][S20]

GitHub MCP Server 的迁移提供了一个实现案例:它删除了initialize时的 Redis Session 写入与每次调用的 Session 读取,利用标准 HTTP Header 支持日志与 secret scanning,并通过 Go SDK wrapper 兼容新旧 elicitation。[^S19] 这只能证明 GitHub 的 Session 存储主要承载了可移除的协议职责,不能外推为“所有 MCP Server 都应删除 Redis”或“只升级 Go SDK 即完成迁移”。

发布前兼容性验收矩阵

场景测试输入应有结果阻断发布的失败信号
新 Client → 新 HTTP Server完整_meta与三个适用 Header任意实例正确处理;Header 与正文一致依赖上一请求、需要黏性、缺 Header 仍放行
必需_meta缺失去掉 protocolVersion 或 clientCapabilitiesHTTP 400,JSON-RPC-32602;不得回退旧时代静默补默认值、沿用上一请求能力或错误触发 initialize
新 Client → 旧 HTTP Server先发现代 POST根据规范识别旧时代并回退,不把现代错误误判为旧 Server-32022仍回退 initialize;无限探测
旧 Client → 双时代 Serverlegacy initialize + Session 路径隔离进入 legacy 适配层;现代路径不受污染旧 Session 数据进入现代业务状态
新 stdio Client → 旧 stdio Server先发server/discover非现代响应/超时后回退 initialize只按某一个错误码判断;死锁
Header 篡改Mcp-Name与正文名称不同HTTP 400,JSON-RPC-32020网关按 Header 路由,Server按正文执行
缺少请求能力当前请求未声明 Tasks选择普通结果;若处理必须依赖 Tasks,则 HTTP 400 /-32021,不得返回 Task沿用上一请求能力或静默返回 Task
不支持版本请求未知 protocolVersionHTTP 400,-32022,列出支持版本静默按默认版本执行
SSE 在副作用后断开第二次调用使用新 request ID、同 operation ID读取 ledger;进入复用结果或OUTCOME_UNKNOWN对账再次执行副作用;把超时直接记为未执行
MRTR 重试input_required后回传 inputResponses/requestState新 JSON-RPC ID;验证主体、TTL、方法和参数摘要修改 requestState 仍接受;缓存中间结果
Task 恢复与取消进程重启后 tasks/get;再 cancelTask 可查询;cancel ack 后最终状态可核实taskId 只存在 Worker 内存;ack 即伪报 cancelled
handle 越权另一租户持有合法 handle/taskId403 或业务拒绝,不泄露对象存在性只要 ID 正确即访问成功
缓存隔离两个 token 请求 private 列表;再发变更通知不跨认证上下文复用;通知后刷新private 缓存跨租户;cacheScope 被当授权
旧式传输请求GET/DELETE、Session Header、Last-Event-ID新版专用端点 405/忽略旧 Header,不恢复流重新创建隐式 Session 或接受 replay
弃用能力现有 Roots/Sampling/Logging 用户升级仍可在弃用窗口运行,同时出现迁移路径把“弃用”误写成“立即移除”;新项目继续强依赖

弃用不等于立刻删除,但新设计不要继续加债

Roots、Sampling、Logging 在2026-07-28被标记为 Deprecated,仍处于规范中且至少十二个月后才有资格被移除;最早是首个在 2027-07-28 当日或之后发布的规范版本,实际也可能更晚。新实现不应采用,现有实现应分别迁移到工具参数/资源 URI/Server 配置、直接 LLM Provider API、stdiostderr或 OpenTelemetry。[S03][S16]

这里有一个容易混淆的细节:logging/setLevelRPC 已经被删除,但 Logging 特性仍在弃用窗口内,日志级别改为每请求_meta.io.modelcontextprotocol/logLevel。同样,notifications/roots/list_changed被删除,不代表 Roots 类型在本版本消失。HTTP+SSE 与部分旧includeContext值属于此前已软弃用、后被生命周期政策重新分类的项目,不能机械套用 Roots 等新弃用项的时间线。[S03][S16]

最终判断:不再依赖连接,只是第一步

一次迁移是否完成,可以用七个问题检查:

  1. 相邻请求落到不同实例,是否仍能得到正确结果?
  2. 响应丢失后重发副作用工具,是否使用稳定 operation ID 并处理未知结果?
  3. 只有 handle 或 taskId、没有正确身份与 ACL 的调用者,是否必然失败?
  4. Client 或 Worker 重启后,Task 与必要业务对象是否可恢复?
  5. MRTR 的 requestState 是否短期、完整性受保护并绑定主体与原请求?
  6. 网关依赖的 Header 是否与正文一致,缓存是否按授权上下文隔离?
  7. 事后能否把身份、授权、请求、重试、Task、下游副作用与补偿拼成证据链?

只要其中任何一项仍依赖“请求大概会回到原实例”“这个 ID 足够随机所以无需授权”或“超时就等于没执行”,系统就只是删除了 Session 字段,没有完成无状态核心迁移。

MCP2026-07-28撤掉了一个语义过载的协议容器。身份回到逐请求授权上下文,短暂补充输入回到 MRTR,长执行回到 Tasks,领域状态由普通 handle 命名,重复副作用由 operation ledger 对账,链路诊断交给 Trace,持久追责交给审计账本。协议因此更容易路由、缓存和横向扩展;应用则必须把状态、授权、重试和恢复写成能被故障注入验证的合同。

FAQ

无状态是否意味着服务端不能保存任何状态?

不是。规范核心不依赖连接历史,服务仍可保存资源、任务、业务操作和审计状态,但必须通过显式标识符与生命周期访问。

Tasks 能否承担所有长任务和业务状态?

不能。Tasks 是可选扩展,解决异步执行生命周期;领域对象、授权和副作用幂等仍需业务层承载。

超时后为什么不能直接重试?

因为副作用可能已经发生。必须先区分未执行、已执行和结果未知,再依据 operation_id 对账或补偿。

参考资料