MCP 动态 Token 注入:企业级认证的下一步

背景:MCP 的认证现状

MCP(Model Context Protocol)连接 AI 工具和外部服务时,HTTP 传输层需要认证。目前绝大多数客户端(Claude Code、OpenClaw 等)的做法是静态 headers

json 复制代码
{
  "mcpServers": {
    "jina": {
      "type": "http",
      "url": "https://mcp.jina.ai/v1",
      "headers": {
        "Authorization": "Bearer jina_6b..."
      }
    }
  }
}

简单直接,但有三个企业场景下的硬伤:

问题 说明
Token 明文暴露 配置文件里躺着长期有效的密钥,泄露即全损
无法自动轮换 短期 Token(OAuth、SSO)过期后必须手动更新
多服务器管理成本 10 个 MCP 服务器 = 10 份独立的认证配置

Claude Code 的解法:headersHelper

Claude Code 在 v2.1.85 引入了 headersHelper 机制------用外部脚本动态生成认证头

工作原理

ini 复制代码
Claude Code 启动
  → 发现 MCP 服务器配置了 headersHelper
  → 注入环境变量:
      CLAUDE_CODE_MCP_SERVER_NAME=gitlab
      CLAUDE_CODE_MCP_SERVER_URL=https://gitlab.example.com/mcp
  → 执行指定脚本(10 秒超时)
  → 脚本输出 JSON 到 stdout
  → 将输出合并为 HTTP 请求头
  → 连接 MCP 服务器

配置方式

json 复制代码
{
  "mcpServers": {
    "gitlab": {
      "type": "http",
      "url": "https://gitlab.example.com/mcp",
      "headersHelper": "/opt/bin/mcp-auth.sh"
    }
  }
}

脚本规范

输入:通过环境变量传入

环境变量
CLAUDE_CODE_MCP_SERVER_NAME 配置中的服务器名(如 gitlab
CLAUDE_CODE_MCP_SERVER_URL 服务器 URL

输出:stdout 输出一个 JSON 对象(string key-value)

json 复制代码
{"Authorization": "Bearer eyJhbGciOi..."}

约束

  • 在 shell 中执行,超时 10 秒
  • 每次连接(启动和重连)都会重新执行,无缓存
  • 动态 headers 覆盖同名静态 headers

实际示例:一个脚本管所有服务器

bash 复制代码
#!/bin/bash
# /opt/bin/mcp-auth.sh

case "$CLAUDE_CODE_MCP_SERVER_NAME" in
  gitlab)
    # 从 macOS Keychain 取 token
    TOKEN=$(security find-generic-password -s "mcp-gitlab" -w)
    ;;
  jira)
    # 从 HashiCorp Vault 取 token
    TOKEN=$(vault kv get -field=token secret/mcp/jira)
    ;;
  internal-api)
    # 调 SSO 接口获取短期 token
    TOKEN=$(curl -s https://sso.corp.com/oauth/token \
      --data "grant_type=client_credentials&client_id=mcp" \
      -u "$USER:$(cat ~/.sso-secret)" | jq -r '.access_token')
    ;;
  *)
    echo '{}' && exit 0
    ;;
esac

echo "{\"Authorization\": \"Bearer $TOKEN\"}"

所有服务器指向同一个脚本:

json 复制代码
{
  "mcpServers": {
    "gitlab":       { "url": "...", "headersHelper": "/opt/bin/mcp-auth.sh" },
    "jira":         { "url": "...", "headersHelper": "/opt/bin/mcp-auth.sh" },
    "internal-api": { "url": "...", "headersHelper": "/opt/bin/mcp-auth.sh" }
  }
}

更多玩法

从 AWS Secrets Manager 取 token:

bash 复制代码
#!/bin/bash
SECRET_NAME="mcp/$CLAUDE_CODE_MCP_SERVER_NAME"
TOKEN=$(aws secretsmanager get-secret-value \
  --secret-id "$SECRET_NAME" \
  --query SecretString --output text | jq -r '.token')
echo "{\"Authorization\": \"Bearer $TOKEN\"}"

从 1Password CLI 取 token:

bash 复制代码
#!/bin/bash
TOKEN=$(op read "op://MCP/$CLAUDE_CODE_MCP_SERVER_NAME/token")
echo "{\"Authorization\": \"Bearer $TOKEN\"}"

