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

Specification

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

它是什么

标准 MCP 授权流程要求用户以交互方式批准访问:浏览器打开,用户登录并授予权限。这对真人用户很合适,但在没有用户在场时就无法工作。 OAuth Client Credentials 扩展通过让客户端使用应用级凭据(client ID 和 secret,或签名 JWT assertion)而不是委托用户凭据来解决这个问题。客户端直接向授权服务器证明自己的身份,授权服务器无需浏览器重定向或用户交互即可签发 access token。

何时使用

以下场景适合使用 OAuth Client Credentials:
  • 后台服务需要按计划或响应事件调用 MCP tools,且没有用户在场
  • CI/CD 流水线需要在自动构建、测试或部署 workflow 中调用 MCP 服务器
  • 服务器到服务器集成需要连接两个后端系统,且不涉及最终用户
  • 守护进程或长时间运行的 worker 需要持续访问 MCP 资源
如果你的集成中存在应明确授权访问的真人用户,请改用标准 MCP 授权流程。

工作原理

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

JWT Bearer Assertions(推荐)

RFC 7523 定义的 JWT Bearer Assertions 允许客户端使用私钥签名 token,并将其作为身份证明提交。授权服务器使用客户端注册的公钥验证签名。 JWT assertion 通常包含:
  • iss: Client ID(签发者)
  • sub: Client ID(被认证的主体)
  • aud: 授权服务器 token 端点 URL
  • exp: 过期时间
  • iat: 签发时间

Client Secrets

对于更简单的部署,该扩展也支持使用 client_idclient_secret 的标准 client credentials 流程。客户端将凭据直接发送到授权服务器的 token 端点,并获得 access token。
Client secrets 是长期有效凭据,可在没有用户交互的情况下授予访问权限。如果 secret 泄露,攻击者可以静默地以你的应用身份完成认证,直到该 secret 被轮换。为降低风险:
  • 将 secrets 存储在 secrets manager 中,绝不要放在源代码或提交到版本控制的环境文件里。
  • 按固定计划轮换 secrets,并在怀疑泄露后立即轮换。
  • 将凭据 scope 限制到所需的最小权限。
  • 尽可能优先使用 JWT assertions,因为它们生命周期短,且不需要传输签名密钥。

实现指南

面向 MCP 客户端

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

声明支持

initialize 请求 capabilities 中包含该扩展:
{
  "capabilities": {
    "extensions": {
      "io.modelcontextprotocol/oauth-client-credentials": {}
    }
  }
}
2

获取 access token

连接 MCP 服务器前,使用 client credentials grant 从授权服务器请求 token。
3

携带 token

在发送给 MCP 服务器的 HTTP 请求中,通过 Authorization header 传递 token:
Authorization: Bearer <access_token>
4

处理 token 刷新

client credentials token 的生命周期通常短于用户委托 token。请实现 token 刷新逻辑,在过期前获取新 token。

面向 MCP 服务器

要接受 client credentials token,服务器必须:
1

验证 token

在每个请求中,使用授权服务器公钥验证 JWT 签名和 claims(通常通过 JWKS 端点)。
2

检查 scopes

确保 token 包含所请求操作所需的 scopes。
3

声明支持能力

可以在 initialize 响应中包含该扩展(为便于发现,建议这样做):
{
  "capabilities": {
    "extensions": {
      "io.modelcontextprotocol/oauth-client-credentials": {}
    }
  }
}

SDK 示例

官方 MCP SDK 内置支持 client credentials 认证,并会自动处理 token 获取和刷新。
1

安装 SDK

npm install @modelcontextprotocol/client
2

创建 provider 并连接

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

使用 client secret

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);

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

await transport.close();

使用 JWT 私钥

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);

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

await transport.close();

客户端支持

不同客户端对此扩展的支持情况不同。扩展需要显式启用,默认永远不会激活。
请查看客户端矩阵,了解各 MCP 客户端当前的实现状态。

相关资源

ext-auth 仓库

源代码和参考实现

完整规范

包含规范性要求的技术规范

RFC 6749 — Client Credentials Grant

底层 OAuth 2.0 规范

RFC 7523 — JWT Bearer Assertions

JWT assertion 格式规范