跳到主要内容
协议修订: 2025-11-25
模型上下文协议 (MCP) 提供了一种标准化方式,让服务器在交互过程中通过客户端向用户请求额外信息。这种流程允许客户端保持对用户交互和数据共享的控制,同时使服务器能够动态收集必要的信息。 信息引导支持两种模式:
  • 表单模式 (Form mode):服务器可以向用户请求结构化数据,并使用可选的 JSON 架构来验证响应。
  • URL 模式 (URL mode):服务器可以将用户引导至外部 URL 进行敏感交互,这些交互不得通过 MCP 客户端。

用户交互模型

MCP 中的信息引导允许服务器通过在其他 MCP 服务器功能中嵌套用户输入请求来实现交互式工作流。 具体实现可以通过任何符合其需求的界面模式来公开引导功能——协议本身并不强制要求任何特定的用户交互模型。
关于信任、安全与保障
  • 服务器绝不能 (MUST NOT) 使用表单模式引导来请求敏感信息。
  • 对于涉及敏感信息(如凭据)的交互,服务器必须 (MUST) 使用 URL 模式。
MCP 客户端必须 (MUST)
  • 提供 UI 明确指示是哪个服务器在请求信息。
  • 尊重用户隐私,并提供清晰的拒绝和取消选项。
  • 对于表单模式,允许用户在发送前查看和修改其响应。
  • 对于 URL 模式,清晰显示目标域名/主机,并在导航至目标 URL 前征得用户同意。

功能

支持信息引导的客户端必须 (MUST)初始化 期间声明 elicitation 能力。
{
  "capabilities": {
    "elicitation": {
      "form": {},
      "url": {}
    }
  }
}
为了向后兼容,空的 capabilities 对象等同于声明仅支持 form 模式。
{
  "capabilities": {
    "elicitation": {}, // Equivalent to { "form": {} }
  },
}
声明了 elicitation 能力的客户端必须 (MUST) 至少支持一种模式(formurl)。 服务器绝不能 (MUST NOT) 发送客户端不支持模式的引导请求。

协议消息

信息引导请求

为了向用户请求信息,服务器发送 elicitation/create 请求。 所有引导请求必须 (MUST) 包含以下参数:
名称类型选项描述
modestringform, url引导的模式。表单模式下为可选(若省略则默认为 "form")。
messagestring解释为什么需要该交互的人类可读消息。
mode 参数指定了引导的类型
  • "form":带内 (In-band) 结构化数据收集,具有可选的架构验证。数据对客户端可见。
  • "url":通过 URL 导航进行的带外 (Out-of-band) 交互。除了 URL 本身以外的数据不会暴露给客户端。
为了向后兼容,服务器可以 (MAY) 在表单模式引导请求中省略 mode 字段。客户端必须 (MUST) 将没有 mode 字段的请求视为表单模式。

表单模式引导请求

表单模式引导允许服务器直接通过 MCP 客户端收集结构化数据。 表单模式引导请求必须 (MUST) 指定 mode: "form" 或省略 mode 字段,并包含以下额外参数:
名称类型描述
requestedSchemaobject定义预期响应结构的 JSON Schema。

请求的架构 (Schema)

requestedSchema 参数允许服务器使用 JSON Schema 的受限子集来定义预期响应的结构。 为了简化客户端用户体验,表单模式引导的架构仅限于仅包含基元属性的扁平对象。 架构受限于以下基元类型:
  1. 字符串架构 (String Schema)
    {
      "type": "string",
      "title": "Display Name",
      "description": "Description text",
      "minLength": 3,
      "maxLength": 50,
      "pattern": "^[A-Za-z]+$",
      "format": "email",
      "default": "[email protected]"
    }
    
    支持的格式:email, uri, date, date-time
  2. 数字架构 (Number Schema)
    {
      "type": "number", // or "integer"
      "title": "Display Name",
      "description": "Description text",
      "minimum": 0,
      "maximum": 100,
      "default": 50
    }
    
  3. 布尔架构 (Boolean Schema)
    {
      "type": "boolean",
      "title": "Display Name",
      "description": "Description text",
      "default": false
    }
    
  4. 枚举架构 (Enum 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"]
    }
    
客户端可以使用此架构来:
  1. 生成适当的输入表单
  2. 在发送前验证用户输入
  3. 为用户提供更好的引导
