Skip to content
MCP 文档版本 2026-07-28 更新于 2026-10-14

OAuth Client Credentials

使用 OAuth 2.0 客户端凭据流程为 MCP 提供机器对机器身份验证

OAuth Client Credentials 扩展(io.modelcontextprotocol/oauth-client-credentials)为 MCP 增加了对 OAuth 2.0 客户端凭据流程的支持。这使自动化系统无需交互式用户授权即可连接到 MCP 服务端。

Specification

OAuth Client Credentials 扩展的完整技术规范。

它是什么

标准 MCP 授权流程要求用户进行交互式授权——浏览器打开、用户登录并授予权限。这对人类用户来说运作良好,但在没有用户在场时就会失效。

OAuth Client Credentials 扩展通过让客户端使用应用级凭据(客户端 ID 和密钥,或签名的 JWT 断言)而非委托的用户凭据进行身份验证来解决这一问题。客户端直接向授权服务器证明其身份,授权服务器随即签发访问令牌,无需浏览器重定向或用户交互。

何时使用

在以下情况下使用 OAuth Client Credentials:

  • 后台服务需要按计划或响应事件调用 MCP 工具,且没有用户在场
  • CI/CD 流水线作为自动化构建、测试或部署工作流的一部分调用 MCP 服务端
  • 服务端到服务端集成连接两个后端系统,且不涉及最终用户
  • 守护进程或长时间运行的工作进程需要持久访问 MCP 资源

如果你的集成有应当显式授权访问的人类用户,请改用标准 MCP 授权流程。

工作原理

该扩展支持两种凭据格式:

JWT Bearer Assertions(推荐)

JWT Bearer Assertions 定义于 RFC 7523,它让客户端使用其私钥对令牌签名,并将其作为身份证明出示。授权服务器使用客户端已注册的公钥验证签名。

sequenceDiagram
    participant Client
    participant AS as Authorization Server
    participant MCP as MCP Server

    Client->>AS: POST /token<br/>grant_type=urn:ietf:params:<br/>oauth:grant-type:jwt-bearer<br/>assertion=<signed JWT>
    AS-->>Client: access_token
    Client->>MCP: MCP request (Bearer token)

JWT 断言通常包含:

  • iss:客户端 ID(签发者)
  • sub:客户端 ID(被验证的主体)
  • aud:授权服务器令牌端点 URL
  • exp:过期时间
  • iat:签发时间

客户端密钥

对于更简单的部署,该扩展还支持使用 client_id 和 client_secret 的标准客户端凭据流程。客户端将其凭据直接发送到授权服务器的令牌端点,并收到返回的访问令牌。

sequenceDiagram
    participant Client
    participant AS as Authorization Server
    participant MCP as MCP Server

    Client->>AS: POST /token<br/>grant_type=client_credentials<br/>client_id + client_secret
    AS-->>Client: access_token
    Client->>MCP: MCP request (Bearer token)

WARNING

Client secrets 是长期有效的凭据,无需用户交互即可授予访问权限。如果密钥泄露,攻击者可以在密钥轮换之前静默地以你的应用身份进行身份验证。为降低风险:

  • 将密钥存储在密钥管理器中,绝不要放在源代码或纳入版本控制的环境文件中。
  • 定期轮换密钥,并在任何疑似泄露后立即轮换。
  • 将凭据范围限定为所需的最小权限。
  • 尽可能优先使用 JWT 断言——它们有效期短,且无需传输签名密钥。

实现指南

对于 MCP 客户端

要使用 OAuth Client Credentials 扩展,你的客户端必须:

声明支持

在其逐请求能力中包含该扩展:

```jsonc
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "...",
  "params": {
    // Other fields...
    "_meta": {
      // Other fields...
      "io.modelcontextprotocol/clientCapabilities": {
        "extensions": {
          "io.modelcontextprotocol/oauth-client-credentials": {},
        },
      },
    },
  },
}
```

获取访问令牌

在连接到 MCP 服务端之前,使用客户端凭据授权向授权服务器请求令牌。

包含令牌

在向 MCP 服务端发送的 HTTP 请求的 `Authorization` 头中传递令牌:

```
Authorization: Bearer <access_token>
```

处理令牌刷新

客户端凭据令牌的有效期通常比用户委托令牌更短。实现令牌刷新逻辑,在过期前获取新令牌。

对于 MCP 服务端

要接受客户端凭据令牌,你的服务端必须:

验证令牌

对每个请求,使用授权服务器的公钥(通常通过 JWKS 端点)验证 JWT 签名和声明。

检查作用域

确保令牌包含所请求操作所需的作用域。

声明支持

可选地(但为便于发现而推荐),在 `server/discover` 响应中包含该扩展:
jsonc
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    // Other fields...
    "capabilities": {
      "extensions": {
        "io.modelcontextprotocol/oauth-client-credentials": {},
      },
    },
  },
}

SDK 示例

官方 MCP SDK 内置支持客户端凭据认证。两者都会自动处理令牌的获取与刷新。

安装 SDK

bash
npm install @modelcontextprotocol/client

创建提供程序并连接

选择与你的设置相匹配的凭据格式:

#### 使用客户端密钥
typescript
import {
  Client,
  ClientCredentialsProvider,
  StreamableHTTPClientTransport,
} from "@modelcontextprotocol/client";

const provider = new ClientCredentialsProvider({
  clientId: "my-service",
  clientSecret: "s3cr3t",
});

const client = new Client(
  { name: "my-service", version: "1.0.0" },
  { capabilities: {} },
);

const transport = new StreamableHTTPClientTransport(
  new URL("https://mcp.example.com/mcp"),
  { authProvider: provider },
);

await client.connect(transport);

// Use the client
const tools = await client.listTools();
console.log(
  "Available tools:",
  tools.tools.map((t) => t.name),
);

await transport.close();
#### 使用 JWT 私钥
typescript
import {
  Client,
  PrivateKeyJwtProvider,
  StreamableHTTPClientTransport,
} from "@modelcontextprotocol/client";

const provider = new PrivateKeyJwtProvider({
  clientId: "my-service",
  privateKey: process.env.CLIENT_PRIVATE_KEY_PEM,
  algorithm: "RS256",
});

const client = new Client(
  { name: "my-service", version: "1.0.0" },
  { capabilities: {} },
);

const transport = new StreamableHTTPClientTransport(
  new URL("https://mcp.example.com/mcp"),
  { authProvider: provider },
);

await client.connect(transport);

// Use the client
const tools = await client.listTools();
console.log(
  "Available tools:",
  tools.tools.map((t) => t.name),
);

await transport.close();

客户端支持

NOTE

此扩展的支持情况因客户端而异。扩展为选择性启用,默认情况下从不激活。

查看客户端矩阵以了解各 MCP 客户端的当前实现状态。

相关资源

BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。