内联写法(简单场景):

json 复制代码
{
  "headersHelper": "echo '{\"Authorization\": \"Bearer '\"$(op read op://MCP/jina/token)\"'\"}'"
}

这不是 MCP 官方标准

需要明确:headersHelper 是 Claude Code 的私有扩展,不是 MCP 协议标准的一部分。

MCP 标准只定义了:

  • headers:静态 key-value 头
  • OAuth 2.1 流程(RFC 8414 发现 + PKCE)

headersHelper 这种"委托外部脚本生成认证头"的模式,有可能成为事实标准------因为它解决了 OAuth 覆盖不到的场景(Kerberos、mTLS token、企业 SSO、Vault 集成等)。

OpenClaw 的现状与改造思路

OpenClaw 目前 只支持静态 headers,不支持动态生成。相关 Issue(#61611)已提出需求,但尚未实现。

要实现类似 headersHelper 的能力,需要改造的核心路径:

1. 配置层:扩展 MCP server schema

mcp.servers 的配置结构中增加 headersHelper 字段:

typescript 复制代码
// 当前
interface McpServerConfig {
  url: string;
  headers?: Record<string, string>;
  transport?: 'sse' | 'streamable-http';
}

// 改造后
interface McpServerConfig {
  url: string;
  headers?: Record<string, string>;
  headersHelper?: string;             // 新增:外部脚本路径或内联命令
  transport?: 'sse' | 'streamable-http';
}

2. 运行时:MCP 客户端连接前执行脚本

在 MCP 客户端建立 HTTP 连接之前,检查是否配置了 headersHelper,如果有:

c 复制代码
读取 headersHelper 配置
  → spawn 子进程执行脚本
  → 注入环境变量(服务器名、URL)
  → 捕获 stdout,解析 JSON
  → 与静态 headers 合并(动态优先)
  → 传递给 HTTP 客户端

核心伪代码:

typescript 复制代码
async function resolveHeaders(serverName: string, config: McpServerConfig) {
  const staticHeaders = config.headers ?? {};

  if (!config.headersHelper) return staticHeaders;

  const { stdout } = await execWithTimeout(config.headersHelper, {
    env: {
      ...process.env,
      MCP_SERVER_NAME: serverName,      // OpenClaw 可以用自己的变量名
      MCP_SERVER_URL: config.url,
    },
    timeout: 10_000,
  });

  const dynamicHeaders = JSON.parse(stdout);
  return { ...staticHeaders, ...dynamicHeaders };  // 动态覆盖静态
}

3. 重连时刷新

MCP 连接断开重连时,需要重新执行 headersHelper(而不是复用上次的结果),确保短期 token 被刷新。

改造总结

模块 改什么 工作量
配置 schema 增加 headersHelper 字段
MCP 客户端 连接前执行脚本、解析输出、合并 headers
重连逻辑 重连时重新执行脚本
CLI 命令 openclaw mcp set 支持设置 headersHelper
文档 配置说明 + 脚本示例

核心改动集中在 MCP 客户端的 HTTP 传输层,是一个边界清晰、风险可控的改造。

相关推荐
iuyup2 小时前
拆解 Hermes Agent 学习闭环,用 LangGraph 实现 Self-Improving Agent 设计模式
agent
程序消消乐4 小时前
第一章:Claude Code 记忆系统——架构总览与四种记忆类型
大数据·架构·agent·claude code
程序消消乐4 小时前
第四章:Claude Code CLI中的CLAUDE.md 系统、团队记忆安全、配置开关与最佳实践
agent
qq_232045574 小时前
ai agent学习大纲
agent
程序消消乐7 小时前
第三章:Claude Code CLI 语义召回机制与后台自动抽取代理
agent·claude code
景同学8 小时前
MCP与CLI之争:AI Agent的协议之辩
人工智能·agent
Henrybit933688 小时前
如何构建高质量Skills?
人工智能·agent
景同学8 小时前
CLI化浪潮:三大企业办公平台的72小时开源赛
agent·mcp
前端双越老师9 小时前
为什么说 OpenClaw 应该装在自己的电脑上
人工智能·agent·全栈