所有基元类型都支持可选的默认值,以提供合理的起点。支持默认值的客户端应当 (SHOULD) 使用这些值预填充表单字段。 请注意,为了简化客户端用户体验,有意不支持复杂的嵌套结构、对象数组(枚举除外)以及其他高级 JSON Schema 特性。

示例:简单文本请求

请求
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "elicitation/create",
  "params": {
    "mode": "form",
    "message": "Please provide your GitHub username",
    "requestedSchema": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        }
      },
      "required": ["name"]
    }
  }
}
响应
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "action": "accept",
    "content": {
      "name": "octocat"
    }
  }
}

示例:结构化数据请求

请求
{
  "jsonrpc": "2.0",
  "id": 2,
  "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"]
    }
  }
}
响应
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "action": "accept",
    "content": {
      "name": "Monalisa Octocat",
      "email": "[email protected]",
      "age": 30
    }
  }
}

URL 模式引导请求

新特性: URL 模式引导是在 MCP 规范的 2025-11-25 版本中引入的。其设计和实现在未来的协议修订中可能会发生变化。
URL 模式引导使服务器能够将用户引导至外部 URL,以便进行不得通过 MCP 客户端的带外交互。这对于身份验证流程、支付处理以及其他敏感或安全操作至关重要。 URL 模式引导请求必须 (MUST) 指定 mode: "url"、一个 message,并包含以下额外参数:
名称类型描述
urlstring用户应当导航至的 URL。
elicitationIdstring该引导请求的唯一标识符。
url 参数必须 (MUST) 包含一个有效的 URL。
重要提示:URL 模式引导不是为了授权 MCP 客户端访问 MCP 服务器(这由 MCP 授权 处理)。相反,它用于 MCP 服务器代表用户获取敏感信息或第三方授权的情况。MCP 客户端的承载令牌 (bearer token) 保持不变。客户端唯一的责任是向用户提供有关服务器希望其打开的引导 URL 的上下文。

示例:请求敏感数据

此示例显示了一个 URL 模式引导请求,该请求将用户引导至一个安全的 URL,用户可以在该 URL 中提供敏感信息(例如 API 密钥)。同样的请求也可以将用户引导至 OAuth 授权流程或支付流程。唯一的区别在于 URL 和消息内容。 请求:
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "elicitation/create",
  "params": {
    "mode": "url",
    "elicitationId": "550e8400-e29b-41d4-a716-446655440000",
    "url": "https://mcp.example.com/ui/set_api_key",
    "message": "Please provide your API key to continue."
  }
}
响应
{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "action": "accept"
  }
}
带有 action: "accept" 的响应表示用户已同意该交互。这并不意味着交互已完成。交互发生在带外,除非服务器发送指示完成的通知,否则客户端不会知晓结果。

URL 模式引导的完成通知

当由 URL 模式引导启动的带外交互完成时,服务器可以 (MAY) 发送 notifications/elicitation/complete 通知。这允许客户端在适当的情况下做出程序化反应。 发送通知的服务器:
  • 必须 (MUST) 仅向发起引导请求的客户端发送通知。
  • 必须 (MUST) 包含在原始 elicitation/create 请求中建立的 elicitationId
客户端 (Clients)
  • 必须 (MUST) 忽略引用未知或已完成 ID 的通知。
  • 可以 (MAY) 等待此通知,以自动重试之前收到 URLElicitationRequiredError 的请求、更新用户界面或以其他方式继续交互。
  • 如果通知未送达,应当 (SHOULD) 仍然提供手动控制项,让用户能够重试或取消原始请求(或以其他方式恢复与客户端的交互)。

示例

{
  "jsonrpc": "2.0",
  "method": "notifications/elicitation/complete",
  "params": {
    "elicitationId": "550e8400-e29b-41d4-a716-446655440000"
  }
}

需要 URL 引导错误 (URL Elicitation Required Error)

