引言
目的与范围
模型上下文协议在传输层提供授权能力,使 MCP 客户端能够代表资源所有者向受限的 MCP 服务器发起请求。本规范定义了基于 HTTP 的传输的授权流程。协议要求
授权对 MCP 实现是**可选(OPTIONAL)**的。当受支持时:- 使用基于 HTTP 的传输的实现**应当(SHOULD)**遵循本规范。
- 使用 STDIO 传输的实现**不应(SHOULD NOT)**遵循本规范,而应从环境中检索凭据。
- 使用其他替代传输的实现**必须(MUST)**遵循其协议既定的安全最佳实践。
标准合规性
此授权机制基于下面列出的既有规范,但实现了它们特性的一个选定子集,以在保持简单性的同时确保安全性和互操作性:- OAuth 2.1 IETF DRAFT(draft-ietf-oauth-v2-1-13)
- OAuth 2.0 Authorization Server Metadata(RFC8414)
- OAuth 2.0 Dynamic Client Registration Protocol(RFC7591)
- OAuth 2.0 Protected Resource Metadata(RFC9728)
- OAuth Client ID Metadata Documents(draft-ietf-oauth-client-id-metadata-document-00)
角色
受保护的 MCP 服务器 充当一个 OAuth 2.1 资源服务器,能够使用访问令牌接受和响应受保护的资源请求。 MCP 客户端 充当一个 OAuth 2.1 客户端,代表资源所有者发起受保护的资源请求。 授权服务器 负责(在必要时)与用户交互,并签发供在 MCP 服务器处使用的访问令牌。授权服务器的实现细节超出本规范的范围。它可以与资源服务器共同托管,或作为一个单独的实体。授权服务器发现一节规定了 MCP 服务器如何向客户端指示其对应授权服务器的位置。概述
- 授权服务器**必须(MUST)**为机密客户端和公开客户端实现带有适当安全措施的 OAuth 2.1。
- 授权服务器和 MCP 客户端**应当(SHOULD)**支持 OAuth Client ID Metadata Documents(draft-ietf-oauth-client-id-metadata-document-00)。
- 授权服务器和 MCP 客户端**可以(MAY)**支持 OAuth 2.0 Dynamic Client Registration Protocol(RFC7591)。
- MCP 服务器**必须(MUST)实现 OAuth 2.0 Protected Resource Metadata(RFC9728)。MCP 客户端必须(MUST)**使用 OAuth 2.0 Protected Resource Metadata 进行授权服务器发现。
-
MCP 授权服务器**必须(MUST)**提供以下发现机制中的至少一种:
- OAuth 2.0 Authorization Server Metadata(RFC8414)
- OpenID Connect Discovery 1.0
授权服务器发现
本节描述 MCP 服务器向 MCP 客户端公布其关联授权服务器的机制,以及 MCP 客户端可借以确定授权服务器端点和所支持能力的发现流程。授权服务器位置
MCP 服务器**必须(MUST)实现 OAuth 2.0 Protected Resource Metadata(RFC9728)规范以指示授权服务器的位置。MCP 服务器返回的受保护资源元数据文档必须(MUST)**包含含至少一个授权服务器的authorization_servers 字段。
authorization_servers 的具体使用超出本规范的范围;实现者应查阅 OAuth 2.0 Protected Resource Metadata(RFC9728)以获取实现细节的指导。
实现者应注意,受保护资源元数据文档可以定义多个授权服务器。选择使用哪个授权服务器的责任在于 MCP 客户端,遵循 RFC9728 第 7.6 节 “Authorization Servers” 中规定的指南。
受保护资源元数据发现要求
MCP 服务器**必须(MUST)**实现以下发现机制之一,以向 MCP 客户端提供授权服务器位置信息:-
WWW-Authenticate Header:在返回
401 Unauthorized响应时,在WWW-AuthenticateHTTP header 的resource_metadata下包含资源元数据 URL,如 RFC9728 第 5.1 节 所述。 -
Well-Known URI:在 RFC9728 规定的 well-known URI 处提供元数据。这可以是:
- 在服务器 MCP 端点的路径处:
https://example.com/public/mcp可以在https://example.com/.well-known/oauth-protected-resource/public/mcp托管元数据 - 在根处:
https://example.com/.well-known/oauth-protected-resource
- 在服务器 MCP 端点的路径处:
WWW-Authenticate header 存在时使用其中的资源元数据 URL;否则,它们必须(MUST)**回退到按上面列出的顺序构造和请求 well-known URI。
MCP 服务器**应当(SHOULD)**在 WWW-Authenticate header 中包含一个 scope 参数,如 RFC 6750 第 3 节 所定义,以指示访问该资源所需的 scope。这为客户端提供了在授权期间请求适当 scope 的即时指导,遵循最小权限原则并防止客户端请求过度的权限。
WWW-Authenticate 质询中包含的 scope **可以(MAY)匹配 scopes_supported、是其子集或超集,或是一个既非严格子集也非超集的替代集合。客户端不得(MUST NOT)假定质询 scope 集与 scopes_supported 之间存在任何特定的集合关系。客户端必须(MUST)将质询中提供的 scope 视为满足当前请求的权威。服务器应当(SHOULD)**在构造 scope 集时力求一致,但它们不要求通过 scopes_supported 呈现每个动态签发的 scope。
带 scope 指导的 401 响应示例:
WWW-Authenticate header 并适当地响应来自 MCP 服务器的 HTTP 401 Unauthorized 响应。
如果 scope 参数缺失,客户端**应当(SHOULD)**应用 Scope 选择策略 一节中定义的回退行为。
授权服务器元数据发现
为处理不同的 issuer URL 格式并确保与 OAuth 2.0 Authorization Server Metadata 和 OpenID Connect Discovery 1.0 规范的互操作性,MCP 客户端在发现授权服务器元数据时**必须(MUST)**尝试多个 well-known 端点。 发现方式基于 RFC8414 第 3.1 节 “Authorization Server Metadata Request”(用于 OAuth 2.0 Authorization Server Metadata 发现)和 RFC8414 第 5 节 “Compatibility Notes”(用于 OpenID Connect Discovery 1.0 互操作性)。 对于带路径组件的 issuer URL(例如https://auth.example.com/tenant1),客户端**必须(MUST)**按以下优先级顺序尝试端点:
- 带路径插入的 OAuth 2.0 Authorization Server Metadata:
https://auth.example.com/.well-known/oauth-authorization-server/tenant1 - 带路径插入的 OpenID Connect Discovery 1.0:
https://auth.example.com/.well-known/openid-configuration/tenant1 - 路径追加的 OpenID Connect Discovery 1.0:
https://auth.example.com/tenant1/.well-known/openid-configuration
https://auth.example.com),客户端**必须(MUST)**尝试:
- OAuth 2.0 Authorization Server Metadata:
https://auth.example.com/.well-known/oauth-authorization-server - OpenID Connect Discovery 1.0:
https://auth.example.com/.well-known/openid-configuration
授权服务器发现序列图
下图勾勒了一个示例流程:客户端注册方式
MCP 支持三种客户端注册机制。请根据你的场景选择:- Client ID Metadata Documents:当客户端和服务器没有事先关系时(最常见)
- 预注册(Pre-registration):当客户端和服务器有既有关系时
- 动态客户端注册(Dynamic Client Registration):用于向后兼容或特定要求
- 如果客户端有可用的、针对该服务器的预注册客户端信息,则使用它
- 如果授权服务器指示服务器支持 Client ID Metadata Documents(通过 OAuth Authorization Server Metadata 中的
client_id_metadata_document_supported),则使用它 - 如果授权服务器支持动态客户端注册(通过 OAuth Authorization Server Metadata 中的
registration_endpoint),则将其作为回退使用 - 如果没有其他选项可用,则提示用户输入客户端信息
Client ID Metadata Documents
MCP 客户端和授权服务器**应当(SHOULD)**支持 OAuth Client ID Metadata Document 所规定的 OAuth Client ID Metadata Documents。此方式使客户端能够使用 HTTPS URL 作为客户端标识符,其中该 URL 指向一个包含客户端元数据的 JSON 文档。这解决了服务器与客户端没有事先关系这一常见的 MCP 场景。实现要求
支持 Client ID Metadata Documents 的 MCP 实现**必须(MUST)**遵循 OAuth Client ID Metadata Document 中规定的要求。关键要求包括: 对于 MCP 客户端:- 客户端**必须(MUST)**遵循 RFC 要求,将其元数据文档托管在一个 HTTPS URL 处
client_idURL **必须(MUST)**使用 “https” 方案并包含一个路径组件,例如https://example.com/client.json- 元数据文档**必须(MUST)**至少包含以下属性:
client_id、client_name、redirect_uris - 客户端**必须(MUST)**确保元数据中的
client_id值与文档 URL 完全匹配 - 客户端**可以(MAY)**使用
private_key_jwt进行客户端认证(例如对令牌端点的请求),并配备如 Client ID Metadata Document 第 6.2 节 所述的适当 JWKS 配置
- **应当(SHOULD)**在遇到 URL 格式的 client_id 时获取元数据文档
- **必须(MUST)**校验所获取文档的
client_id与该 URL 完全匹配 - **应当(SHOULD)**尊重 HTTP 缓存 header 缓存元数据
- **必须(MUST)**依据元数据文档中的 redirect URI 校验授权请求中呈现的 redirect URI
- **必须(MUST)**校验文档结构是有效的 JSON 并包含必需字段
- **应当(SHOULD)**遵循 Client ID Metadata Document 第 6 节 中的安全考量
示例元数据文档
Client ID Metadata Documents 流程
下图演示使用 Client ID Metadata Documents 时的完整流程:发现
授权服务器通过在其 OAuth Authorization Server 元数据中包含以下属性,来公布它支持使用 Client ID Metadata Documents 的客户端:预注册
MCP 客户端**应当(SHOULD)**支持静态客户端凭据的选项,例如通过预注册流程提供的那些。这可以是:- 硬编码一个专门供 MCP 客户端在与该授权服务器交互时使用的 client ID(以及在适用时的客户端凭据),或
- 向用户呈现一个 UI,允许他们在自行注册一个 OAuth 客户端(例如通过服务器托管的配置界面)后输入这些详情。
动态客户端注册
MCP 客户端和授权服务器**可以(MAY)**支持 OAuth 2.0 Dynamic Client Registration Protocol RFC7591,以允许 MCP 客户端在无用户交互的情况下获取 OAuth client ID。此选项被包含在内以向后兼容 MCP 授权规范的较早版本。Scope 选择策略
在实现授权流程时,MCP 客户端**应当(SHOULD)通过只请求其预期操作所必需的 scope 来遵循最小权限原则。在初始授权握手期间,MCP 客户端应当(SHOULD)**遵循以下 scope 选择优先级顺序:- 使用
scope参数——来自 401 响应中的初始WWW-Authenticateheader(如果提供) - 如果
scope不可用,使用受保护资源元数据文档的scopes_supported中定义的所有 scope;如果scopes_supported未定义则省略scope参数。
scopes_supported 字段旨在表示基本功能所必需的最小 scope 集(参见 Scope 最小化),额外的 scope 则通过 Scope 质询处理 一节所述的升级授权流程步骤增量地请求。
授权流程步骤
完整的授权流程如下进行:Resource 参数实现
MCP 客户端**必须(MUST)**实现 RFC 8707 中定义的 OAuth 2.0 资源指示符(Resource Indicators),以显式指定正在为之请求令牌的目标资源。resource 参数:
- **必须(MUST)**同时包含在授权请求和令牌请求中。
- **必须(MUST)**标识客户端打算将令牌用于的 MCP 服务器。
- **必须(MUST)**使用 RFC 8707 第 2 节 中定义的 MCP 服务器规范 URI。
规范服务器 URI
就本规范而言,MCP 服务器的规范 URI 定义为 RFC 8707 第 2 节 中规定的资源标识符,并与 RFC 9728 中的resource 参数对齐。
MCP 客户端**应当(SHOULD)为它们打算访问的 MCP 服务器提供它们能提供的最具体的 URI,遵循 RFC 8707 中的指导。虽然规范形式使用小写的方案和主机组件,但实现应当(SHOULD)**为稳健性和互操作性接受大写的方案和主机组件。
有效规范 URI 示例:
https://mcp.example.com/mcphttps://mcp.example.comhttps://mcp.example.com:8443https://mcp.example.com/server/mcp(当需要路径组件来标识各个 MCP 服务器时)
mcp.example.com(缺少方案)https://mcp.example.com#fragment(包含 fragment)
注意: 虽然例如,如果访问位于https://mcp.example.com/(带尾部斜杠)和https://mcp.example.com(不带尾部斜杠)根据 RFC 3986 在技术上都是有效的绝对 URI,但实现**应当(SHOULD)**一致地使用不带尾部斜杠的形式以获得更好的互操作性,除非尾部斜杠对特定资源在语义上有意义。
https://mcp.example.com 的 MCP 服务器,授权请求将包含:
访问令牌用法
令牌要求
向 MCP 服务器发起请求时的访问令牌处理**必须(MUST)**符合 OAuth 2.1 第 5 节 “Resource Requests” 中定义的要求。具体而言:- MCP 客户端**必须(MUST)**使用 OAuth 2.1 第 5.1.1 节 中定义的 Authorization 请求 header 字段:
- 访问令牌**不得(MUST NOT)**包含在 URI 查询串中
令牌处理
MCP 服务器,以其 OAuth 2.1 资源服务器的角色,**必须(MUST)按 OAuth 2.1 第 5.2 节 所述校验访问令牌。MCP 服务器必须(MUST)根据 RFC 8707 第 2 节 校验访问令牌是专门为作为预期受众的它们签发的。若校验失败,服务器必须(MUST)按 OAuth 2.1 第 5.3 节 错误处理要求响应。无效或过期的令牌必须(MUST)**收到 HTTP 401 响应。 MCP 客户端**不得(MUST NOT)**向 MCP 服务器发送除 MCP 服务器授权服务器签发的令牌以外的令牌。 MCP 服务器**必须(MUST)**只接受对其自身资源有效的令牌。 MCP 服务器**不得(MUST NOT)**接受或转发任何其他令牌。错误处理
服务器**必须(MUST)**为授权错误返回适当的 HTTP 状态码:Scope 质询处理
本节涵盖在运行时操作期间处理 scope 不足错误,即客户端已拥有令牌但需要额外权限的情况。这遵循 OAuth 2.1 第 5 节 中定义的错误处理模式,并利用 RFC 9728(OAuth 2.0 Protected Resource Metadata) 中的元数据字段。运行时 scope 不足错误
当客户端在运行时操作期间以 scope 不足的访问令牌发起请求时,服务器**应当(SHOULD)**以以下方式响应:HTTP 403 Forbidden状态码(依据 RFC 6750 第 3.1 节)- 带
Bearer方案和附加参数的WWW-Authenticateheader:error="insufficient_scope"—— 指示授权失败的具体类型scope="required_scope1 required_scope2"—— 指定操作所需的最小 scoperesource_metadata—— 受保护资源元数据文档的 URI(与 401 响应保持一致)error_description(可选)—— 错误的人类可读描述
scope 参数中包含满足当前请求所需的 scope。
服务器在确定要包含哪些 scope 方面有灵活性:
- 最小方式:包含特定操作所需的新 scope。如果任何既有已授予 scope 也是必需的,也一并包含,以防止客户端失去先前授予的权限。
- 推荐方式:同时包含既有相关 scope 和新需要的 scope,以防止客户端失去先前授予的权限
- 扩展方式:包含既有 scope、新需要的 scope,以及常常一起工作的相关 scope
升级授权流程
客户端将在初始授权期间或运行时收到与 scope 相关的错误(insufficient_scope)。客户端**应当(SHOULD)通过升级授权流程请求一个具有更大 scope 集的新访问令牌来响应这些错误,或以其他适当的方式处理这些错误。代表用户行事的客户端应当(SHOULD)**尝试升级授权流程。代表自身行事的客户端(client_credentials 客户端)**可以(MAY)**尝试升级授权流程或立即中止请求。
流程如下:
- 解析错误信息——来自授权服务器响应或
WWW-Authenticateheader - 确定所需 scope——如 Scope 选择策略 中所述。
- 发起(重新)授权——使用所确定的 scope 集
- 重试原始请求——以新授权重试,次数不超过若干次,并将其视为永久性授权失败
安全考量
实现**必须(MUST)**遵循 OAuth 2.1 第 7 节 “Security Considerations” 中列出的 OAuth 2.1 安全最佳实践。令牌受众绑定与校验
RFC 8707 资源指示符 在授权服务器支持该能力时 通过将令牌绑定到其预期受众来提供关键的安全益处。为启用当前和未来的采用:- MCP 客户端**必须(MUST)**按 Resource 参数实现 一节所规定,在授权和令牌请求中包含
resource参数 - MCP 服务器**必须(MUST)**校验呈现给它们的令牌是专门为其使用而签发的
令牌窃取
获取客户端所存储令牌、或服务器上缓存或记录令牌的攻击者,可以用在资源服务器看来合法的请求访问受保护资源。 客户端和服务器**必须(MUST)**实现安全的令牌存储并遵循 OAuth 最佳实践,如 OAuth 2.1 第 7.1 节 所述。 授权服务器**应当(SHOULD)签发短寿命的访问令牌,以降低泄露令牌的影响。对于公开客户端,授权服务器必须(MUST)**按 OAuth 2.1 第 4.3.1 节 “Token Endpoint Extension” 所述轮换 refresh token。通信安全
实现**必须(MUST)**遵循 OAuth 2.1 第 1.5 节 “Communication Security”。 具体而言:- 所有授权服务器端点**必须(MUST)**通过 HTTPS 提供。
- 所有 redirect URI **必须(MUST)**要么是
localhost要么使用 HTTPS。
授权码保护
已获得授权响应中所含授权码访问权的攻击者,可以尝试将授权码兑换为访问令牌或以其他方式利用该授权码。(在 OAuth 2.1 第 7.5 节 中有进一步描述) 为缓解这一点,MCP 客户端**必须(MUST)按 OAuth 2.1 第 7.5.2 节 实现 PKCE,并必须(MUST)**在继续授权之前验证 PKCE 支持。PKCE 通过要求客户端创建一个秘密的 verifier-challenge 对来帮助防止授权码拦截和注入攻击,确保只有原始请求方可以将授权码兑换为令牌。 MCP 客户端在技术上可行时**必须(MUST)**使用S256 code challenge 方法,如 OAuth 2.1 第 4.1.1 节 所要求。
由于 OAuth 2.1 和 PKCE 规范未定义客户端发现 PKCE 支持的机制,MCP 客户端**必须(MUST)**依赖授权服务器元数据来验证此能力:
-
OAuth 2.0 Authorization Server Metadata:如果
code_challenge_methods_supported缺失,则授权服务器不支持 PKCE,MCP 客户端**必须(MUST)**拒绝继续。 -
OpenID Connect Discovery 1.0:虽然 OpenID Provider Metadata 未定义
code_challenge_methods_supported,但此字段通常被 OpenID 提供方包含。MCP 客户端**必须(MUST)验证提供方元数据响应中code_challenge_methods_supported的存在。如果该字段缺失,MCP 客户端必须(MUST)**拒绝继续。
code_challenge_methods_supported 以确保 MCP 兼容性。
开放重定向
攻击者可能构造恶意的 redirect URI 以将用户导向钓鱼站点。 MCP 客户端**必须(MUST)**在授权服务器处注册 redirect URI。 授权服务器**必须(MUST)**依据预注册值校验精确的 redirect URI,以防止重定向攻击。 MCP 客户端**应当(SHOULD)**在授权码流程中使用并验证 state 参数,并丢弃任何不包含原始 state 或与之不匹配的结果。 授权服务器**必须(MUST)**采取预防措施以防止将用户代理重定向到不受信任的 URI,遵循 OAuth 2.1 第 7.12.2 节 中列出的建议。 授权服务器**应当(SHOULD)**仅在它信任重定向 URI 时才自动重定向用户代理。如果该 URI 不受信任,授权服务器可以(MAY)告知用户并依赖用户做出正确决策。Client ID Metadata Document 安全
在实现 Client ID Metadata Documents 时,授权服务器**必须(MUST)**考虑 OAuth Client ID Metadata Document 第 6 节 中详述的安全影响。关键考量包括:授权服务器滥用防护
授权服务器将一个 URL 作为来自未知客户端的输入并获取该 URL。恶意客户端可以利用这一点触发授权服务器向任意 URL 发起请求,例如向授权服务器有权访问的私有管理端点发起请求。 获取元数据文档的授权服务器**应当(SHOULD)**考虑服务器端请求伪造(SSRF)风险,如 OAuth Client ID Metadata Document:服务器端请求伪造(SSRF)攻击 所述。Localhost 重定向 URI 风险
Client ID Metadata Documents 本身无法防止localhost URL 冒充。攻击者可以通过以下方式声称自己是任何客户端:
- 提供合法客户端的元数据 URL 作为其
client_id - 绑定到任意
localhost端口,并提供该地址作为 redirect_uri - 在用户批准时通过重定向接收授权码
- **应当(SHOULD)**对仅
localhost的 redirect URI 显示额外警告 - **可以(MAY)**为增强安全性要求额外的证明机制
- **必须(MUST)**在授权期间清晰地显示 redirect URI 主机名
信任策略
授权服务器**可以(MAY)**实现基于域名的信任策略:- 受信任域名的允许列表(用于受保护的服务器)
- 接受任何 HTTPS
client_id(用于开放的服务器) - 对未知域名的信誉检查
- 基于域名年龄或证书校验的限制
- 显著地显示 CIMD 和其他关联的客户端主机名以防止钓鱼
混淆代理问题
攻击者可以利用充当第三方 API 中介的 MCP 服务器,导致混淆代理漏洞。通过使用窃取的授权码,他们可以在未经用户同意的情况下获取访问令牌。 使用静态 client ID 的 MCP 代理服务器**必须(MUST)**在转发到第三方授权服务器(可能需要额外同意)之前,为每个动态注册的客户端获取用户同意。访问令牌权限限制
如果服务器接受为其他资源签发的令牌,攻击者可以获得未授权的访问或以其他方式危及 MCP 服务器。 此漏洞有两个关键维度:- Audience 校验失败。 当 MCP 服务器不验证令牌是专门为它准备的(例如,通过 RFC9068 中提到的 audience claim)时,它可能接受最初为其他服务签发的令牌。这打破了一个基本的 OAuth 安全边界,允许攻击者跨不同于预期的服务重用合法令牌。
- 令牌透传。 如果 MCP 服务器不仅接受具有不正确 audience 的令牌,还将这些未修改的令牌转发给下游服务,它就可能引发”混淆代理”问题,其中下游 API 可能错误地信任该令牌,仿佛它来自 MCP 服务器,或假设该令牌已被上游 API 校验。有关更多细节,参见安全最佳实践指南的令牌透传一节。
resource 参数,以显式指定正在为之请求令牌的目标资源。此要求与 RFC 9728 第 7.4 节 中的建议对齐。这确保访问令牌被绑定到其预期资源,无法跨不同服务被滥用。
MCP 授权扩展
核心协议有若干定义额外授权机制的授权扩展。这些扩展是:- 可选(Optional) —— 实现可以选择采用这些扩展
- 附加(Additive) —— 扩展不修改或破坏核心协议功能;它们在保留核心协议行为的同时添加新能力
- 可组合(Composable) —— 扩展是模块化的,被设计为无冲突地协同工作,允许实现同时采用多个扩展
- 独立版本化(Versioned independently) —— 扩展遵循核心 MCP 版本化周期,但可按需采用独立的版本化