> ## Documentation Index
> Fetch the complete documentation index at: https://mcp.transdocs.org/llms.txt
> Use this file to discover all available pages before exploring further.

# 授权

<Info>**协议版本**：2025-03-26</Info>

## 简介

### 目的和范围

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

### 协议要求

授权对于MCP实现是**可选的**。当支持授权时：

* 使用HTTP传输的实现**应该**遵循本规范。
* 使用STDIO传输的实现**不应该**遵循本规范，而应从环境中获取凭证。
* 使用其他传输方式的实现**必须**遵循其协议的安全最佳实践。

### 标准合规性

本授权机制基于以下已确立的规范，但仅实现其部分功能，以确保安全性、互操作性和简洁性：

* [OAuth 2.1 IETF 草案](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12)
* OAuth 2.0 授权服务器元数据
  ([RFC8414](https://datatracker.ietf.org/doc/html/rfc8414))
* OAuth 2.0 动态客户端注册协议
  ([RFC7591](https://datatracker.ietf.org/doc/html/rfc7591))

## 授权流程

### 概述

1. MCP授权实现**必须**实现OAuth 2.1，并为保密客户端和公开客户端都采取适当的安全措施。

2. MCP授权实现**应该**支持OAuth 2.0动态客户端注册协议 ([RFC7591](https://datatracker.ietf.org/doc/html/rfc7591))。

3. MCP服务器**应该**且MCP客户端**必须**实现OAuth 2.0授权服务器元数据 ([RFC8414](https://datatracker.ietf.org/doc/html/rfc8414))。不支持授权服务器元数据的服务器**必须**遵循默认的URI方案。

### OAuth授权类型

OAuth定义了不同的流程或授权类型，即获取访问令牌的不同方式。每种类型适用于不同的使用场景。

MCP服务器**应该**支持最适合其目标用户的OAuth授权类型。例如：

1. 授权码：当客户端代表（人类）终端用户操作时使用。
   * 例如，一个代理调用由SaaS系统实现的MCP工具。
2. 客户端凭证：客户端是另一个应用程序（非人类）。
   * 例如，一个代理调用安全的MCP工具以检查特定门店的库存。无需模拟终端用户。

### 示例：授权码授权

此示例演示了用于用户认证的OAuth 2.1授权码授权流程。

**注意**：以下示例假设MCP服务器同时作为授权服务器。然而，授权服务器也可以作为独立的服务部署。

人类用户通过Web浏览器完成OAuth流程，获取一个代表其身份的访问令牌，使客户端能够代表用户操作。

当客户端未提供授权时，服务器**必须**返回\_HTTP 401 未授权\_响应。

客户端在收到\_HTTP 401 未授权\_响应后，启动
[OAuth 2.1 IETF 草案](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#name-authorization-code-grant)
授权流程。

以下演示了使用PKCE的公共客户端基本OAuth 2.1流程。

```mermaid theme={null}
sequenceDiagram
    participant B as 用户代理（浏览器）
    participant C as 客户端
    participant M as MCP服务器

    C->>M: MCP请求
    M->>C: HTTP 401 未授权
    注释 over C: 生成code_verifier和code_challenge
    C->>B: 使用授权URL + code_challenge打开浏览器
    B->>M: GET /authorize
    注释 over M: 用户登录并授权
    M->>B: 重定向到回调URL并携带授权码
    B->>C: 带有授权码的回调
    C->>M: 带code + code_verifier的令牌请求
    M->>C: 访问令牌（+ 刷新令牌）
    C->>M: 带访问令牌的MCP请求
    注释 over C,M: 开始标准的MCP消息交换
```

### 服务器元数据发现

对于服务器能力发现：

* MCP客户端\_必须\_遵循在[RFC8414](https://datatracker.ietf.org/doc/html/rfc8414)中定义的OAuth 2.0授权服务器元数据协议。
* MCP服务器\_应该\_遵循OAuth 2.0授权服务器元数据协议。
* 不支持OAuth 2.0授权服务器元数据协议的MCP服务器，\_必须\_支持回退URL。

发现流程如下所示：

```mermaid theme={null}
sequenceDiagram
    participant C as 客户端
    participant S as 服务器

    C->>S: GET /.well-known/oauth-authorization-server
    alt 发现成功
        S->>C: 200 OK + 元数据文档
        注释 over C: 使用元数据中的端点
    else 发现失败
        S->>C: 404 未找到
        注释 over C: 回退到默认端点
    end
    注释 over C: 继续进行授权流程
```

#### 服务器元数据发现请求头

MCP客户端在进行服务器元数据发现时，\_应该\_包含请求头`MCP-Protocol-Version: <protocol-version>`，以便MCP服务器可以根据MCP协议版本做出响应。

例如：`MCP-Protocol-Version: 2024-11-05`

#### 授权基础URL

授权基础URL**必须**通过丢弃任何现有的`path`组件从MCP服务器URL中确定。例如：

如果MCP服务器URL是 `https://api.example.com/v1/mcp`，那么：

* 授权基础URL是 `https://api.example.com`
* 元数据端点**必须**位于
  `https://api.example.com/.well-known/oauth-authorization-server`

这确保了无论MCP服务器URL中包含什么路径组件，授权端点始终位于托管MCP服务器的域名根级别。

#### 无元数据发现服务器的回退方案

对于不实现OAuth 2.0授权服务器元数据的服务器，客户端**必须**使用以下相对于[授权基础URL](#authorization-base-url)的默认端点路径：

| 端点   | 默认路径       | 描述        |
| ---- | ---------- | --------- |
| 授权端点 | /authorize | 用于授权请求    |
| 令牌端点 | /token     | 用于令牌交换和刷新 |
| 注册端点 | /register  | 用于动态客户端注册 |

例如，对于托管在 `https://api.example.com/v1/mcp` 的MCP服务器，默认端点将是：

* `https://api.example.com/authorize`
* `https://api.example.com/token`
* `https://api.example.com/register`

客户端**必须**首先尝试通过元数据文档发现端点，然后再回退到默认路径。使用默认路径时，所有其他协议要求保持不变。

### 动态客户端注册

MCP客户端和服务器**应该**支持
[OAuth 2.0动态客户端注册协议](https://datatracker.ietf.org/doc/html/rfc7591)
，以允许MCP客户端在无需用户交互的情况下获取OAuth客户端ID。这为客户端自动注册到新服务器提供了一种标准化方式，这对MCP至关重要，因为：

* 客户端无法预先知道所有可能的服务器
* 手动注册会增加用户使用难度
* 它允许无缝连接到新服务器
* 服务器可以实施自己的注册策略

任何**不**支持动态客户端注册的MCP服务器都需要提供替代方式来获取客户端ID（以及适用时的客户端密钥）。对于这类服务器，MCP客户端必须：

1. 为该MCP服务器硬编码客户端ID（以及适用时的客户端密钥），或
2. 提供一个UI，允许用户输入这些信息（例如，通过服务器托管的配置界面自行注册OAuth客户端后）。

### 授权流程步骤

完整的授权流程如下所示：

```mermaid theme={null}
sequenceDiagram
    participant B as 用户代理（浏览器）
    participant C as 客户端
    participant M as MCP服务器

    C->>M: GET /.well-known/oauth-authorization-server
    alt 服务器支持发现
        M->>C: 授权服务器元数据
    else 无发现
        M->>C: 404（使用默认端点）
    end

    alt 动态客户端注册
        C->>M: POST /register
        M->>C: 客户端凭证
    end

    注释 over C: 生成PKCE参数
    C->>B: 使用授权URL + code_challenge打开浏览器
    B->>M: 授权请求
    注释 over M: 用户授权
    M->>B: 重定向到回调并携带授权码
    B->>C: 授权码回调
    C->>M: 带code_verifier的令牌请求
    M->>C: 访问令牌（+ 刷新令牌）
    C->>M: 带访问令牌的API请求
```

#### 决策流程概览

```mermaid theme={null}
flowchart TD
    A[开始授权流程] --> B{检查元数据发现}
    B -->|可用| C[使用元数据端点]
    B -->|不可用| D[使用默认端点]

    C --> G{检查注册端点}
    D --> G

    G -->|可用| H[执行动态注册]
    G -->|不可用| I[需要替代注册]

    H --> J[开始OAuth流程]
    I --> J

    J --> K[生成PKCE参数]
    K --> L[请求授权]
    L --> M[用户授权]
    M --> N[用代码换令牌]
    N --> O[使用访问令牌]
```

### 访问令牌使用

#### 令牌要求

访问令牌处理**必须**符合
[OAuth 2.1 第5节](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-5)
中对资源请求的要求。具体而言：

1. MCP客户端**必须**使用授权请求头字段
   [第5.1.1节](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-5.1.1)：

```
Authorization: Bearer <access-token>
```

请注意，授权**必须**包含在客户端到服务器的每个HTTP请求中，即使它们属于同一个逻辑会话。

2. 访问令牌**不得**包含在URI查询字符串中

示例请求：

```http theme={null}
GET /v1/contexts HTTP/1.1
Host: mcp.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
```

#### 令牌处理

资源服务器**必须**按照
[第5.2节](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-5.2)
描述验证访问令牌。如果验证失败，服务器**必须**按照
[第5.3节](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-5.3)
的错误处理要求作出响应。无效或过期的令牌**必须**返回HTTP 401响应。

### 安全考虑

以下安全要求**必须**实施：

1. 客户端**必须**按照OAuth 2.0最佳实践安全存储令牌
2. 服务器**应该**强制实施令牌过期和轮换
3. 所有授权端点**必须**通过HTTPS提供
4. 服务器**必须**验证重定向URI以防止开放重定向漏洞
5. 重定向URI**必须**是localhost URL或HTTPS URL

### 错误处理

服务器**必须**为授权错误返回适当的HTTP状态码：

| 状态码 | 描述   | 使用场景      |
| --- | ---- | --------- |
| 401 | 未授权  | 需要授权或令牌无效 |
| 403 | 禁止   | 范围无效或权限不足 |
| 400 | 错误请求 | 授权请求格式错误  |

### 实现要求

1. 实现**必须**遵循OAuth 2.1安全最佳实践
2. PKCE对所有客户端**是强制要求**
3. 令牌轮换**应该**实现以增强安全性
4. 令牌生命周期**应该**根据安全要求进行限制

### 第三方授权流程

#### 概述

MCP服务器**可以**通过第三方授权服务器支持委托授权。在此流程中，MCP服务器同时作为OAuth客户端（对第三方授权服务器）和OAuth授权服务器（对MCP客户端）。

#### 流程描述

第三方授权流程包括以下步骤：

1. MCP客户端向MCP服务器发起标准OAuth请求
2. MCP服务器将用户重定向到第三方授权服务器
3. 用户向第三方服务器授权
4. 第三方服务器将授权码重定向回MCP服务器
5. MCP服务器用授权码换取第三方访问令牌
6. MCP服务器生成绑定到第三方会话的自己的访问令牌
7. MCP服务器完成与MCP客户端的原始OAuth流程

```mermaid theme={null}
sequenceDiagram
    participant B as 用户代理（浏览器）
    participant C as MCP客户端
    participant M as MCP服务器
    participant T as 第三方授权服务器

    C->>M: 初始OAuth请求
    M->>B: 重定向到第三方 /authorize
    B->>T: 授权请求
    注释 over T: 用户授权
    T->>B: 重定向到MCP服务器回调
    B->>M: 授权码
    M->>T: 用代码换令牌
    T->>M: 第三方访问令牌
    注释 over M: 生成绑定的MCP令牌
    M->>B: 重定向到MCP客户端回调
    B->>C: MCP授权码
    C->>M: 用代码换令牌
    M->>C: MCP访问令牌
```

#### 会话绑定要求

实现第三方授权的MCP服务器**必须**：

1. 在第三方令牌和发出的MCP令牌之间保持安全映射
2. 在接受MCP令牌之前验证第三方令牌状态
3. 实现适当的令牌生命周期管理
4. 处理第三方令牌过期和续订

#### 安全考虑

在实现第三方授权时，服务器**必须**：

1. 验证所有重定向URI
2. 安全存储第三方凭证
3. 实现适当的会话超时处理
4. 考虑令牌链的安全影响
5. 为第三方授权失败实现适当的错误处理

## 最佳实践

#### 本地客户端作为公共OAuth 2.1客户端

我们强烈建议本地客户端将OAuth 2.1作为公共客户端实现：

1. 使用代码挑战（PKCE）进行授权请求，以防止拦截攻击
2. 根据本地系统实现安全的令牌存储
3. 遵循令牌刷新最佳实践以维持会话
4. 正确处理令牌过期和续订

#### 授权元数据发现

我们强烈建议所有客户端实现元数据发现。这减少了用户手动提供端点或客户端回退到默认端点的需求。

#### 动态客户端注册

由于客户端无法预先知道MCP服务器的集合，我们强烈建议实现动态客户端注册。这允许应用程序自动注册到MCP服务器，消除了用户手动获取客户端ID的需求。