当请求在引导完成前无法处理时,服务器可以 (MAY) 返回 URLElicitationRequiredError (代码 -32042),向客户端指示需要进行 URL 模式引导。除非确实需要 URL 模式引导,否则服务器绝不能 (MUST NOT) 返回此错误。 该错误必须 (MUST) 包含在重试原始请求前必须完成的引导列表。 错误中返回的任何引导项必须 (MUST) 是 URL 模式引导,并且具有 elicitationId 属性。 错误响应:
{
  "jsonrpc": "2.0",
  "id": 2,
  "error": {
    "code": -32042, // URL_ELICITATION_REQUIRED
    "message": "This request requires more information.",
    "data": {
      "elicitations": [
        {
          "mode": "url",
          "elicitationId": "550e8400-e29b-41d4-a716-446655440000",
          "url": "https://mcp.example.com/connect?elicitationId=550e8400-e29b-41d4-a716-446655440000",
          "message": "Authorization is required to access your Example Co files."
        }
      ]
    }
  }
}

消息流

表单模式流程

URL 模式流程

带有“需要 URL 引导错误”的 URL 模式流程

响应操作

引导响应使用“三动作模型”来明确区分不同的用户操作。这些动作适用于表单和 URL 引导模式。
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "action": "accept", // or "decline" or "cancel"
    "content": {
      "propertyName": "value",
      "anotherProperty": 42
    }
  }
}
三个响应动作分别是:
  1. 接受 (Accept) (action: "accept"):用户显式批准并提交了数据。
    • 对于表单模式:content 字段包含与请求架构匹配的提交数据。
    • 对于 URL 模式:省略 content 字段。
    • 示例:用户点击了“提交”、“确定”、“确认”等。
  2. 拒绝 (Decline) (action: "decline"):用户显式拒绝了请求。
    • 通常省略 content 字段。
    • 示例:用户点击了“拒绝”、“拒绝接受”、“否”等。
  3. 取消 (Cancel) (action: "cancel"):用户在未做出明确选择的情况下关闭了请求。
    • 通常省略 content 字段。
    • 示例:用户关闭了对话框、点击了外部区域、按下了 Esc 键、浏览器加载失败等。
服务器应妥善处理每种状态:
  • 接受:处理提交的数据。
  • 拒绝:处理显式拒绝(例如,提供替代方案)。
  • 取消:处理关闭操作(例如,稍后再次提示)。

实现注意事项

状态性 (Statefulness)

信息引导的大多数实际用途都要求服务器维护有关用户的状态:
  • 是否已收集所需信息(例如,通过表单模式引导获取用户的显示名称)。
  • 资源访问的状态(例如,通过 URL 模式引导获取 API 密钥或支付流程)。
实施信息引导的服务器必须 (MUST) 遵循 安全最佳实践 文档中的指南,将此状态与个人用户安全地关联。具体而言:
  • 状态绝不能 (MUST NOT) 仅与会话 ID 关联。
  • 状态存储必须 (MUST) 受到保护,防止未经授权的访问。
  • 对于远程 MCP 服务器,在可能的情况下,用户标识必须 (MUST) 源自通过 MCP 授权 获取的凭据(例如 sub 声明)。
本节中的示例是非规范性的,旨在说明信息引导的潜在用途。实施者应在保持安全最佳实践的同时,根据其特定需求调整这些模式。

敏感数据的 URL 模式引导

对于与需要敏感信息(如凭据、支付信息)的外部 API 交互的服务器,URL 模式引导提供了一种安全机制,让用户提供这些信息而不会将其暴露给 MCP 客户端。 在这种模式中:
  1. 服务器将用户引导至一个安全的网页(通过 HTTPS 提供)。
  2. 该页面在用户信任的域上呈现品牌化的表单 UI。
  3. 用户直接将敏感凭据输入安全表单。
  4. 服务器安全地存储凭据,并将其与用户的身份绑定。
  5. 后续的 MCP 请求使用这些存储的凭据进行 API 访问。
这种方法确保了敏感凭据绝不会经过 LLM 上下文、MCP 客户端或任何中间 MCP 服务器,从而降低了通过客户端日志或其他攻击向量泄露的风险。

OAuth 流程的 URL 模式引导

URL 模式引导使得 MCP 服务器可以作为第三方资源服务器的 OAuth 客户端。通过 URL 模式引导启用的与外部 API 的授权与 MCP 授权 是分开的。MCP 服务器绝不能 (MUST NOT) 依赖 URL 模式引导来对自己进行用户授权。

理解区别

  • MCP 授权:MCP 客户端与 MCP 服务器之间所需的 OAuth 流程(在 授权规范 中涵盖)。
  • 外部(第三方)授权:MCP 服务器与第三方资源服务器之间可选的授权,通过 URL 模式引导启动。
