- 基础协议(Base Protocol):核心的 JSON-RPC 消息类型
- 版本管理与兼容性(Versioning and Compatibility):协议版本协商、扩展协商,以及与早期协议修订版的互操作性
- 消息模式(Message Patterns):核心协议所支持的消息传递模式,包括请求与响应、多轮往返请求(MRTR),以及订阅与通知
- 授权(Authorization):用于基于 HTTP 的传输的认证和授权框架
- 服务器特性(Server Features):由服务器暴露的资源、提示和工具
- 客户端特性(Client Features):由客户端提供的征询、采样和根目录列表
- 实用工具(Utilities):诸如日志记录和参数补全之类的横切关注点
消息
MCP 客户端与服务器之间的所有消息**必须(MUST)**遵循 JSON-RPC 2.0 规范。协议定义以下类型的消息:请求
请求从客户端发送到服务器,以发起一个操作。- 请求**必须(MUST)**包含一个字符串或整数 ID。
- 与基础 JSON-RPC 不同,ID **不得(MUST NOT)**为
null。 - 请求 ID **不得(MUST NOT)**与发送方已发出且尚未收到响应的任何其他请求的 ID 相同。
响应
响应作为对请求的答复发送,包含操作的结果或错误。结果响应
结果响应在操作成功完成时发送。- 结果响应**必须(MUST)**包含与它们所对应的请求相同的 ID。
- 结果响应**必须(MUST)**包含一个
result字段。 result**可以(MAY)**遵循任何 JSON 对象结构。result**必须(MUST)**包含一个resultType字段以指示结果的类型。
ResultType
结果中的resultType 字段指示所返回结果的类型。MCP 支持多态的结果类型,允许服务器根据请求的结果返回不同的结构。resultType 字段是一个字符串,客户端可以用它来确定如何解析和处理 result 对象。
resultType为"complete"表示请求成功完成,且结果包含最终内容。resultType为"input_required"表示请求未完成,需要更多信息来处理该请求。结果包含一个带有所需额外信息的InputRequiredResult对象。- 扩展**可以(MAY)添加额外的
ResultType值。所支持的ResultType值集合必须(MUST)**从核心协议中定义的集合创建,并包含通过能力公布的所支持扩展的任何额外值。 - 客户端无法识别的任何
resultType值**必须(MUST)**被视为无效。 - 为了与实现早期协议版本、不包含
resultType的服务器向后兼容,客户端**必须(MUST)**将缺失的resultType视为"complete"。
错误响应
错误响应在操作失败或遇到错误时发送。- 错误响应**必须(MUST)**包含与它们所对应的请求相同的 ID(除了由于请求格式错误而无法读取 ID 的错误情况)。
- 错误响应**必须(MUST)**包含一个带有
code和message的error字段。 - 错误代码**必须(MUST)**是整数。
- 错误响应**可以(MAY)**包含一个带有任何类型额外信息(例如嵌套错误)的
data成员。
错误代码
MCP 使用标准的 JSON-RPC 2.0 错误代码(-32700、-32600 到 -32603)表示一般的协议失败。
JSON-RPC 2.0 为实现定义的服务器错误保留了 -32000 到 -32099 的范围。MCP 按如下方式对该范围进行分区:
-32000到-32019—— 遗留(legacy)。 此子范围内的代码是在本策略引入之前由实现分配的。**不得(MUST NOT)在此子范围内分配新代码,且新的实现完全不应(SHOULD NOT)使用此子范围内的代码。除了-32002(见下文)之外,接收方不得(MUST NOT)**假定这些代码有任何特定含义。-32020到-32099—— 为 MCP 规范保留。 此子范围内的错误代码专由 MCP 规范定义,并记录在 schema 中。实现**不得(MUST NOT)发出此子范围内任何未由本规范定义的代码,并必须(MUST)**仅以其指定的含义使用已定义的代码。
由早期协议版本定义的代码仍被保留且不会被重用。本协议版本的实现**不得(MUST NOT)**发出这些代码:
-32002—— 资源未找到(2025-11-25 及更早版本;由-32602替换)。客户端**应当(SHOULD)**仍接受来自实现早期版本的服务器的-32002。-32042—— 需要 URL 征询(仅 2025-11-25)。
-32768 到 -32000)之外分配;整数空间的其余部分可用于应用定义的错误。
通知
通知从客户端发送到服务器或反之,作为单向消息。接收方**不得(MUST NOT)**发送响应。- 通知**不得(MUST NOT)**包含 ID。
消息模式
模型上下文协议(MCP)支持若干消息模式,它们定义客户端与服务器如何交互:- 请求与响应:客户端向服务器发送请求,服务器以结果或错误响应。
- 多轮往返请求(MRTR):服务器需要额外的客户端输入(采样、征询或 roots)来完成一个请求。
- 订阅与通知:客户端订阅来自服务器的通知流,这些通知在发生时被发送。
无状态性
模型上下文协议(MCP)是一个无状态协议:处理请求所需的所有信息都包含在请求本身中。服务器独立地处理每个请求;不应从先前的请求(即使是同一连接或流上的请求)推断任何状态。 具体而言:- 服务器**不得(MUST NOT)**依赖同一连接上的先前请求来建立上下文(例如能力、协议版本、客户端身份)。每个请求都在其
_meta字段中提供这些元数据。 - 服务器**应当(SHOULD)**准备好处理与多个任务、线程或对话关联的请求。
- 服务器**不应(SHOULD NOT)**要求客户端重用同一连接或进程来执行相关操作。
- 客户端**不应(SHOULD NOT)**将单个任务、线程或对话用作 stdio 进程的生命周期边界。
- 需要跨多个请求的状态(例如长时运行的任务、应用级句柄)**必须(MUST)**由客户端在每个请求上传递的显式标识符来引用。
这意味着一个打开的连接(例如一个 STDIO 进程)不是一次对话或会话:客户端可以在同一传输上交错无关的请求,而服务器不得将连接或进程身份视为对话或会话连续性的代理。
subscriptions/listen 之类的长期存在的请求仍然是请求/响应;响应只是一个打开的通知流。它们的状态被限定于请求本身,而不是其下的连接。
有关每请求模型如何映射到 SDK 代码的讲解,参见架构指南。
认证
MCP 提供一个用于 HTTP 的授权框架。使用基于 HTTP 的传输的实现**应当(SHOULD)遵循本规范,而使用 STDIO 传输的实现不应(SHOULD NOT)**遵循本规范,而应改为从环境中检索凭据。 此外,客户端和服务器**可以(MAY)**协商它们自己的自定义认证和授权策略。 要就 MCP 认证机制的演进进行进一步讨论和贡献,请加入我们的 GitHub Discussions,帮助塑造协议的未来!Schema
协议的完整规范被定义为一个 TypeScript schema。这是所有协议消息和结构的真实来源(source of truth)。 还有一个 JSON Schema,它从 TypeScript 真实来源自动生成,供各种自动化工具使用。JSON Schema 用法
模型上下文协议在整个协议中使用 JSON Schema 进行校验。本节澄清 JSON Schema 应如何在 MCP 消息中使用。Schema 方言
MCP 支持带有以下规则的 JSON Schema:- 默认方言:当一个 schema 不包含
$schema字段时,它默认为 JSON Schema 2020-12 - 显式方言:schema 可以(MAY)包含一个
$schema字段以指定一个不同的方言 - 支持的方言:实现必须(MUST)至少支持 2020-12,并应当(SHOULD)记录它们额外支持哪些方言
- 建议:推荐(RECOMMENDED)实现者使用 JSON Schema 2020-12。
用法示例
默认方言(2020-12):
显式方言(draft-07):
实现要求
- 对于没有显式
$schema字段的 schema,客户端和服务器**必须(MUST)**支持 JSON Schema 2020-12 - 客户端和服务器**必须(MUST)根据其声明的或默认的方言来校验 schema。它们必须(MUST)**通过返回一个指示不支持该方言的适当错误,优雅地处理不受支持的方言。
- 客户端和服务器**应当(SHOULD)**记录它们支持哪些 schema 方言
Schema 校验
- Schema **必须(MUST)**根据其声明的或默认的方言有效
$ref 解析
JSON Schema 2020-12 允许 $ref 指向一个绝对 URI。实现**不得(MUST NOT)**自动解引用解析为网络 URI 的 $ref 值。
实现**可以(MAY)提供一个选择加入的模式来获取非本地的 $ref,但它必须(MUST)默认禁用,并应当(SHOULD)**强制执行主机 allowlist,或至少拒绝回环、链路本地和私有网络地址,应用超时和大小限制,并记录被解引用的 URI。
由于未解析的外部 $ref 而校验失败的 schema **应当(SHOULD)**被拒绝,而不是被静默地视为宽松的。
组合关键字资源使用
组合关键字(anyOf、oneOf、allOf、if/then/else)和 $defs 支持富有表现力的 schema,但校验起来可能代价高昂。实现**应当(SHOULD)**应用合理的界限,例如最大 schema 深度、子 schema 总数的上限,或每次校验的时间预算,以防止一个恶意的 schema 充当针对校验器的拒绝服务(Denial-of-Service)向量。
通用字段
_meta
_meta 属性/参数被 MCP 用来允许客户端和服务器为它们的交互附加额外的元数据。
某些键名被 MCP 保留用于协议级别的元数据,如下所指定;实现**不得(MUST NOT)**对这些键处的值做出假设。
键名格式: 有效的 _meta 键名有两个部分:一个可选的前缀(prefix)和一个名称(name)。
前缀:
- 如果指定,必须(MUST)是由点(
.)分隔的一系列标签,后跟一个斜杠(/)。- 标签必须(MUST)以字母开头并以字母或数字结尾;内部字符可以是字母、数字或连字符(
-)。 - 实现应当(SHOULD)使用反向 DNS 表示法(例如
com.example/而非example.com/)。
- 标签必须(MUST)以字母开头并以字母或数字结尾;内部字符可以是字母、数字或连字符(
- 任何第二个标签为
modelcontextprotocol或mcp的前缀都为 MCP 使用而保留。- 例如:
io.modelcontextprotocol/、dev.mcp/、org.modelcontextprotocol.api/和com.mcp.tools/都是保留的。 - 然而,
com.example.mcp/不保留,因为第二个标签是example。
- 例如:
- 除非为空,否则必须(MUST)以一个字母数字字符(
[a-z0-9A-Z])开头和结尾。 - 可以(MAY)在中间包含连字符(
-)、下划线(_)、点(.)和字母数字。
_meta 键由本规范保留:
官方扩展在
io.modelcontextprotocol/ 前缀下定义额外的 _meta 键,而第三方扩展使用它们自己的供应商前缀。在这两种情况下,键都在扩展的文档中指定。
每请求协议字段:
客户端请求在 _meta 中携带以下 io.modelcontextprotocol/* 字段;标记为必需的字段**必须(MUST)**包含在每个请求上。服务器使用这些字段来识别所使用的协议版本和能力,而无需依赖任何先前的连接状态。版本协商规则参见版本管理与兼容性。
缺少任何必需字段的请求是格式错误的;服务器**必须(MUST)以 JSON-RPC 错误代码
-32602(Invalid params)拒绝它。在 HTTP 上,响应状态必须(MUST)**是 400 Bad Request。
除非被特别配置为不这样做,客户端**应当(SHOULD)**在每个请求上包含 io.modelcontextprotocol/clientInfo。
服务器**不得(MUST NOT)依赖客户端未声明的能力。如果处理一个请求需要客户端未包含在 io.modelcontextprotocol/clientCapabilities 中的能力,服务器必须(MUST)返回一个 MissingRequiredClientCapabilityError(-32021),其 data.requiredCapabilities 列出缺少的能力。在 HTTP 上,响应状态必须(MUST)**是 400 Bad Request。
每响应协议字段:
除非被特别配置为不这样做,服务器**应当(SHOULD)**在每个结果的 _meta 中包含以下 io.modelcontextprotocol/* 字段,以在不依赖任何先前连接状态的情况下标识自己:
io.modelcontextprotocol/clientInfo 和 io.modelcontextprotocol/serverInfo 由发送方自行报告,且不由协议校验。它们旨在用于显示、日志记录和调试。实现**不应(SHOULD NOT)使用它们来改变客户端或服务器的行为,并不应(SHOULD NOT)**依赖它们做出安全决策。subscriptions/listen 流投递的通知上,服务器**必须(MUST)**在 _meta 中包含 io.modelcontextprotocol/subscriptionId,以便客户端可以将通知与发起的订阅请求关联起来。
OpenTelemetry 追踪上下文:
作为对上述前缀要求的一个例外,键 traceparent、tracestate 和 baggage 为 OpenTelemetry 追踪上下文传播保留。当存在时,它们的值必须(MUST)分别遵循 W3C Trace Context 和 W3C Baggage 格式。
此例外的存在是为了维持与现有实现以及 OpenTelemetry MCP 语义惯例的兼容性。
_meta 中追踪上下文的非规范性示例:
icons
icons 属性为服务器提供了一种标准化的方式来为其资源、工具、提示和实现暴露视觉标识符。图标通过提供视觉上下文来增强用户界面,并改善可用功能的可发现性。
图标被表示为一个 Icon 对象数组,其中每个图标包括:
src:指向图标资源的 URI(必需)。这可以是:- 指向图像文件的 HTTP/HTTPS URL
- 带有 base64 编码图像数据的 data URI
mimeType:可选的 MIME 类型,用于服务器类型缺失或通用的情况sizes:可选的尺寸规格数组(例如["48x48"],对于像 SVG 这样的可缩放格式用["any"],或对于多个尺寸用["48x48", "96x96"])theme:可选的图标背景主题偏好(light或dark)
image/png—— PNG 图像(安全、通用兼容)image/jpeg(和image/jpg)—— JPEG 图像(安全、通用兼容)
image/svg+xml—— SVG 图像(可缩放,但需要如下所述的安全预防措施)image/webp—— WebP 图像(现代、高效的格式)
- 将图标元数据和图标字节视为不受信任的输入,并防御网络、隐私和解析风险。
- 确保图标 URI 是 HTTPS 或
data:URI。客户端**必须(MUST)**拒绝使用不安全的 scheme 和重定向的图标 URI,例如javascript:、file:、ftp:、ws:或本地应用 URI scheme。- 不允许 scheme 变更和到不同 origin 主机的重定向。
- 对源于过大图像、大尺寸或过多帧(例如 GIF 中)的资源耗尽攻击保持有韧性。
- 消费者**可以(MAY)**为图像和内容大小设置限制。
- 在不带凭据的情况下获取图标。不要发送 cookie、
Authorizationheader 或客户端凭据。 - 验证图标 URI 与服务器同源。这最小化了向第三方暴露数据或跟踪信息的风险。
- 在获取和渲染图标时保持谨慎,因为负载**可以(MAY)**包含可执行内容(例如带有嵌入 JavaScript 或扩展能力的 SVG)。
- 消费者**可以(MAY)**选择不允许特定的文件类型,或在渲染前以其他方式净化图标文件。
- 在渲染前校验 MIME 类型和文件内容。将 MIME 类型信息视为建议性的。通过魔术字节(magic bytes)检测内容类型;在不匹配或未知类型时拒绝。
- 维护一个严格的图像类型 allowlist。
Implementation:MCP 服务器/客户端实现的视觉标识符Tool:工具功能的视觉表示Prompt:与提示模板一起显示的图标Resource:不同资源类型的视觉指示器