Skip to main content

引言

目的和范围

模型上下文协议在传输层提供授权能力,使 MCP 客户端能够代表资源所有者向受限的 MCP 服务器发起请求。本规范定义了基于 HTTP 的传输方式的授权流程。

协议要求

对于 MCP 实现,授权是可选的。若支持:
  • 使用基于 HTTP 的传输的实现应当符合本规范。
  • 使用 STDIO 传输的实现不应遵循本规范,而应改为从环境中获取凭据。
  • 使用其他传输方式的实现必须遵循其协议既定的安全最佳实践。

标准符合性

此授权机制基于下列已建立的规范,但仅实现了其功能的一个选定子集,以在保持简洁性的同时确保安全性和互操作性:

角色

受保护的 MCP 服务器 充当 OAuth 2.1 资源服务器,能够使用访问令牌接收并响应受保护资源请求。 MCP 客户端 充当 OAuth 2.1 客户端,代表资源所有者发起受保护资源请求。 授权服务器 负责在必要时与用户交互,并签发供 MCP 服务器使用的访问令牌。 授权服务器的实现细节不在本规范的范围内。它可以与资源服务器托管在一起,也可以是独立实体。授权服务器发现 规定了 MCP 服务器如何向客户端指示其对应授权服务器的位置。

概览

  1. 授权服务器 MUST 实现 OAuth 2.1,并为机密客户端和公有客户端采取适当的安全措施。
  2. 授权服务器和 MCP 客户端 SHOULD 支持 OAuth 客户端 ID 元数据文档 (draft-ietf-oauth-client-id-metadata-document-00)。
  3. 授权服务器和 MCP 客户端 MAY 支持 OAuth 2.0 动态客户端注册协议 (RFC7591)。请注意, 动态客户端注册 已废弃,仅为与不支持客户端 ID 元数据文档的授权服务器向后兼容而保留。
  4. MCP 服务器 MUST 实现 OAuth 2.0 受保护资源元数据 (RFC9728)。 MCP 客户端 MUST 使用 OAuth 2.0 受保护资源元数据进行 授权服务器发现
  5. MCP 授权服务器 MUST 至少提供以下发现机制之一: MCP 客户端 MUST 支持这两种 发现机制,以获取与授权服务器交互所需的信息。

授权服务器发现

MCP 服务器通过 OAuth 2.0 受保护资源元数据声明其关联的授权服务器,MCP 客户端则通过授权服务器元数据发现来确定授权服务器端点和受支持的能力。实现 必须 遵循 授权服务器发现 中定义的规范性发现要求。

客户端注册

在启动授权流程之前,MCP 客户端 必须 通过以下三种注册机制之一获取客户端 ID:客户端 ID 元数据文档、预注册或动态客户端注册,并遵循 客户端注册 中定义的要求和选择优先级。

作用域选择策略

MCP 服务器 应当WWW-Authenticate 头中包含 scope 参数,如 RFC 6750 第 3 节 所定义,以指明访问该资源所需的作用域。这为客户端在授权过程中请求合适的作用域提供了即时指导, 遵循最小权限原则,并防止客户端请求过多权限。 WWW-Authenticate 挑战中包含的作用域 可以scopes_supported 相匹配,或是其子集 或超集,或者是既非严格子集也非严格超集的另一组作用域。客户端 不得 假定挑战中的 作用域集合与 scopes_supported 之间存在任何特定的集合关系。客户端 必须 将挑战中提供的作用域视为当前操作的权威依据。这些作用域是满足当前请求所必需的。 在重新授权时,客户端 应当 将这些作用域与之前已授予的任何作用域一并包含在内,以避免丢失其他操作所需的权限 (参见 逐步提升授权流程)。服务器 应当 尽量保持其构建作用域集合方式的一致性,但不要求通过 scopes_supported 公开每一个动态发放的作用域。 带有作用域指引的 401 响应示例:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource",
                         scope="files:read"
在实现授权流程时,MCP 客户端 应当 遵循最小权限原则,仅请求其预期操作所必需的作用域。在初始授权握手期间,MCP 客户端 应当 按照以下优先级顺序选择作用域:
  1. 使用 初始 WWW-Authenticate 头中的 scope 参数(如果提供)
  2. 如果 scope 不可用,则使用受保护资源元数据文档中 scopes_supported 定义的所有作用域;如果未定义 scopes_supported,则省略 scope 参数。
