MCP(Model Context Protocol)连接 AI 工具和外部服务时,HTTP 传输层需要认证。目前绝大多数客户端(Claude Code、OpenClaw 等)的做法是静态 headers:
{
"mcpServers": {
"jina": { "type": "http", "url": "https://mcp.jina.ai/v1", "headers": { "Authorization": "Bearer jina_6b..." } }
} }
简单直接,但有三个企业场景下的硬伤:
Claude Code 在 v2.1.85 引入了 headersHelper 机制------用外部脚本动态生成认证头。
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 服务器
{
"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)
{"Authorization": "Bearer eyJhbGciOi..."}
约束:
- 在 shell 中执行,超时 10 秒
- 每次连接(启动和重连)都会重新执行,无缓存
- 动态 headers 覆盖同名静态 headers
#!/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"}"
所有服务器指向同一个脚本:
{
"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:
#!/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:
#!/bin/bash
TOKEN=\((op read "op://MCP/\)CLAUDE_CODE_MCP_SERVER_NAME/token") echo "{"Authorization": "Bearer $TOKEN"}"
内联写法(简单场景):
{
"headersHelper": "echo ‘{"Authorization": "Bearer ‘"$(op read op://MCP/jina/token)"’"}’" }
需要明确:headersHelper 是 Claude Code 的私有扩展,不是 MCP 协议标准的一部分。
MCP 标准只定义了:
headers:静态 key-value 头- OAuth 2.1 流程(RFC 8414 发现 + PKCE)
但 headersHelper 这种"委托外部脚本生成认证头"的模式,有可能成为事实标准------因为它解决了 OAuth 覆盖不到的场景(Kerberos、mTLS token、企业 SSO、Vault 集成等)。
OpenClaw 目前 只支持静态 headers,不支持动态生成。相关 Issue(#61611)已提出需求,但尚未实现。
要实现类似 headersHelper 的能力,需要改造的核心路径:
在 mcp.servers 的配置结构中增加 headersHelper 字段:
// 当前
interface McpServerConfig { url: string; headers?: Record
; transport?: ‘sse’ | ‘streamable-http’; }
// 改造后 interface McpServerConfig { url: string; headers?: Record
; headersHelper?: string; // 新增:外部脚本路径或内联命令 transport?: ‘sse’ | ‘streamable-http’; }
在 MCP 客户端建立 HTTP 连接之前,检查是否配置了 headersHelper,如果有:
读取 headersHelper 配置
→ spawn 子进程执行脚本 → 注入环境变量(服务器名、URL) → 捕获 stdout,解析 JSON → 与静态 headers 合并(动态优先) → 传递给 HTTP 客户端
核心伪代码:
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 }; // 动态覆盖静态 }
MCP 连接断开重连时,需要重新执行 headersHelper(而不是复用上次的结果),确保短期 token 被刷新。
headersHelper 字段 小 MCP 客户端 连接前执行脚本、解析输出、合并 headers 中 重连逻辑 重连时重新执行脚本 小 CLI 命令
openclaw mcp set 支持设置 headersHelper 小 文档 配置说明 + 脚本示例 小
核心改动集中在 MCP 客户端的 HTTP 传输层,是一个边界清晰、风险可控的改造。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/252567.html