MCP 标准化的是模型应用与外部能力的连接层
没有 MCP 时,每个模型应用都要为文件、数据库、浏览器或业务服务重复设计能力描述、调用、结果和连接生命周期。MCP 把这部分收敛为基于 JSON-RPC 的共同语义,使一个 Host 可以连接不同 Server,也让 Server 不必了解具体模型供应商。
协议只统一“如何声明和交换能力”,不会自动统一能力的业务语义。两个都叫 search 的 Tool,权限、召回范围和一致性仍可能完全不同;业务 API 的事务、鉴权和幂等也不会因包上一层 MCP 就消失。
Host–Client–Server 责任
Host
Host 是安全与体验边界:选择哪些 Server 可见,把哪些结果放入模型上下文,何时提示用户审批,以及如何展示来源和副作用。Server 返回的描述、Prompt 和内容都只是外部输入,不能覆盖 Host 的系统指令或策略。
Client
Client 是 Host 内部或其 SDK 中的协议端点。它为一个 Server 处理版本、能力发现、请求 ID、取消、超时、内容解码和错误归一化。实现上可复用连接池,但不能让不同 Server 或租户的凭据、缓存与 Context 默认串联。
Server
Server 把业务能力映射为协议 Primitive,校验输入,在业务边界再次鉴权,并返回可供人和机器消费的结果。它不应假设 Tool 被模型选中就代表用户授权,也不应把模型视为可信调用者。
有状态会话的生命周期
版本边界:本节标题描述 2025-11-25 及更早版本的主模型,而不是当前推荐实现。旧版通过 initialize/initialized 交换版本和能力,Streamable HTTP 还可返回 Mcp-Session-Id;客户端随后携带 Session ID,服务端需处理粘性路由、共享状态与断线清理。
在 2026-07-28 正式规范中,握手与协议级 Session 已移除。每个请求携带协议版本、客户端信息和能力;客户端可选调用 server/discover 预先探测。应用若需要跨调用状态,应返回显式 basket_id、browser_id 等 Handle,由后续 Tool 参数继续传递。
| 维度 | 2025-11-25 及更早 | 2026-07-28 |
|---|---|---|
| 启动 | initialize → initialized | 请求自包含;server/discover 可选 |
| 协议状态 | 可能依赖 Mcp-Session-Id | 不得从前序请求推断状态 |
| 扩缩容 | 常需粘性路由或共享 Session Store | 普通无状态实例即可处理任一请求 |
| 应用状态 | 容易与 Transport Session 混合 | 显式 Handle 或业务存储 |
兼容客户端不能猜版本。对 stdio 可先发 server/discover,收到 Method Not Found 再降级旧握手;对 HTTP 按版本头和错误处理。迁移期间应把“现代无状态路径”和“旧版会话路径”做成两个可独立删除的适配器。
三类 Primitive 的不同语义
Tool、Resource 和 Prompt 不是同一份内容的三种包装。选错 Primitive 会让权限、缓存和交互语义模糊。
Tools
定义
Tool 表示可调用动作,核心是稳定名称、面向选择的描述、JSON Schema 输入以及可选输出 Schema。2026-07-28 的 Tool Schema 支持完整 JSON Schema 2020-12,但实现仍应限制 Schema 深度、验证耗时和外部引用。Annotations 只是提示信息,不能代替真实副作用策略。
调用
tools/call 必须在服务端解析参数、鉴权并执行。传输成功不等于业务成功:业务错误应保持可读摘要与结构化信息;未知副作用结果不能简单重试。长任务可使用 Tasks 扩展,但其生命周期和核心协议独立演进。
Resources
标识与读取
Resource 用 URI 标识可读数据,适合文档、Schema、日志片段等“获取内容”语义;Resource Template 用 URI Template 表达参数化集合。URI 是定位标识,不自动证明权限或新鲜度,服务端读取时仍需做路径归一化、租户校验和访问控制。
变化
当前列表与读取结果可携带 ttlMs 和 cacheScope。客户端按新鲜度和共享范围缓存,而不是永久相信首次发现。旧版订阅和 List Changed 机制在兼容路径中仍可能出现,缓存失效策略必须按协商版本实现。
Prompts
Prompt 是 Server 提供的参数化消息资产,适合用户显式选择的工作方式或领域模板。它不拥有高于 Host 的指令优先级;Host 应把来源标清并按不可信内容处理,避免 Server 通过 Prompt 获得隐式控制权。
Server 请求的客户端能力
Elicitation 等能力必须由客户端显式支持。2026-07-28 使用 Multi Round-Trip Request(MRTR):Server 在处理一个客户端请求期间返回 input_required,Host 收集用户输入后带 requestState 重发。Roots、Sampling 和 Logging 已进入弃用周期,新实现不应继续围绕它们建立核心依赖。
Transport 不改变协议责任
stdio 适合本地子进程:stdout 必须只承载协议帧,日志写 stderr;Host 管理进程启动、退出、环境变量和文件权限。Streamable HTTP 适合远程服务:2026-07-28 要求 MCP-Protocol-Version、Mcp-Method 与必要时的 Mcp-Name,让网关无需解析正文即可路由、限流和审计。
JSON-RPC Request 有 ID 并期待 Response,Notification 不期待响应;重复 ID、丢失响应、取消竞态都属于 Client 状态机责任。HTTP 2xx 只说明承载层成功,JSON-RPC Error、MCP 协议错误和 Tool 业务失败必须分层观测。
// 简化的协议观测事件:不是 SDK API
type McpTraceEvent = {
protocolVersion: string
transport: 'stdio' | 'http'
method: string
name?: string
requestId: string | number
phase: 'sent' | 'input_required' | 'completed' | 'failed'
errorLayer?: 'transport' | 'jsonrpc' | 'mcp' | 'business'
}
内容模型与大结果处理
结果可包含文本、图像、音频、嵌入资源或 Resource Link;结构化内容用于机器处理,人类可读摘要用于审阅。客户端必须按 Content Type、大小、敏感级别和可信来源过滤后,才决定是否展示或注入模型上下文。
大结果不应直接塞满 Context。优先返回分页游标、可鉴权 Artifact/Resource 引用、摘要与校验信息;读取时再次校验权限和有效期。对工具返回的 URL、文件名、MIME 和自然语言指令都按不可信外部输入处理。
协议版本和能力演进
版本兼容的最小单位不是“SDK 能启动”,而是一条完整协议序列。测试应固定请求/响应录制、能力组合、未知可选字段、错误码、MRTR、多版本降级和断线情形。2026-07-28 引入扩展框架和正式弃用生命周期,新能力可独立版本化;这降低核心频繁破坏的概率,但不会替团队自动完成迁移。
| 场景 | 期望行为 | 证据 |
|---|---|---|
| 现代 Client × 现代 Server | 无握手、请求自包含 | 无 Session 依赖的 Trace |
| 现代 Client × 旧 Server | 探测后显式降级 | discover -32601 → initialize 序列 |
| 未知扩展 | 可选项忽略;必需项拒绝 | 扩展协商契约测试 |
| Schema/错误演进 | 读旧写新,保留稳定内部错误 | Golden Trace 与回归报告 |
主动提取:为什么 2026-07-28 的“无状态”不等于 Agent 业务无状态?
迁移判断:已有 2025-11-25 Server 是否应一次性删除 Session?
资料与事实边界
以下以官方文档、标准、论文和原始工程资料为主。厂商 API、价格、限额与模型能力会变化,落地时仍需按目标版本做能力探测和回归。
- MCP Specification 2026-07-28 — 当前正式规范、版本与能力导航
- MCP 2026-07-28 release notes — 无状态核心、MRTR、缓存、扩展与弃用的断代说明
- MCP TypeScript SDK v2 — 实现 2026-07-28 的稳定 SDK 线及 v1→v2 边界
- JSON-RPC 2.0 Specification — Request、Response、Notification 与错误基础