信息征询
社区译文;来源: MCP 80041ab0
模型上下文协议(MCP)为服务器在交互期间通过客户端向用户请求补充信息提供了一种标准方式。 此流程使客户端能够控制用户交互和数据共享,同时让服务器可以动态收集所需信息。
信息征询支持两种模式:
- 表单模式:服务器可以向用户请求结构化数据,并可选择使用 JSON Schema 验证响应
- URL 模式:服务器可以将用户引导至外部 URL,完成不得经过 MCP 客户端的敏感交互
用户交互模型
MCP 中的信息征询允许在其他 MCP 服务器功能内部_嵌套_发起用户输入请求,使服务器能够 实现交互式工作流。
实现可以自由采用符合自身需求的任何界面模式来公开信息征询;协议本身不规定具体的用户 交互模型。
出于信任、安全与防护考虑:
- 服务器 MUST NOT 使用表单模式信息征询请求密码、API 密钥、访问令牌或支付凭据等 敏感信息
- 对于涉及此类敏感信息的交互,服务器 MUST 使用 URL 模式
此处的“敏感信息”是指能够授予访问权限或授权交易的秘密和凭据。一般联系方式或个人资料 信息(例如姓名、电子邮件地址或用户名)并非一概禁止;是否通过表单模式请求此类数据由 服务器自行决定,但用户必须能够审查并拒绝请求。
MCP 客户端 MUST:
- 提供能够清楚表明哪个服务器正在请求信息的 UI
- 尊重用户隐私,并提供明确的拒绝和取消选项
- 对于表单模式,允许用户在发送前审查和修改响应
- 对于 URL 模式,在导航到目标 URL 前清楚显示目标域名/主机,并征得用户同意
能力
支持信息征询的客户端 MUST 在每个请求的
_meta.io.modelcontextprotocol/clientCapabilities 中声明 elicitation 能力:
{
"_meta": {
"io.modelcontextprotocol/clientCapabilities": {
"elicitation": {
"form": {},
"url": {}
}
}
}
}为了向后兼容,空的能力对象等同于仅声明支持 form 模式:
{
"_meta": {
"io.modelcontextprotocol/clientCapabilities": {
"elicitation": {}, // Equivalent to { "form": {} }
},
},
}声明 elicitation 能力的客户端 MUST 至少支持一种模式(form 或 url)。
服务器 MUST NOT 发送客户端不支持的模式的信息征询请求。
协议消息
信息征询请求
服务器在处理客户端请求期间 MAY 向用户请求信息,方法是发送一个包含
elicitation/create 请求的
InputRequiredResult
。
所有信息征询请求 MUST 包含以下参数:
| 名称 | 类型 | 选项 | 说明 |
|---|---|---|---|
mode | string | form, url | 信息征询模式。表单模式可省略(省略时默认为 "form")。 |
message | string | 说明为何需要此次交互的人类可读消息。 |
mode 参数指定信息征询的类型:
"form":带内结构化数据收集,可选择进行 schema 验证。数据会向客户端公开。"url":通过 URL 导航进行带外交互。除 URL 本身外,数据不会向客户端公开。
为了向后兼容,服务器对表单模式信息征询请求 MAY 省略 mode 字段。客户端对不含
mode 字段的请求 MUST 按表单模式处理。
表单模式信息征询请求
表单模式信息征询允许服务器直接通过 MCP 客户端收集结构化数据。
表单模式信息征询请求 MUST 指定 mode: "form" 或省略 mode 字段,并包含以下
附加参数:
| 名称 | 类型 | 说明 |
|---|---|---|
requestedSchema | object | 定义预期响应结构的 JSON Schema。 |
请求的 Schema
requestedSchema 参数允许服务器使用 JSON Schema 的受限子集定义预期响应的结构。
为简化客户端用户体验,表单模式的信息征询 schema 仅限于属性为基本类型的扁平对象。
schema 仅限以下基本类型:
字符串 Schema
{ "type": "string", "title": "Display Name", "description": "Description text", "minLength": 3, "maxLength": 50, "format": "email", "default": "[email protected]" }支持的格式:
email、uri、date、date-time数字 Schema
{ "type": "number", // or "integer" "title": "Display Name", "description": "Description text", "minimum": 0, "maximum": 100, "default": 50 }布尔 Schema
{ "type": "boolean", "title": "Display Name", "description": "Description text", "default": false }枚举 Schema
单选枚举(无标题):
{ "type": "string", "title": "Color Selection", "description": "Choose your favorite color", "enum": ["Red", "Green", "Blue"], "default": "Red" }单选枚举(有标题):
{ "type": "string", "title": "Color Selection", "description": "Choose your favorite color", "oneOf": [ { "const": "#FF0000", "title": "Red" }, { "const": "#00FF00", "title": "Green" }, { "const": "#0000FF", "title": "Blue" } ], "default": "#FF0000" }多选枚举(无标题):
{ "type": "array", "title": "Color Selection", "description": "Choose your favorite colors", "minItems": 1, "maxItems": 2, "items": { "type": "string", "enum": ["Red", "Green", "Blue"] }, "default": ["Red", "Green"] }多选枚举(有标题):
{ "type": "array", "title": "Color Selection", "description": "Choose your favorite colors", "minItems": 1, "maxItems": 2, "items": { "anyOf": [ { "const": "#FF0000", "title": "Red" }, { "const": "#00FF00", "title": "Green" }, { "const": "#0000FF", "title": "Blue" } ] }, "default": ["#FF0000", "#00FF00"] }
客户端可以使用此 schema:
- 生成适当的输入表单
- 在发送前验证用户输入
- 为用户提供更好的指引
所有基本类型都支持可选的默认值,以提供合理的初始值。支持默认值的客户端 SHOULD 使用这些值预填表单字段。
请注意,为简化客户端用户体验,复杂嵌套结构、对象数组(枚举除外)以及其他高级 JSON Schema 功能被有意排除在支持范围之外。
示例:简单文本请求
输入请求(在 InputRequiredResult.inputRequests
中传递):
{
"method": "elicitation/create",
"params": {
"mode": "form",
"message": "Please provide your GitHub username",
"requestedSchema": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": ["name"]
}
}
}客户端结果(在重试请求的 inputResponses 中返回):
{
"action": "accept",
"content": {
"name": "octocat"
}
}示例:结构化数据请求
输入请求(在 InputRequiredResult.inputRequests 中传递):
{
"method": "elicitation/create",
"params": {
"mode": "form",
"message": "Please provide your contact information",
"requestedSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Your full name"
},
"email": {
"type": "string",
"format": "email",
"description": "Your email address"
},
"age": {
"type": "number",
"minimum": 18,
"description": "Your age"
}
},
"required": ["name", "email"]
}
}
}客户端结果(在重试请求的 inputResponses 中返回):
{
"action": "accept",
"content": {
"name": "Monalisa Octocat",
"email": "[email protected]",
"age": 30
}
}URL 模式信息征询请求
2025-11-25 版本中引入。其设计和实现可能会
在未来的协议修订中发生变化。URL 模式信息征询使服务器能够将用户引导至外部 URL,以完成不得经过 MCP 客户端的带外 交互。这对于身份验证流程、支付处理及其他敏感或安全操作至关重要。
URL 模式信息征询请求 MUST 指定 mode: "url"、message,并包含以下附加参数:
| 名称 | 类型 | 说明 |
|---|---|---|
url | string | 用户应导航到的 URL。 |
url 参数 MUST 包含有效 URL。
示例:请求敏感数据
以下示例展示了一个 URL 模式信息征询请求,它将用户引导至安全 URL,以便用户在该处 提供敏感信息(例如 API 密钥)。同一请求也可以将用户引导至 OAuth 授权流程或支付流程, 区别仅在于 URL 和消息。
输入请求(在 InputRequiredResult.inputRequests 中传递):
{
"method": "elicitation/create",
"params": {
"mode": "url",
"url": "https://mcp.example.com/ui/set_api_key",
"message": "Please provide your API key to continue."
}
}客户端结果(在重试请求的 inputResponses 中返回):
{
"action": "accept"
}包含 action: "accept" 的响应表示用户已同意此次交互,并不表示交互已经完成。交互在
带外进行,客户端不会直接获知结果。客户端重试原始请求时,服务器根据回显的
requestState(或自身存储的状态)判断带外交互是否完成,并返回最终结果或再次响应
InputRequiredResult。客户端 SHOULD 提供手动控件,让用户能够重试或取消原始请求
(或以其他方式恢复与客户端的交互)。
消息流
表单模式流程
sequenceDiagram
participant User
participant Client
participant Server
Client->>Server: tools/call(id: 1)
note over Server: Server needs more info
Server-->>Client: InputRequiredResult(elicitation/create (mode: form))
Note over User,Client: Present elicitation UI
User-->>Client: Provide requested information
Note over Server,Client: Retry request with new information
Client->>Server: tools/call(id: 2, user response)
Server-->>Client: Result(id: 2, result)
URL 模式流程
sequenceDiagram
participant UserAgent as User Agent (Browser)
participant User
participant Client
participant Server
Client->>Server: tools/call(id: 1)
Note over Server: Server needs more info <br/> Server creates requestState encoding url info.
Server-->>Client: InputRequiredResult(elicitation/create (mode: url), requestState)
Client->>User: Present consent to open URL
User-->>Client: Provide consent
Client->>UserAgent: Open URL
Client->>Server: tools/call(id: 2, Accept Response, requestState))
Note over Server: Server uses requestState to discover url info. <br/> It may need to block until the request is fulfilled.
Note over User,UserAgent: User interaction
UserAgent-->>Server: Interaction complete
Note over Server: Continue processing with new information
Server-->Client: Result(id: 2, result)
响应操作
信息征询响应采用三种操作的模型,以清楚区分不同的用户操作。这些操作同时适用于表单和 URL 信息征询模式。
{
"action": "accept", // or "decline" or "cancel"
"content": {
"propertyName": "value",
"anotherProperty": 42
}
}三种响应操作为:
接受(
action: "accept"):用户明确批准并提交了数据- 表单模式:
content字段包含与请求 schema 匹配的已提交数据 - URL 模式:省略
content字段 - 示例:用户点击“提交”“确定”“确认”等
- 表单模式:
拒绝(
action: "decline"):用户明确拒绝请求- 通常省略
content字段 - 示例:用户点击“拒绝”“不同意”“否”等
- 通常省略
取消(
action: "cancel"):用户未作出明确选择便关闭交互- 通常省略
content字段 - 示例:用户关闭对话框、点击对话框外部、按 Escape、浏览器加载失败等
- 通常省略
服务器应适当处理每种状态:
- 接受:处理提交的数据
- 拒绝:处理明确拒绝(例如提供替代方案)
- 取消:处理关闭操作(例如稍后再次提示)
实现注意事项
状态性
借助多次往返请求 机制, 信息征询不要求服务器维护用户状态。
但如果存储了状态,实现信息征询的服务器 MUST 按照安全最佳实践(英文) 中的指南,将该状态与单个用户安全关联。具体而言:
- 状态存储 MUST 防止未经授权的访问
- 对于远程 MCP 服务器,在可能的情况下,用户标识 MUST 派生自通过
MCP 授权
获取的凭据(例如
subclaim)
使用 URL 模式信息征询获取敏感数据
对于与需要敏感信息(例如凭据、支付信息)的外部 API 交互的服务器,URL 模式信息征询 提供了一种安全机制,使用户无需向 MCP 客户端公开信息即可提供这些信息。
在此模式中:
- 服务器将用户引导至通过 HTTPS 提供的安全网页
- 该页面在用户信任的域名上展示带有品牌标识的表单 UI
- 用户将敏感凭据直接输入安全表单
- 服务器安全存储凭据,并将其绑定到用户身份
- 后续 MCP 请求使用这些已存储凭据访问 API
这种方式确保敏感凭据绝不会经过 LLM 上下文、MCP 客户端或任何中间 MCP 服务器,从而 降低客户端日志记录或其他攻击途径导致凭据泄露的风险。
用于 OAuth 流程的 URL 模式信息征询
URL 模式信息征询支持一种由 MCP 服务器充当第三方资源服务器 OAuth 客户端的模式。 URL 模式信息征询实现的外部 API 授权与 MCP 授权 相互独立。 MCP 服务器 MUST NOT 依赖 URL 模式信息征询为用户授权其自身。
理解两者区别
- MCP 授权:MCP 客户端与 MCP 服务器之间必需的 OAuth 流程(参见 授权规范 )
- 外部(第三方)授权:MCP 服务器与第三方资源服务器之间通过 URL 模式信息征询 发起的可选授权
在外部授权中,服务器同时充当:
- 面向 MCP 客户端的 OAuth 资源服务器
- 面向第三方资源服务器的 OAuth 客户端
示例场景:
- MCP 客户端连接到 MCP 服务器
- MCP 服务器集成多个不同的第三方服务
- 当 MCP 客户端调用需要访问第三方服务的工具时,MCP 服务器需要该服务的凭据
关键安全要求为:
- 第三方凭据 MUST NOT 经过 MCP 客户端:客户端绝不能看到第三方凭据,以保护安全边界
- MCP 服务器 MUST NOT 将客户端凭据用于第三方服务:这将构成被禁止的 令牌透传(英文)
- 用户 MUST 直接授权 MCP 服务器:交互在 MCP 协议之外进行,不涉及 MCP 客户端
- MCP 服务器负责令牌:MCP 服务器负责存储和管理通过 URL 模式信息征询获得的第三方 令牌(换言之,MCP 服务器必须是有状态的)
通过 URL 模式信息征询获得的凭据与 MCP 客户端使用的 MCP 服务器凭据不同。MCP 服务器 MUST NOT 将通过 URL 模式信息征询获得的凭据传输给 MCP 客户端。
实现模式
通过 URL 模式信息征询实现外部授权时:
- MCP 服务器生成授权 URL,充当第三方服务的 OAuth 客户端
- MCP 服务器存储内部状态,将信息征询请求与用户身份关联(绑定)
- MCP 服务器向客户端发送 URL 模式信息征询请求,其中包含可启动授权流程的 URL,
以及可选的
requestState,用于编码信息征询请求和用户的相关信息(如有需要) - 用户直接通过第三方授权服务器完成 OAuth 流程
- 第三方授权服务器重定向回 MCP 服务器
- MCP 服务器安全存储第三方令牌,并将其绑定到用户身份
- 后续 MCP 请求可以利用这些已存储令牌访问第三方资源服务器 API
以下是此模式的一种非规范性实现示例:
sequenceDiagram
participant User
participant UserAgent as User Agent (Browser)
participant 3AS as 3rd Party AS
participant 3RS as 3rd Party RS
participant Client as MCP Client
participant Server as MCP Server
Client->>Server: tools/call
Note over Server: Needs 3rd-party authorization for user
Note over Server: Store state (bind the elicitation request to the user)
Note over Server: generate requestState that encodes information about the original request and user.
Server->>Client: InputRequiredResult<br/>(mode: "url", url: "https://mcp.example.com/connect?...", requestState)
Client->>User: Present consent to open URL
User->>Client: Provide consent
Client->>UserAgent: Open URL
Client->>Server: Accept response
UserAgent->>Server: Load connect route
Note over Server: Confirm: user is logged into MCP Server or MCP AS<br>Confirm: elicitation user matches session user
Server->>UserAgent: Redirect to third-party authorization endpoint
UserAgent->>3AS: Load authorize route
Note over 3AS,User: User interaction (OAuth flow):<br>User consents to scoped MCP Server access
3AS->>UserAgent: redirect to MCP Server's redirect_uri
UserAgent->>Server: load redirect_uri page
Note over Server: Confirm: redirect_uri belongs to MCP Server
Server->>3AS: Exchange authorization code for OAuth tokens
3AS->>Server: Grants tokens
Note over Server: Bind tokens to MCP user identity
Client->>Server: tools/call (ElicitResults, requestState)
Note over Server: Retrieve token bound to user identity
Server->>3RS: Call 3rd-party API
此模式在支持需要用户授权的丰富第三方服务集成时,仍能保持清晰的安全边界。
错误处理
服务器 SHOULD NOT 假定信息征询请求总会成功,并且 MUST 处理用户拒绝或取消 信息征询,以及客户端无法处理请求的情况。
安全注意事项
- 服务器 MUST 将信息征询请求绑定到客户端和用户身份
- 客户端 MUST 清楚表明哪个服务器正在请求信息
- 客户端 SHOULD 实施用户审批控制
- 客户端 SHOULD 允许用户随时拒绝信息征询请求
- 客户端 SHOULD 以清楚表明所请求信息及其原因的方式展示信息征询请求
安全处理 URL
请求信息征询的 MCP 服务器:
- MUST NOT 在 URL 信息征询请求发送给客户端的 URL 中包含最终用户的敏感信息, 包括凭据、个人身份信息等。
- MUST NOT 提供已预先通过身份验证、能够访问受保护资源的 URL,因为恶意客户端 可能利用该 URL 冒充用户。
- SHOULD NOT 在表单模式信息征询请求的任何字段中包含预期可点击的 URL。
- SHOULD 在非开发环境中使用 HTTPS URL。
这些服务器要求为客户端实现提供了明确规则,使其能够一致地应用下述客户端规则。
实现 URL 模式信息征询的客户端 MUST 谨慎处理 URL,防止用户在不知情的情况下点击 恶意链接。
处理 URL 模式信息征询请求时,MCP 客户端:
- MUST NOT 自动预取 URL 或其任何元数据。
- 未经用户明确同意,MUST NOT 打开 URL。
- MUST 在用户同意前向其显示完整 URL 以供检查。
- MUST 以安全方式打开服务器提供的 URL,且不得使客户端或 LLM 能够检查其内容或 用户输入。例如,在 iOS 上,SFSafariViewController 是合适的选择,而 WkWebView 不是。
- SHOULD 突出显示 URL 的域名,以降低子域名仿冒风险。
- SHOULD 针对存在歧义或可疑的 URI(例如包含 Punycode)发出警告。
- 除 URL 信息征询请求的
url字段外(并遵守上述限制),SHOULD NOT 将信息征询 请求任何字段中的 URL 渲染为可点击链接。
识别用户
服务器 MUST NOT 在未经服务器验证的情况下依赖客户端提供的用户标识,因为它可能 被伪造。服务器 SHOULD 遵循安全最佳实践(英文) 。
非规范性示例:
- 错误:将“我是 [email protected] ”之类的用户输入视为权威信息
- 正确:依靠授权 识别用户
表单模式安全
- 服务器 MUST NOT 通过表单模式请求敏感信息(密码、API 密钥等)
- 客户端 SHOULD 根据提供的 schema 验证所有响应
- 服务器 SHOULD 验证收到的数据是否与请求的 schema 匹配
网络钓鱼
URL 模式信息征询返回一个攻击者可以转发给受害者的 URL。MCP 服务器在接受信息前 MUST 验证打开 URL 的用户身份。
通常,身份验证会利用 MCP 授权服务器 通过浏览器中的会话 cookie 或等效机制识别用户。
例如,URL 模式信息征询可用于执行 OAuth 流程,其中服务器充当另一资源服务器的 OAuth 客户端。如果没有适当的缓解措施,可能发生以下网络钓鱼攻击:
- 连接到正常服务器的恶意用户(Alice)触发信息征询请求
- 正常服务器充当第三方授权服务器的 OAuth 客户端并生成授权 URL
- Alice 的客户端显示 URL 并请求同意
- Alice 没有点击链接,而是诱骗同一正常服务器的受害用户(Bob)点击该链接
- Bob 打开链接并完成授权,误以为是在授权自己与正常服务器的连接
- 正常服务器收到第三方授权服务器的回调/重定向,并假定它属于 Alice 的请求
- 第三方服务器令牌被绑定到 Alice 而非 Bob 的会话和身份,导致账户接管
为防止此攻击,服务器 MUST 确保发起信息征询请求的用户(通过 MCP 客户端访问服务器 的最终用户)与完成授权流程的用户是同一人。
实现此要求的方法有很多,最佳方式取决于具体实现。
以一种常见的非规范性示例为例:MCP 服务器可通过 Web 访问,并希望执行第三方授权码流程。
为防止网络钓鱼攻击,服务器会创建 URL 模式信息征询并指向
https://mcp.example.com/connect?...,而不是第三方授权端点。此“连接 URL”必须确保打开
页面的用户就是信息征询所针对的用户。例如,它可以检查用户是否具有有效会话 cookie,
并确认该 cookie 属于使用 MCP 客户端生成 URL 模式信息征询的同一用户。实现可以比较
MCP 服务器授权服务器提供的权威主体(sub claim)与会话 cookie 中的主体。页面确认
用户一致后,便可将用户发送到第三方授权服务器的 https://example.com/authorize?...,
在那里完成正常的 OAuth 流程。
在其他情况下,服务器可能无法通过 Web 访问,也可能无法使用会话 cookie 识别用户。 此时,服务器必须使用其他机制确认打开信息征询 URL 的用户就是信息征询所针对的用户。
在所有实现中,服务器 MUST 确保用于确定用户身份的机制能够抵御攻击者修改信息征询 URL 的攻击。