SEP-1613:将 JSON Schema 2020-12 确立为 MCP 默认方言

SEP-1613:将 JSON Schema 2020-12 确立为 MCP 默认方言

社区译文;来源: MCP 29affa6b

本 SEP 已达到 Final 状态,并作为已接受设计的历史记录保留。 定稿后对协议所做的更改不会反映在此处。权威要求请参阅当前规范 及其变更日志。
字段值
SEP1613
标题将 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 和 outputSchema
  • prompts/elicit 请求:requestedSchema
  • 未来内嵌 JSON Schema 定义的 MCP 特性

5. 实现要求

服务器 MUST:

  • 默认生成符合 2020-12 的 schema
  • 使用非默认方言时包含显式 $schema

客户端 MUST:

  • 根据声明的方言或默认方言验证 schema
  • 至少支持 JSON Schema 2020-12

理由

为什么选择 2020-12?

  1. 生态系统一致性:Python SDK(通过 Pydantic)和 Go SDK 实现倾向于或正在使用 2020-12
  2. 现代特性:提供更好的验证能力和组合支持
  3. 社区偏好:PR #655 讨论中的多位维护者和社区成员主张选择 2020-12,而不是 draft-07
  4. 当前标准:截至 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。

可选方案:

  1. 更新 schema 生成脚本,在生成后修补为 2020-12(我在当前 PR 中采用了这种方式)
  2. 改用支持 2020-12 的其他 schema 生成器
  3. 保持现状,因为它实际上并不与规范冲突?

就个人而言,我倾向于短期采用方案 (1),然后通过后续工作实施方案 (2)。