主题
概述
Model Context Protocol 由若干协同工作的关键组件构成:
- 基础协议:核心 JSON-RPC 消息类型
- 版本管理与兼容性:协议版本协商、扩展协商,以及与更早协议修订版的互操作性
- 消息模式:核心协议支持的消息模式,包括请求与响应、多轮往返请求(MRTR),以及订阅与通知
- 授权:面向基于 HTTP 的传输的身份认证与授权框架
- 服务端特性:服务端暴露的资源、提示模板和工具
- 客户端特性:客户端提供的征询、采样和根目录列表
- 实用工具:日志记录和参数补全等横切关注点
所有实现 MUST(必须)支持基础协议、版本管理和消息模式。其他组件 MAY(可以)根据应用的具体需求进行实现。
这些协议层在实现关注点清晰分离的同时,支持客户端与服务端之间丰富的交互。模块化设计使实现能够精确支持其所需的功能。
消息
MCP 客户端与服务端之间的所有消息 MUST(必须)遵循 JSON-RPC 2.0 规范。协议定义了以下消息类型:
请求
请求由客户端发送至服务端,用于发起一项操作。
typescript
{
jsonrpc: "2.0";
id: string | number;
method: string;
params?: {
[key: string]: unknown;
};
}- 请求 MUST(必须)包含字符串或整数 ID。
- 与基础 JSON-RPC 不同,ID MUST NOT(不得)为
null。 - 请求 ID MUST NOT(不得)与发送方已发出但尚未收到响应的任何其他请求的 ID 相同。
响应
响应用于回复请求,包含操作的结果或错误。
结果响应
结果响应在操作成功完成时发送。
typescript
{
jsonrpc: "2.0";
id: string | number;
result: {
resultType: string;
[key: string]: unknown;
};
}- 结果响应 MUST(必须)包含与其对应请求相同的 ID。
- 结果响应 MUST(必须)包含
result字段。 resultMAY(可以)遵循任意 JSON 对象结构。resultMUST(必须)包含resultType字段,以指示结果的类型。
ResultType
结果中的 resultType 字段指示所返回结果的类型。MCP 支持多态结果类型,允许服务端根据请求的结果返回不同的结构。resultType 字段是一个字符串,客户端可用它来确定如何解析和处理 result 对象。
resultType为"complete"表示请求已成功完成,结果包含最终内容。resultType为"input_required"表示请求尚未完成,处理该请求还需要更多信息。结果包含一个InputRequiredResult对象,其中带有所需的附加信息。- 扩展 MAY(可以)添加额外的
ResultType值。受支持的ResultType值集合 MUST(必须)由核心协议中定义的值集合以及通过能力声明的受支持扩展的任何附加值构成。 - 客户端无法识别的任何
resultType值 MUST(必须)被视为无效。 - 为与实现更早协议版本(不包含
resultType)的服务端保持向后兼容,客户端 MUST(必须)将缺失的resultType视为"complete"。
错误响应
错误响应在操作失败或遇到错误时发送。
typescript
{
jsonrpc: "2.0";
id?: string | number;
error: {
code: number;
message: string;
data?: unknown;
}
}- 错误响应 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— 传统。 该子范围内的错误码由各实现在此策略引入之前分配。新错误码 MUST NOT(不得)分配在该子范围内,新实现 SHOULD NOT(不应)使用该子范围内的任何错误码。除-32002(见下文)外,接收方 MUST NOT(不得)假定这些错误码具有任何特定含义。-32020至-32099— 保留给 MCP 规范。 该子范围内的错误码仅由 MCP 规范定义,并记录在模式中。实现 MUST NOT(不得)发出该子范围内本规范未定义的任何错误码,且 MUST(必须)仅按指定含义使用已定义的错误码。
MCP 定义了以下错误码:
| Code | Name |
|---|---|
-32020 | HeaderMismatch |
-32021 | MissingRequiredClientCapability |
-32022 | UnsupportedProtocolVersion |
| 更早协议版本定义的错误码仍为保留状态,不会被复用。本协议版本的实现 MUST NOT(不得)发出以下错误码: |
-32002— 资源未找到(2025-11-25 及更早版本;已被-32602取代)。对于实现更早版本的服务端,客户端SHOULD(应当)仍然接受-32002。-32042— 需要 URL 征询(仅限 2025-11-25)。
纯粹属于实现本地的错误(例如 SDK 内部引发的请求超时)目前未被本规范分配错误码。实现若以 JSON-RPC 形式的结构呈现本地错误,应确保它们不会被误认为是从对端接收到的错误。规范的未来版本可能会在保留子范围内为常见本地错误情况定义标准错误码。
本规范未定义用途的新错误码 SHOULD(应当)分配在 JSON-RPC 保留范围(-32768 至 -32000)之外;整数空间的其余部分可供应用定义的错误使用。
通知
通知由客户端发送至服务端,或反之,作为单向消息。接收方 MUST NOT(不得)发送响应。
typescript
{
jsonrpc: "2.0";
method: string;
params?: {
[key: string]: unknown;
};
}- 通知 MUST NOT(不得)包含 ID。
消息模式
Model Context Protocol (MCP) 支持若干种消息模式,用于定义客户端与服务端的交互方式:
- 请求与响应:客户端向服务端发送请求,服务端以结果或错误作为响应。
- 多轮往返请求(MRTR):服务端需要额外的客户端输入(采样、征询或根目录)才能完成请求。
- 订阅与通知:客户端订阅来自服务端的通知流,通知在发生时即被发送。
无状态
Model Context Protocol (MCP) 是一种无状态协议:处理请求所需的所有信息都包含在请求本身之中。服务端独立处理每个请求;不应从先前的请求(即使是同一连接或流上的请求)推断任何状态。
具体而言:
- 服务端 MUST NOT(不得)依赖同一连接上的先前请求来建立上下文(例如能力、协议版本、客户端身份)。每个请求都在其
_meta字段中提供这些元数据。 - 服务端 SHOULD(应当)准备好处理与多个任务、线程或对话相关联的请求。
- 服务端 SHOULD NOT(不应)要求客户端复用同一连接或进程来执行相关操作。
- 客户端 SHOULD NOT(不应)将单个任务、线程或对话作为 stdio 进程的生命周期边界。
- 需要跨多个请求存在的状态(例如长时间运行的任务、应用级句柄)MUST(必须)通过客户端在每次请求中传递的显式标识符来引用。
NOTE
这意味着一个打开的连接(例如 STDIO 进程)并不是对话或会话:客户端可以在同一传输上交错发送不相关的请求,服务端不得将连接或进程身份视为对话或会话连续性的代理。
诸如 subscriptions/listen 这样的长生命周期请求仍然是请求/响应式的;其响应只是一个打开的通知流。它们的状态作用域是请求本身,而不是底层的连接。
INFO
关于逐请求模型如何映射到 SDK 代码的演练,请参阅架构指南。
授权
MCP 提供了用于 HTTP 的授权框架。使用基于 HTTP 的传输的实现 SHOULD(应当)遵循本规范,而使用 STDIO 传输的实现 SHOULD NOT(不应)遵循本规范,而应从环境中获取凭据。
此外,客户端与服务端 MAY(可以)协商各自自定义的身份认证与授权策略。
如需进一步讨论并为 MCP 授权机制的演进做出贡献,请加入我们的 GitHub Discussions,共同塑造协议的未来!
模式
协议的完整规范以 TypeScript 模式的形式定义。这是所有协议消息和结构的权威来源。
此外还有一份 JSON Schema,它由 TypeScript 权威来源自动生成,供各种自动化工具使用。
JSON Schema 用法
Model Context Protocol 在整个协议中使用 JSON Schema 进行校验。本节阐明在 MCP 消息中应如何使用 JSON Schema。
模式方言
MCP 按以下规则支持 JSON Schema:
- 默认方言:当模式不包含
$schema字段时,默认使用 JSON Schema 2020-12 - 显式方言:模式 MAY(可以)包含
$schema字段以指定不同的方言 - 受支持的方言:实现 MUST(必须)至少支持 2020-12,并 SHOULD(应当)记录其额外支持哪些方言
- 建议:建议实现者使用 JSON Schema 2020-12。
用法示例
默认方言(2020-12):
json
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer", "minimum": 0 }
},
"required": ["name"]
}显式方言(draft-07):
json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer", "minimum": 0 }
},
"required": ["name"]
}实现要求
- 对于没有显式
$schema字段的模式,客户端与服务端 MUST(必须)支持 JSON Schema 2020-12 - 客户端与服务端 MUST(必须)根据其声明或默认的方言校验模式。它们 MUST(必须)优雅地处理不支持的方言,返回表明该方言不受支持的适当错误。
- 客户端与服务端 SHOULD(应当)记录其支持哪些模式方言
模式校验
- 模式 MUST(必须)根据其声明或默认的方言有效
$ref 解析
JSON Schema 2020-12 允许 $ref 指向绝对 URI。实现 MUST NOT(不得)自动解引用解析为网络 URI 的 $ref 值。
实现 MAY(可以)提供一种选择性启用的模式来获取非本地 $ref,但它 MUST(必须)默认禁用,并 SHOULD(应当)强制实施主机允许列表,或至少拒绝回环、链路本地和私有网络地址,应用超时和大小限制,并记录被解引用的 URI。
因无法解析的外部 $ref 而校验失败的模式 SHOULD(应当)被拒绝,而不是被静默视为宽松模式。
组合关键字的资源使用
组合关键字(anyOf、oneOf、allOf、if/then/else)和 $defs 可实现富有表现力的模式,但校验成本可能很高。实现 SHOULD(应当)施加合理的界限,例如最大模式深度、子模式总数上限或每次校验的时间预算,以防止恶意模式成为针对校验器的拒绝服务攻击途径。
通用字段
_meta
MCP 使用 _meta 属性/参数,允许客户端与服务端为其交互附加额外的元数据。
如下所述,某些键名由 MCP 保留用于协议级元数据;实现 MUST NOT(不得)对这些键的值做出任何假设。
键名格式: 有效的 _meta 键名包含两段:可选的前缀和名称。
前缀:
- 若指定,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 键:
| Key | Description | Defined in |
|---|---|---|
progressToken | Opts the request into progress notifications | Progress |
io.modelcontextprotocol/protocolVersion | Protocol version for a request | Per-request protocol fields (below) |
io.modelcontextprotocol/clientInfo | Client name and version | Per-request protocol fields (below) |
io.modelcontextprotocol/clientCapabilities | Client capabilities relevant to a request | Per-request protocol fields (below) |
io.modelcontextprotocol/logLevel | Minimum log level the server should emit for a request | Logging |
io.modelcontextprotocol/subscriptionId | Correlates a notification with its originating subscription | Subscriptions |
traceparent, tracestate, baggage | OpenTelemetry trace context propagation | OpenTelemetry trace context (below) |
官方扩展在 io.modelcontextprotocol/ 前缀下定义了额外的 _meta 键,第三方扩展则使用各自的厂商前缀。在这两种情况下,这些键都在扩展的文档中加以规定。
逐请求协议字段:
客户端请求在 _meta 中携带以下 io.modelcontextprotocol/* 字段;标记为必需的字段 MUST(必须)在每次请求中都包含。服务端使用这些字段来识别正在使用的协议版本和能力,而无需依赖任何先前的连接状态。版本协商规则请参阅版本管理与兼容性。
| Key | Type | Required | Description |
|---|---|---|---|
io.modelcontextprotocol/protocolVersion | string | Yes | Protocol version for this request (e.g., "2026-07-28") |
io.modelcontextprotocol/clientInfo | Implementation | No | Client name and version |
io.modelcontextprotocol/clientCapabilities | ClientCapabilities | Yes | Client capabilities relevant to this request |
io.modelcontextprotocol/logLevel | LoggingLevel | No | Minimum log level the server should emit for this request |
缺少任何必需字段的请求均为格式错误;服务端 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/* 字段,以便在不依赖任何先前连接状态的情况下标识自身:
| Key | Type | Required | Description |
|---|---|---|---|
io.modelcontextprotocol/serverInfo | Implementation | No | Server name and version |
NOTE
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 中追踪上下文的非规范性示例:
json
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": {
"location": "New York"
},
"_meta": {
"traceparent": "00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01"
}
}
}icons
icons 属性为服务端提供了一种标准化方式,用于为其资源、工具、提示模板和实现暴露可视化标识。图标通过提供视觉上下文并改善可用功能的可发现性来增强用户界面。
图标表示为 Icon 对象数组,其中每个图标包含:
src:指向图标资源的 URI(必需)。可以是:- 指向图像文件的 HTTP/HTTPS URL
- 带有 base64 编码图像数据的 data URI
mimeType:当服务端的类型缺失或为通用类型时,可选的 MIME 类型sizes:可选的大小规格数组(例如["48x48"]、可缩放格式如 SVG 的["any"],或多种尺寸的["48x48", "96x96"])theme:可选的图标背景主题偏好(light或dark)
必需的 MIME 类型支持:
支持渲染图标的客户端 MUST(必须)至少支持以下 MIME 类型:
image/png- PNG 图像(安全,通用兼容)image/jpeg(以及image/jpg)- JPEG 图像(安全,通用兼容)
支持渲染图标的客户端 SHOULD(应当)还支持:
image/svg+xml- SVG 图像(可缩放,但需要如下所述的安全预防措施)image/webp- WebP 图像(现代、高效的格式)
安全注意事项:
图标元数据的消费方在处理图标时 MUST(必须)采取适当的安全预防措施,以防被攻陷:
- 将图标元数据和图标字节视为不可信输入,并防御网络、隐私和解析风险。
- 确保图标 URI 为 HTTPS 或
data:URI。客户端 MUST(必须)拒绝使用不安全协议和重定向的图标 URI,例如javascript:、file:、ftp:、ws:或本地应用 URI 协议。- 禁止协议变更以及重定向到不同源的主机。
- 对来自超大图像、过大尺寸或过多帧(例如 GIF 中)的资源耗尽攻击保持韧性。
- 消费方 MAY(可以)为图像和内容大小设置限制。
- 获取图标时不携带凭据。不要发送 cookie、
Authorization头或客户端凭据。 - 验证图标 URI 与服务端来自同一源。这可将数据或追踪信息暴露给第三方的风险降至最低。
- 在获取和渲染图标时保持谨慎,因为载荷 MAY(可以)包含可执行内容(例如带有内嵌 JavaScript 或扩展能力的 SVG)。
- 消费方 MAY(可以)选择禁止特定文件类型,或在渲染前以其他方式清理图标文件。
- 在渲染前校验 MIME 类型和文件内容。将 MIME 类型信息视为参考性信息。通过魔数字节检测内容类型;在不匹配或类型未知时拒绝。
- 维护严格的图像类型允许列表。
用法:
图标可附加到:
Implementation:MCP 服务端/客户端实现的可视化标识Tool:工具功能的可视化表示Prompt:与提示模板一同显示的图标Resource:不同资源类型的可视化指示 可提供多个图标以支持不同的显示场景和分辨率。客户端应根据其 UI 需求选择最合适的图标。