这种方法兼顾了 MCP 客户端通用性的特点,因为它们通常缺乏针对单个作用域做出明智决策的领域知识。请求所有可用作用域可以让授权服务器和终端用户在同意过程中决定合适的权限。 这种方法在遵循最小权限原则的同时,尽量减少用户操作阻力。 scopes_supported 字段旨在表示基本功能所需的最小作用域集合 (参见 作用域最小化), 而额外的作用域则通过 作用域挑战处理 部分所述的逐步提升授权流程步骤逐步请求。

授权流程步骤

流程中显示的注册步骤使用了客户端注册中定义的一种机制。 完整的授权流程如下:

授权响应验证

在重定向用户代理之前,客户端 MUST 记录所选授权服务器已验证元数据文档中的 issuer 值(参见授权服务器元数据发现),并将其关联到用于存储 PKCE code verifier(以及 state 值,如果使用了的话)的同一请求级记录中。本节中的验证依赖于该已记录值的真实性;如果期望的颁发者来自未验证来源,则此验证不提供任何保护。 MCP 授权服务器 SHOULD 在授权响应中包含 iss 参数,包括错误响应,如 RFC9207 第 2 节所定义。包含 iss 参数的授权服务器 MUST 通过在其元数据中将 authorization_response_iss_parameter_supported 设为 true 来声明这一点(RFC9207 第 2.3 节)。 在接收授权响应时,MCP 客户端 MUST 在将授权码传递给任何令牌端点之前,应用 RFC9207 第 2.4 节中的验证:
authorization_response_iss_parameter_supported响应中的 iss客户端操作
true存在使用简单字符串比较与记录的颁发者进行比较(RFC3986 第 6.2.1 节
true不存在拒绝响应
false 或不存在存在使用简单字符串比较与记录的颁发者进行比较(RFC3986 第 6.2.1 节
false 或不存在不存在继续
第三行适用 RFC9207 第 2.4 节中的本地策略规定:本规范会将存在的 iss 与记录的颁发者进行比较,而不管元数据公告如何,以适配那些在更新元数据之前就发出 iss 的授权服务器。 预计本规范的未来修订将把授权服务器包含 iss 的要求从 SHOULD 提升为 MUST。建议实现方现在就发出并验证 iss,以便顺利过渡;在该修订定义升级路径之前,客户端对 iss 缺失的拒绝行为仍将依据 authorization_response_iss_parameter_supported 来决定。 在根据 RFC 9207 第 2.4 节application/x-www-form-urlencoded 响应中解码 iss 值之后,客户端在比较前 MUST NOT 应用协议或主机大小写折叠、默认端口省略、尾部斜杠处理或百分号编码规范化(RFC 3986 第 6.2.2-6.2.3 节)。 此验证同样适用于错误响应——在不匹配时,客户端 MUST NOT 处理或显示 errorerror_descriptionerror_uri

资源参数实现

MCP 客户端 MUST 实现 RFC 8707 中定义的 OAuth 2.0 资源指示器, 以显式指定请求令牌所针对的目标资源。resource 参数:
  1. MUST 同时包含在授权请求和令牌请求中。
  2. MUST 标识客户端打算使用该令牌的 MCP 服务器。
  3. MUST 使用 RFC 8707 第 2 节 中定义的 MCP 服务器规范 URI。

规范服务器 URI

就本规范而言,MCP 服务器的规范 URI 定义为 RFC 8707 第 2 节 中规定的资源标识符,并与 RFC 9728 中的 resource 参数保持一致。 MCP 客户端 SHOULD 按照 RFC 8707 的指导,为其打算访问的 MCP 服务器提供尽可能具体的 URI。虽然规范形式使用小写的协议和主机组件,但为保证健壮性和互操作性,实现 SHOULD 接受大写的协议和主机组件。 有效规范 URI 的示例:
  • https://mcp.example.com/mcp
  • https://mcp.example.com
  • https://mcp.example.com:8443
  • https://mcp.example.com/server/mcp(当路径组件对于标识单个 MCP 服务器是必要的时)
无效规范 URI 的示例:
  • mcp.example.com(缺少协议)
  • https://mcp.example.com#fragment(包含片段)
注意: 尽管 https://mcp.example.com/(带尾部斜杠)和 https://mcp.example.com(不带尾部斜杠)在 RFC 3986 中技术上都属于有效的绝对 URI,但除非尾部斜杠对于特定资源在语义上具有重要意义,否则实现 SHOULD 一致地使用不带尾部斜杠的形式以获得更好的互操作性。
例如,如果访问的 MCP 服务器为 https://mcp.example.com,则授权请求将包含:
&resource=https%3A%2F%2Fmcp.example.com
无论授权服务器是否支持此参数,MCP 客户端 MUST 都发送该参数。

访问令牌使用

令牌要求

在向 MCP 服务器发出请求时,访问令牌的处理 必须 符合 OAuth 2.1 第 5 节“资源请求” 中定义的要求。 具体而言:
  1. MCP 客户端 必须 使用 OAuth 2.1 第 5.1.1 节 中定义的 Authorization 请求头字段:
Authorization: Bearer <access-token>
请注意,授权信息 必须 包含在客户端到服务器的每个 HTTP 请求中。
  1. 访问令牌 不得 包含在 URI 查询字符串中
请求示例:
GET /mcp HTTP/1.1
Host: mcp.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

令牌处理

MCP 服务器在其作为 OAuth 2.1 资源服务器的角色下,必须 按照 OAuth 2.1 第 5.2 节 的描述验证访问令牌。 MCP 服务器 必须 验证访问令牌是专门为其签发的,即以其为预期受众, 并遵循 RFC 8707 第 2 节。 如果验证失败,服务器 必须 按照 OAuth 2.1 第 5.3 节 中的错误处理要求进行响应。无效或过期的令牌 必须 收到 HTTP 401 响应。 MCP 客户端 不得 向 MCP 服务器发送除 MCP 服务器授权服务器签发之外的令牌。 MCP 服务器 必须 只接受可用于其 自身资源的有效令牌。 MCP 服务器 不得 接受或转发任何其他令牌。

刷新令牌

本节为 MCP 客户端和 MCP 服务器在处理或签发用于 OAuth 和 OpenID Connect 的刷新令牌时提供指导。 MCP 客户端 若需要刷新令牌:
  • 必须按照 OAuth 2.1 第 4.3 节 的规定,在传输和存储过程中保持刷新令牌的机密性
  • 应当在其 grant_types 客户端元数据中包含 refresh_token
  • 当授权服务器元数据在 scopes_supported 中包含 offline_access 时,可以在授权请求和令牌请求的 scope 参数中添加 offline_access
  • 不得假定一定会签发刷新令牌;是否签发由授权服务器自行决定
MCP 服务器(受保护资源)不应WWW-Authenticate 的 scope 或受保护资源元数据的 scopes_supported 中包含 offline_access,因为刷新令牌不是资源要求。

错误处理

服务器在发生授权错误时,必须返回适当的 HTTP 状态码:
状态码描述用途
401未授权需要授权或令牌无效
403禁止访问范围无效或权限不足
400错误请求授权请求格式错误

Scope 挑战处理

本节说明在运行时操作期间如何处理范围不足错误:当客户端已经拥有令牌,但需要额外权限时,会出现此类错误。这遵循 OAuth 2.1 第 5 节 中定义的错误处理模式,并利用 RFC 9728(OAuth 2.0 受保护资源元数据) 中的元数据字段。

运行时范围不足错误

当客户端在运行时操作期间使用权限范围不足的访问令牌发起请求时,服务器应当响应:
  • HTTP 403 Forbidden 状态码(依据 RFC 6750 第 3.1 节
  • 带有 Bearer 方案及以下附加参数的 WWW-Authenticate 头:
    • error="insufficient_scope" - 表示具体的授权失败类型
    • scope="required_scope1 required_scope2" - 指定该操作所需的最小范围
    • resource_metadata - 受保护资源元数据文档的 URI(与 401 响应保持一致)
    • error_description(可选)- 人类可读的错误描述
服务器范围管理:当返回范围不足错误时,服务器应当scope 参数中包含满足当前操作所需的范围,并与 RFC 6750 第 3.1 节 保持一致。 scope 属性描述了访问请求资源所必需的范围——服务器不必包含 客户端此前已获授的范围。 服务器在决定包含哪些范围时具有灵活性:
  • 最小方案:仅包含触发该错误的具体操作所需的范围。
  • 推荐方案:包含当前操作所需的范围,以及通常需要协同工作的相关范围,以减少升级授权轮次的次数。
  • 扩展方案:包含当前操作所需的范围、相关范围,以及服务器预期客户端在不久的将来可能需要的任何其他范围。
选择取决于服务器对用户体验影响和授权摩擦的评估。 无论采用哪种方案,服务器应当将当前操作所需的全部范围一次性包含在单个挑战中。 逐步挑战(先返回一个缺失范围,再在后续重试中返回另一个)会迫使单个操作经历多次授权往返,降低用户体验。所需范围可以根据具体请求参数和上下文动态确定,但一旦确定,就应当一并发出。 服务器应当在范围包含策略上保持一致,以便为客户端提供可预测的行为。 服务器应当在确定响应中要包含哪些范围时考虑用户体验影响,因为配置不当的范围可能会导致用户频繁交互。
跨操作的范围累积是客户端的责任。客户端在发起重新授权时,应当计算先前请求的范围与新挑战范围的并集,如 升级授权流程 所述。这样既能让服务器在客户端范围集合方面保持无状态,又能确保客户端不会丢失此前已授予的权限。
范围不足响应示例:
HTTP/1.1 403 禁止
WWW-Authenticate: Bearer error="权限不足",
                         scope="files:write",
                         resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource",
                         error_description="此操作需要文件写入权限"

分步升级授权流程

客户端在初始授权期间或运行时会收到与作用域相关的错误(insufficient_scope)。 客户端应该通过分步升级授权流程请求一个包含更多作用域的新访问令牌来响应这些错误,或者以其他适当方式处理这些错误。 代表用户行事的客户端应该尝试分步升级授权流程。代表自身行事的客户端(client_credentials 客户端) 可以尝试分步升级授权流程,或立即中止请求。 流程如下:
  1. 解析错误信息,来自授权服务器响应或 WWW-Authenticate 标头
  2. 确定所需作用域,方法是计算 客户端先前请求的作用域集合与 当前质询中的作用域的并集。这可确保在服务器按操作发出作用域质询时,先前已授予的 权限得以保留,参见 RFC 6750 第 3.1 节。 客户端也可以查阅 作用域选择策略, 以获取初始作用域选择指导。
  3. 发起(重新)授权,并使用确定的作用域集合
  4. 使用新的授权重试原始请求,重试次数不应超过几次,并将其视为永久性的授权失败
客户端应该实现重试次数限制,并且应该跟踪作用域升级尝试,以避免 同一资源与操作组合反复失败。
层级式作用域:某些授权服务器定义了作用域层级 ,其中较宽泛的作用域意味着较窄的作用域(例如,admin 作用域 包含 read)。在累积作用域时,客户端的并集可能 包含语义上冗余的条目——例如,先前 被授予较宽泛作用域的令牌,可能会被质询要求一个它已经 隐含包含的较窄作用域。客户端无需按层级去重;授权服务器 通常会在令牌签发期间规范化此类冗余。服务器则在判定令牌是否足以执行某项操作时,必须考虑层级关系, 但这不会影响它们在质询中发出的作用域。

安全注意事项

本规范的实现必须遵循 安全注意事项 中的规范性安全要求,涵盖令牌受众绑定与验证、令牌窃取、通信安全、授权码保护、混淆攻击与受骗代理攻击、开放重定向以及客户端 ID 元数据文档安全。

MCP 授权扩展

核心协议有若干授权扩展,用于定义额外的授权机制。这些扩展具有以下特点:
  • 可选 - 实现可以选择采用这些扩展
  • 增量式 - 扩展不会修改或破坏核心协议功能;它们在保持核心协议行为不变的同时添加新能力
  • 可组合 - 扩展是模块化的,设计上可协同工作且不会冲突,允许实现同时采用多个扩展
  • 独立版本管理 - 扩展遵循核心 MCP 的版本迭代周期,但在需要时可以采用独立版本管理
支持的扩展列表可在 MCP 授权扩展 仓库中找到。