SEP-1613:将 JSON Schema 2020-12 确立为 MCP 默认方言
社区译文;来源: MCP 29affa6b
| 字段 | 值 |
|---|---|
| SEP | 1613 |
| 标题 | 将 JSON Schema 2020-12 确立为 MCP 默认方言 |
| 状态 | Final |
| 类型 | 标准跟踪 |
| 创建日期 | 2025-10-06 |
| 作者 | Ola Hungerford |
| 发起人 | 无 |
| PR | #1613 |
摘要
本 SEP 将 JSON Schema 2020-12 确立为 MCP 消息内嵌 schema(工具的 inputSchema/outputSchema
以及 elicitation 的 requestedSchema 字段)的默认方言。Schema 可以通过 $schema 字段显式声明
其他方言。此项变更消除了已在不同实现之间造成兼容性问题的歧义。
动机
MCP 规范没有明确说明内嵌 schema 应使用哪个 JSON Schema 版本。这导致了以下问题:
- 假定不同版本的客户端与服务器之间发生验证失败
- 各 SDK 生态系统的实现出现分歧
- 开发者无法确定版本,只能任意选择
社区讨论(GitHub Discussion #366、PR #655)表明,实现分别采用 draft-07 和 2020-12; 多位维护者和社区成员强烈倾向于将 2020-12 作为默认版本。
规范
1. 默认方言
当不存在 $schema 字段时,MCP 消息内嵌的 JSON schema MUST 遵循
JSON Schema 2020-12。
2. 显式方言声明
Schema MAY 包含显式 $schema 字段,以声明不同的方言:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": { "type": "string" }
}
}3. Schema 验证要求
- Schema MUST 根据其声明的方言或默认方言保持有效
inputSchema字段 MUST NOT 为null
对于没有参数的工具,使用以下任一有效方式:
true- 接受任何输入(最宽松){}- 等价于true,接受任何输入{ "type": "object" }- 接受含任意属性的任何对象{ "type": "object", "additionalProperties": false }- 只接受空对象{}
没有参数的工具示例:
{
"name": "get_current_time",
"description": "Returns the current server time",
"inputSchema": {
"type": "object",
"additionalProperties": false
}
}4. 适用范围
本规范适用于:
tools/list响应:inputSchema和outputSchemaprompts/elicit请求:requestedSchema- 未来内嵌 JSON Schema 定义的 MCP 特性
5. 实现要求
服务器 MUST:
- 默认生成符合 2020-12 的 schema
- 使用非默认方言时包含显式
$schema
客户端 MUST:
- 根据声明的方言或默认方言验证 schema
- 至少支持 JSON Schema 2020-12
理由
为什么选择 2020-12?
- 生态系统一致性:Python SDK(通过 Pydantic)和 Go SDK 实现倾向于或正在使用 2020-12
- 现代特性:提供更好的验证能力和组合支持
- 社区偏好:PR #655 讨论中的多位维护者和社区成员主张选择 2020-12,而不是 draft-07
- 当前标准:截至 2025 年,2020-12 是稳定版本
为什么允许显式声明?
- 为现有 schema 提供迁移路径
- 无需修改协议即可提供灵活性
- 遵循 JSON Schema 最佳实践
考虑过的替代方案
- 将 Draft-07 作为默认版本:根据社区反馈拒绝;该版本较旧、能力较少
- 不设默认版本:因不必要地冗长而拒绝;会增加样板内容
- 多个版本地位相同:拒绝;会造成不可预测性和碎片化
向后兼容性
严格来说,这是一项澄清,而不是破坏性变更:
- 不含
$schema的现有 schema 默认采用 2020-12 - 服务器可以在过渡期间添加显式
$schema - 基础 schema(type、properties、required)在多个版本中都可工作
默认假定 draft-07 的 schema 可能需要迁移:
- 使用
dependencies的 schema(→dependentSchemas+dependentRequired) - 位置数组验证(→
prefixItems)
**迁移策略:**在过渡期间添加显式 $schema: "http://json-schema.org/draft-07/schema#",
然后再更新为 2020-12 特性。
参考实现
SDK 实现
Python SDK - 已兼容:
- 使用 Pydantic 生成 schema
- Pydantic 通过
.model_json_schema()默认采用 2020-12
Go SDK - 已实现 2020-12:
- 显式的 2020-12 实现已经完成
- @samthanawalla 在 PR #655 的讨论中予以确认
其他 SDK:
- 可能需要更新,但根据其他示例,应有直接支持或开箱即用的方式支持此版本。提案被接受后, 我可以在此添加更多示例,也可以创建 issue 继续跟进。
安全影响
目前尚未发现将 2020-12 确立为默认方言会带来具体安全影响。这项澄清减少了可能导致实现之间 验证结果不一致的歧义,通过提高可预测性带来了小幅安全改善。
与任何依赖项一样,实现应使用维护良好的 JSON Schema 验证器库,并保持更新。
相关工作
SEP-1330:Elicitation 枚举 Schema 改进
SEP-1330 提议弃用非标准的 enumNames 属性,改用符合 JSON Schema 2020-12 的模式。
将 2020-12 确立为默认方言,为这项工作提供了直接基础。
实现注意事项:
正如 SEP-1330 讨论中指出的,一些人担心 oneOf 和 anyOf 等高级 JSON Schema 特性会增加解析复杂度。
不过,这些特性属于 JSON Schema 标准,并已得到成熟验证器库的良好支持。实现可以使用经过充分测试的
JSON Schema 验证库,在标准合规性与自身解析需求之间取得平衡。
SEP-834:完整支持 JSON Schema 2020-12
本 SEP 建立基础(默认方言),而 SEP-834 处理对 2020-12 特性的全面支持。
开放问题
规范自身的 schema 引用了 draft-07,而我们用于生成它的 typescript-json-schema 包只支持 draft-07。
可选方案:
- 更新 schema 生成脚本,在生成后修补为 2020-12(我在当前 PR 中采用了这种方式)
- 改用支持 2020-12 的其他 schema 生成器
- 保持现状,因为它实际上并不与规范冲突?
就个人而言,我倾向于短期采用方案 (1),然后通过后续工作实施方案 (2)。