- 表单模式:服务器可以向用户请求结构化数据,并可选使用 JSON schema 来验证响应
- URL 模式:服务器可以将用户引导至外部 URL 进行敏感交互,此类交互必须 不能 通过 MCP 客户端传递
用户交互模型
MCP 中的询问功能允许服务器通过使用户输入请求嵌套在其他 MCP 服务器功能中,来实现交互式工作流。 实现可以自由通过任何适合其需求的接口模式来暴露询问功能——协议本身并不强制规定任何特定的用户交互模型。能力
支持引导获取(elicitation)的客户端 必须 在每个请求中的_meta.io.modelcontextprotocol/clientCapabilities 里声明 elicitation 能力:
form 模式:
elicitation 能力的客户端 必须 至少支持一种模式(form 或 url)。
服务器 不得 发送使用客户端不支持的模式的引导获取请求。
协议消息
询问请求
服务器在处理客户端请求期间,可以通过发送一个包含elicitation/create 请求的 InputRequiredResult 来向用户请求信息。
所有询问请求必须包含以下参数:
mode 参数指定询问的类型:
"form":通过带内的结构化数据收集,并可选进行模式校验。数据会暴露给客户端。"url":通过 URL 导航进行带外交互。数据(URL 本身除外)不会暴露给客户端。
mode 字段。客户端必须将没有 mode 字段的请求视为表单模式。
表单模式询问请求
表单模式询问允许服务器通过 MCP 客户端直接收集结构化数据。 表单模式询问请求必须指定mode: "form" 或省略 mode 字段,并包含以下附加参数:
请求的 Schema
requestedSchema 参数允许服务器使用 JSON Schema 的受限子集来定义预期响应的结构。
为简化客户端用户体验,表单模式询问的 schema 限制为仅包含原始属性的扁平对象。
该 schema 仅支持以下原始类型:
-
字符串 Schema
支持的格式:
email、uri、date、date-time -
数值 Schema
-
布尔 Schema
-
枚举 Schema
单选枚举(无标题):
单选枚举(带标题):多选枚举(无标题):多选枚举(带标题):
- 生成合适的输入表单
- 在发送前校验用户输入
- 为用户提供更好的引导
示例:简单文本请求
输入请求(在InputRequiredResult.inputRequests 中传递):
inputResponses 中):
示例:结构化数据请求
输入请求(在InputRequiredResult.inputRequests 中传递):
inputResponses 中):
URL 模式询问请求
新功能: URL 模式询问在 MCP 规范的
2025-11-25 版本中引入。其设计和实现可能会在未来的协议修订中发生变化。mode: "url"、message,并包含以下附加参数:
url 参数必须包含一个有效的 URL。
重要:URL 模式询问并不是用于授权 MCP 客户端访问 MCP 服务器(这由 MCP
authorization 负责)。相反,它用于当 MCP 服务器需要代表用户获取敏感信息或第三方授权时。MCP 客户端的 bearer token 保持不变。客户端唯一的职责是向用户提供关于服务器希望其打开的询问 URL 的上下文说明。
示例:请求敏感数据
此示例展示了一个 URL 模式询问请求,它将用户引导至一个安全 URL,以便用户提供敏感信息(例如 API 密钥)。 同一个请求也可以将用户引导至 OAuth 授权流程或支付流程。唯一的区别是 URL 和消息。 输入请求(在InputRequiredResult.inputRequests 中传递):
inputResponses 中):
action: "accept" 的响应表示用户已同意进行交互。这并不意味着交互已经完成。交互发生在带外,客户端不会直接获知其结果。当客户端重试原始请求时,服务器会根据回显的 requestState(或其自身保存的状态)确定带外交互是否已完成,并返回最终结果或再次响应一个 InputRequiredResult。客户端应当提供手动控制,让用户重试或取消原始请求(或以其他方式恢复与客户端的交互)。
消息流
表单模式流程
URL 模式流程
响应动作
诱导响应使用三动作模型,以清晰区分不同的用户操作。这些动作同时适用于表单和 URL 诱导模式。-
接受(
action: "accept"):用户明确批准并提交了数据- 对于表单模式:
content字段包含与所请求 schema 匹配的已提交数据 - 对于 URL 模式:省略
content字段 - 示例:用户点击“提交”、“确定”、“确认”等
- 对于表单模式:
-
拒绝(
action: "decline"):用户明确拒绝了请求- 通常省略
content字段 - 示例:用户点击“拒绝”、“否”等
- 通常省略
-
取消(
action: "cancel"):用户未作出明确选择就关闭了- 通常省略
content字段 - 示例:用户关闭对话框、点击外部区域、按下 Escape、浏览器加载失败等
- 通常省略
- 接受:处理已提交的数据
- 拒绝:处理明确拒绝(例如,提供替代方案)
- 取消:处理关闭(例如,稍后再次提示)
实现考虑事项
状态性
通过 多轮往返请求 机制,Elicitation 不要求服务器维护关于用户的状态。 然而,如果存储了状态,实现 elicitation 的服务器 MUST 按照 安全最佳实践 文档中的指南,将该状态与单个用户安全地关联。具体来说:- 状态存储 MUST 受到防止未授权访问的保护
- 对于远程 MCP 服务器,在可能的情况下,用户标识 MUST 从通过 MCP 授权 获取的凭据中派生(例如
sub声明)
本节中的示例不具规范性,仅用于说明 elicitation 的潜在用途。
实现者应根据其具体需求调整这些模式,同时保持安全最佳实践。
敏感数据的 URL 模式 Elicitation
对于需要敏感信息(例如凭据、支付信息)并与外部 API 交互的服务器,URL 模式 elicitation 为用户提供此类信息提供了一种安全机制,而不会将其暴露给 MCP 客户端。 在这种模式下:- 服务器将用户引导到一个安全网页(通过 HTTPS 提供)
- 该页面在用户信任的域名上呈现一个品牌化表单 UI
- 用户直接在安全表单中输入敏感凭据
- 服务器安全地存储凭据,并与用户身份绑定
- 后续的 MCP 请求使用这些已存储的凭据进行 API 访问
OAuth 流程的 URL 模式 Elicitation
URL 模式 elicitation 支持一种模式,其中 MCP 服务器作为 OAuth 客户端与第三方资源服务器交互。 通过 URL 模式 elicitation 启用的外部 API 授权,与 MCP 授权 是分开的。MCP 服务器 MUST NOT 依赖 URL 模式 elicitation 来为其自身授权用户。理解这种区别
- MCP 授权:MCP 客户端与 MCP 服务器之间所需的 OAuth 流程(见 授权规范)
- 外部(第三方)授权:MCP 服务器与第三方资源服务器之间的可选授权,通过 URL 模式 elicitation 发起
- OAuth 资源服务器(面向 MCP 客户端)
- OAuth 客户端(面向第三方资源服务器)
- 一个 MCP 客户端连接到一个 MCP 服务器
- 该 MCP 服务器集成了各种不同的第三方服务
- 当 MCP 客户端调用一个需要访问第三方服务的工具时,MCP 服务器需要该服务的凭据
- 第三方凭据 MUST NOT 经过 MCP 客户端传输:客户端绝不能看到第三方凭据,以保护安全边界
- MCP 服务器 MUST NOT 将客户端的凭据用于第三方服务:那将属于 token 透传,这是被禁止的
- 用户 MUST 直接授权 MCP 服务器:交互发生在 MCP 协议之外,不涉及 MCP 客户端
- MCP 服务器负责令牌:MCP 服务器负责存储和管理通过 URL 模式 elicitation 获取的第三方令牌(换句话说,MCP 服务器必须具有状态性)。
有关更多背景,请参阅安全最佳实践文档中的 token 透传
部分,以了解为什么 MCP 服务器不能
充当透传代理。
实现模式
通过 URL 模式 elicitation 实现外部授权时:- MCP 服务器生成一个授权 URL,作为第三方服务的 OAuth 客户端
- MCP 服务器存储内部状态,将 elicitation 请求与用户身份关联(绑定)
- MCP 服务器向客户端发送一个 URL 模式 elicitation 请求,其中包含可启动授权流程的 URL,以及可选的
requestState,用于编码关于 elicitation 请求和用户的信息(如需要) - 用户直接与第三方授权服务器完成 OAuth 流程
- 第三方授权服务器重定向回 MCP 服务器
- MCP 服务器安全地存储第三方令牌,并与用户身份绑定
- 未来的 MCP 请求可以利用这些已存储的令牌访问第三方资源服务器的 API
错误处理
服务器不应假定征询请求总是会成功,并且必须处理用户拒绝或取消征询,或客户端未能处理请求的情况。安全注意事项
- 服务器 MUST 将询问请求绑定到客户端和用户身份
- 客户端 MUST 清楚指示是哪台服务器正在请求信息
- 客户端 SHOULD 实现用户批准控制
- 客户端 SHOULD 允许用户随时拒绝询问请求
- 客户端 SHOULD 以清楚显示所请求信息及其原因的方式呈现询问请求
安全的 URL 处理
请求询问的 MCP 服务器:- MUST NOT 在发送给客户端的 URL 询问请求中的 URL 里包含关于最终用户的敏感信息,包括凭据、个人可识别信息等。
- MUST NOT 提供一个预先认证、可用于访问受保护资源的 URL,因为恶意客户端可能会利用该 URL 冒充用户。
- SHOULD NOT 在表单模式询问请求的任何字段中包含意图可点击的 URL。
- SHOULD 在非开发环境中使用 HTTPS URL。
- MUST NOT 自动预取 URL 或其任何元数据。
- MUST NOT 未经用户明确同意就打开 URL。
- MUST 在同意之前向用户完整展示 URL 以供检查。
- MUST 以安全方式打开服务器提供的 URL,且不能让客户端或 LLM 检查内容或用户输入。 例如,在 iOS 上,SFSafariViewController 是合适的,但 WkWebView 不是。
- SHOULD 高亮显示 URL 的域名,以减轻子域名欺骗。
- SHOULD 对模糊/可疑的 URI(即包含 Punycode 的 URI)发出警告。
- SHOULD NOT 将询问请求中的任何字段渲染为可点击链接,URL 询问请求中的
url字段除外(并受上述限制约束)。
用户身份识别
服务器 MUST NOT 在未经服务器验证的情况下依赖客户端提供的用户身份信息,因为这可以被伪造。 相反,服务器 SHOULD 遵循 安全最佳实践。 非规范性示例:- 错误:将“I am [email protected]”这样的用户输入视为权威信息
- 正确:依赖 授权 来识别用户
表单模式安全
- 服务器 MUST NOT 通过表单模式请求敏感信息(密码、API 密钥等)
- 客户端 SHOULD 根据提供的 schema 验证所有响应
- 服务器 SHOULD 验证接收的数据是否与请求的 schema 匹配
网络钓鱼
URL 模式询问会返回一个攻击者可用于发送给受害者的 URL。MCP 服务器 MUST 在接受信息之前验证打开该 URL 的用户身份。 通常,身份验证是通过利用 MCP 授权服务器 来识别用户,并在浏览器中通过会话 cookie 或等效机制完成的。 例如,URL 模式询问可用于执行 OAuth 流程,其中服务器充当另一个资源服务器的 OAuth 客户端。若无适当缓解,可能发生如下钓鱼攻击:- 连接到良性服务器的恶意用户(Alice)触发了一次询问请求
- 良性服务器生成一个授权 URL,作为第三方授权服务器的 OAuth 客户端
- Alice 的客户端显示该 URL 并请求同意
- Alice 没有点击链接,而是诱使同一良性服务器上的受害用户(Bob)点击该链接
- Bob 打开链接并完成授权,认为自己是在为与良性服务器的连接授权
- 良性服务器收到来自第三方授权服务器的回调/重定向,并将其视为 Alice 的请求
- 第三方服务器的令牌被绑定到 Alice 的会话和身份,而不是 Bob 的,从而导致账户接管
https://mcp.example.com/connect?...,而不是第三方授权端点。
这个“connect URL”必须确保打开页面的用户与生成该询问的用户是同一人。
例如,它会检查用户是否拥有有效的会话 cookie,以及该会话 cookie 是否属于用于生成 URL 模式询问的同一用户。
这可以通过将 MCP 服务器授权服务器中的权威主体(sub claim)与会话 cookie 中的主体进行比较来完成。
一旦该页面确认是同一用户,它就可以将用户发送到第三方授权服务器 https://example.com/authorize?...,在那里完成正常的 OAuth 流程。
在其他情况下,服务器可能无法通过 Web 访问,也可能无法使用会话 cookie 来识别用户。
在这种情况下,服务器必须使用不同的机制来识别打开询问 URL 的用户与生成该询问时的用户是同一人。
在所有实现中,服务器 MUST 确保用于确定用户身份的机制能够抵御攻击者修改询问 URL 的攻击。