在外部授权中,服务器同时充当:
  • OAuth 资源服务器(对 MCP 客户端而言)。
  • OAuth 客户端(对第三方资源服务器而言)。
示例场景:
  • MCP 客户端连接到 MCP 服务器。
  • MCP 服务器集成了各种不同的第三方服务。
  • 当 MCP 客户端调用一个需要访问第三方服务的工具时,MCP 服务器需要该服务的凭据。
关键的安全要求是:
  1. 第三方凭据绝不能 (MUST NOT) 经过 MCP 客户端:客户端绝不能看到第三方凭据,以保护安全边界。
  2. MCP 服务器绝不能 (MUST NOT) 将客户端的凭据用于第三方服务:这将构成 令牌透传 (token passthrough),这是被禁止的。
  3. 用户必须 (MUST) 直接授权 MCP 服务器:交互发生在 MCP 协议之外,不涉及 MCP 客户端。
  4. MCP 服务器负责令牌:MCP 服务器负责存储和管理通过 URL 模式引导获得的第三方令牌(换句话说,MCP 服务器必须是有状态的)。
通过 URL 模式引导获得的凭据与 MCP 客户端使用的 MCP 服务器凭据是不同的。MCP 服务器绝不能 (MUST NOT) 将通过 URL 模式引导获得的凭据传输给 MCP 客户端。
有关更多背景信息,请参阅安全最佳实践文档的 令牌透传部分,以了解为什么 MCP 服务器不能充当透传代理。

实现模式

当通过 URL 模式引导实施外部授权时:
  1. MCP 服务器生成授权 URL,作为第三方服务的 OAuth 客户端。
  2. MCP 服务器存储内部状态,将引导请求与用户的身份关联(绑定)。
  3. MCP 服务器向客户端发送 URL 模式引导请求,其中包含可以启动授权流程的 URL。
  4. 用户直接与第三方授权服务器完成 OAuth 流程。
  5. 第三方授权服务器重定向回 MCP 服务器。
  6. MCP 服务器安全地存储第三方令牌,并与用户的身份绑定。
  7. 未来的 MCP 请求可以利用这些存储的令牌访问第三方资源服务器的 API。
以下是关于此模式如何实现的一个非规范性示例: 此模式在维持清晰安全边界的同时,实现了与需要用户授权的第三方服务的丰富集成。

错误处理

服务器在常见故障情况下必须 (MUST) 返回标准 JSON-RPC 错误:
  • 当请求在引导完成前无法处理时:-32042 (URLElicitationRequiredError)。
客户端在常见故障情况下必须 (MUST) 返回标准 JSON-RPC 错误:
  • 服务器发送了客户端能力中未声明模式的 elicitation/create 请求:-32602 (Invalid params)。

安全注意事项

  1. 服务器必须 (MUST) 将引导请求与客户端及用户身份绑定。
  2. 客户端必须 (MUST) 明确指示是哪个服务器在请求信息。
  3. 客户端应当 (SHOULD) 实施用户批准控制项。
  4. 客户端应当 (SHOULD) 允许用户随时拒绝引导请求。
  5. 客户端应当 (SHOULD) 实施速率限制。
  6. 客户端应当 (SHOULD) 以一种能清晰说明正在请求什么信息以及原因的方式呈现引导请求。

安全的 URL 处理

请求信息引导的 MCP 服务器:
  1. 绝不能 (MUST NOT) 在发送给客户端的 URL 引导请求的 URL 中包含有关最终用户的敏感信息,包括凭据、个人身份信息等。
  2. 绝不能 (MUST NOT) 提供已预先验证可访问受保护资源的 URL,因为该 URL 可能会被恶意客户端用来冒充用户。
  3. 在表单模式引导请求的任何字段中,不应当 (SHOULD NOT) 包含旨在可点击的 URL。
  4. 对于非开发环境,应当 (SHOULD) 使用 HTTPS URL。
