最终版标准轨道
| 字段 | 值 |
|---|---|
| SEP | 1330 |
| 标题 | 询问枚举模式改进与标准合规性 |
| 状态 | 最终版 |
| 类型 | 标准轨道 |
| 创建日期 | 2025-08-11 |
| 作者 | chughtapan |
| 赞助人 | 无 |
| PR | #1330 |
摘要
本 SEP 提议改进 MCP 中的枚举模式定义,弃用非标准的enumNames 属性,转而采用符合 JSON 模式的模式,并除了单选模式外,引入对多选枚举模式的额外支持。新模式已针对 JSON 规范进行了验证。
模式变更: https://github.com/modelcontextprotocol/modelcontextprotocol/pull/1148
Typescript SDK 变更:https://github.com/modelcontextprotocol/typescript-sdk/pull/1077
Python SDK 变更:https://github.com/modelcontextprotocol/python-sdk/pull/1246
客户端实现: https://github.com/evalstate/fast-agent/pull/324/files
工作演示: https://asciinema.org/a/anBvJdqEmTjw0JkKYOooQa5Ta
动机
现有的枚举模式使用了一种非标准的方法来为枚举值添加标题。它还限制了枚举在询问(Elicitation)(以及未来任何应采用EnumSchema 的模式对象)中的使用,仅限于单选模型。要求用户选择多个条目是一种常见模式。在 UI 中,这相当于使用复选框或单选按钮的区别。
出于这些原因,我们提议对 EnumSchema 进行以下非破坏性的次要改进,以改善用户和开发者体验。
- 将现有的
EnumSchema保留为“遗留”- 它使用一种非标准的方法来为枚举值添加标题
- 将其标记为遗留,但目前仍支持它。
- 根据 @dsp-ant 的说法,当我们有了适当的弃用策略时,我们将标记它为已弃用
- 引入无标题枚举和有标题枚举的区别。
- 如果枚举值已足够,则无需为每个值指定单独的标题。
- 如果枚举值不适合显示,则可以为每个值指定标题。
- 引入单选和多选枚举的区别。
- 如果只能选择一个值,可以使用单选模式
- 如果可以选择多个值,可以使用多选模式
- 在
ElicitResponse中,将数组添加为additionalProperty类型- 允许将多个枚举值的选择返回给服务器
规范
1. 将带有非标准 enumNames 属性的当前 EnumSchema 标记为“遗留”
当前的 MCP 规范使用非标准的 enumNames 属性来提供枚举值的显示名称。我们提议将 enumNames 属性标记为遗留,建议使用 TitledSingleSelectEnum,这是我们下面定义的一种符合标准的枚举类型。
2. 定义单选枚举(带有有标题和无标题变体)
枚举可能需要也可能不需要标题。枚举值可能是人类可读的并且适合显示。在这种情况下,使用 JSON 模式关键字enum 的无标题实现更简单。添加标题需要使用 const 和 title 将 enum 数组替换为对象数组。
3. 引入多选枚举(带有有标题和无标题变体)
虽然询问不支持任意 JSON 类型(如数组和对象),以便客户端可以轻松显示选择项,但可以轻松实现多选枚举。4. 将所有变体组合为 EnumSchema
最终的 EnumSchema 将遗留、多选和单选模式汇总为一个,定义如下:
5. 扩展 ElicitResult
当前的询问结果模式仅允许返回原始类型。我们扩展此内容以包含用于 MultiSelectEnums 的字符串数组:实例模式示例
不带标题的单选(无变更)
带标题的遗留单选
带标题的单选
不带标题的多选
带标题的多选
理由
- 标准合规性:与官方 JSON 模式规范保持一致。标准模式可与现有的 JSON 模式验证器一起工作
- 灵活性:支持普通枚举和带有显示名称的枚举,适用于单选和多选枚举。
- 客户端实现: 表明实现一组复选框与单个复选框的额外开销是最小的:https://github.com/evalstate/fast-agent/pull/324/files
向后兼容性
LegacyEnumSchema 类型在迁移期间保持向后兼容。使用 enumNames 的现有实现将继续工作,直到实施协议范围的弃用策略,并且此模式被移除。
参考实现
模式变更: https://github.com/modelcontextprotocol/modelcontextprotocol/pull/1148 Typescript SDK 变更:https://github.com/modelcontextprotocol/typescript-sdk/pull/1077 Python SDK 变更:https://github.com/modelcontextprotocol/python-sdk/pull/1246 客户端实现: https://github.com/evalstate/fast-agent/pull/324/files 工作演示: https://asciinema.org/a/anBvJdqEmTjw0JkKYOooQa5Ta安全考虑
未发现安全隐患。此变更纯粹是关于模式结构和标准合规性。附录
验证
使用存储在 https://www.jsonschemavalidator.net/ 的 JSON Schema Validator 中的验证,我们验证:- 本文档中的所有示例实例模式针对下一节中提出的 JSON 元模式
EnumSchema进行验证。 - 针对本文档中的示例实例模式验证有效和无效的值。
遗留单选
EnumSchema验证一个 带有标题的遗留单选实例模式- 遗留带标题单选实例模式验证 一个正确的单选
- 遗留带标题单选实例模式验证 一个错误的单选
单选
EnumSchema验证一个 无标题的单选实例模式EnumSchema验证一个 带有标题的单选实例模式- 无标题单选实例模式验证 一个正确的单选
- 无标题单选实例模式使 [一个错误的单选] 无效 (https://www.jsonschemavalidator.net/s/3Try4BCt)
- 带标题单选实例模式验证 一个正确的单选
- 带标题单选实例模式使 [一个错误的单选] 无效 (https://www.jsonschemavalidator.net/s/A2KlNzLH)
多选
EnumSchema验证 无标题的多选实例模式EnumSchema验证 带有标题的多选实例模式- 无标题多选实例模式验证 一个正确的多选 无标题多选实例模式验证使 [ 一个错误的多选] 无效 (https://www.jsonschemavalidator.net/s/8tlqjUgW) 带标题多选实例模式验证 一个正确的多选 带标题多选实例模式验证使 [一个错误的多选] 无效 (https://www.jsonschemavalidator.net/s/MRfyqrVC)
JSON 元模式
这是我们提出的用于替换规范中schema.json 内当前 EnumSchema 的方案。