这些服务器要求确保了客户端实现对于何时向用户呈现 URL 有明确的规则,以便能够一致地应用客户端规则(见下文)。 实施 URL 模式引导的客户端必须 (MUST) 谨慎处理 URL,以防止用户在不知情的情况下点击恶意链接。 在处理 URL 模式引导请求时,MCP 客户端:
  1. 绝不能 (MUST NOT) 自动预取 URL 或其任何元数据。
  2. 未经用户明确同意,绝不能 (MUST NOT) 打开该 URL。
  3. 必须 (MUST) 在征得同意前向用户显示完整的 URL 以供检查。
  4. 必须 (MUST) 以安全的方式打开服务器提供的 URL,使客户端或 LLM 无法检查其内容或用户输入。例如,在 iOS 上,SFSafariViewController 是合适的,但 WkWebView 不合适。
  5. 应当 (SHOULD) 突出显示 URL 的域名,以减轻子域名欺骗风险。
  6. 对于歧义/可疑的 URI(即包含 Punycode 的 URI),应当 (SHOULD) 发出警告。
  7. 除了 URL 引导请求中的 url 字段(具有上述限制)外,不应当 (SHOULD NOT) 将引导请求任何字段中的 URL 渲染为可点击状态。

标识用户

服务器绝不能 (MUST NOT) 在未经服务器验证的情况下依赖客户端提供的用户标识,因为这可能会被伪造。相反,服务器应当 (SHOULD) 遵循 安全最佳实践 非规范性示例:
  • 错误:将用户输入(如“我是 [email protected]”)视为权威标识。
  • 正确:依靠 授权 来识别用户。

表单模式安全

  1. 服务器绝不能 (MUST NOT) 通过表单模式请求敏感信息(密码、API 密钥等)。
  2. 客户端应当 (SHOULD) 根据提供的架构验证所有响应。
  3. 服务器应当 (SHOULD) 验证接收到的数据是否符合请求的架构。

网络钓鱼 (Phishing)

URL 模式引导会返回一个 URL,攻击者可能会利用该 URL 发送给受害者。MCP 服务器在接受信息之前,必须 (MUST) 验证打开该 URL 的用户身份。 通常,身份验证是通过利用 MCP 授权服务器,通过浏览器中的会话 Cookie 或等效机制来识别用户的。 例如,URL 模式引导可用于执行 OAuth 流程,其中服务器充当另一个资源服务器的 OAuth 客户端。如果没有适当的缓解措施,可能会发生以下钓鱼攻击:
  1. 连接到合法服务器的恶意用户 (Alice) 触发了一个引导请求。
  2. 合法服务器生成了一个授权 URL,作为第三方授权服务器的 OAuth 客户端。
  3. Alice 的客户端显示该 URL 并请求同意。
  4. Alice 并没有点击链接,而是诱导同一合法服务器的受害用户 (Bob) 点击它。
  5. Bob 打开链接并完成了授权,以为是在授权自己与该合法服务器的连接。
  6. 合法服务器收到了来自第三方授权服务器的回调/重定向,并认为这是 Alice 的请求。
  7. 访问第三方服务器的令牌被绑定到了 Alice 的会话和身份上,而不是 Bob 的,从而导致账号被接管。
为了防止这种攻击,服务器必须 (MUST) 确保启动引导请求的用户(即通过 MCP 客户端访问服务器的终端用户)与完成授权流程的用户是同一个人。 实现这一点有多种方法,最佳方式取决于具体的实现。 作为一个常见的非规范性示例,假设 MCP 服务器可以通过 Web 访问,并希望执行第三方授权码流程。为了防止钓鱼攻击,服务器应创建一个指向 https://mcp.example.com/connect?elicitationId=... 的 URL 模式引导,而不是直接指向第三方授权端点。这个“连接 URL”必须确保打开页面的用户就是该引导请求为其生成的用户。例如,它可以检查用户是否拥有有效的会话 Cookie,且该会话 Cookie 属于生成该 URL 模式引导的同一个 MCP 客户端用户。这可以通过将来自 MCP 服务器授权服务器的权威主体(sub 声明)与来自会话 Cookie 的主体进行比较来实现。一旦页面确保是同一用户,它就可以将用户发送到第三方授权服务器 https://example.com/authorize?... 完成正常的 OAuth 流程。 在其他情况下,如果服务器无法通过 Web 访问或无法使用会话 Cookie 识别用户,则必须使用不同的机制来识别打开引导 URL 的用户与生成引导的用户是一致的。 在所有实现中,服务器必须 (MUST) 确保确定用户身份的机制能够抵御攻击者修改引导 URL 的攻击。