site logo

Marico's space

ProxyKey MCP:让 AI Agent 获得 API 访问权限,却无需交出密钥

AI技术与应用 2026-09-14 20:56:24 11

最近在折腾 AI Agent 的安全问题,踩了一个挺有意思的坑:怎么让 Claude Code 或者 Cursor 这种 AI 编程助手调用第三方 API,但又不能把真实的密钥暴露给它们。Context 会记录日志这事大家都懂,但实际操作的时候怎么处理?ProxyKey MCP 就是奔着解决这个问题去的。这篇不讲大道理,只说实操:怎么连上、13 个工具都是啥、为什么故意不提供"读取密钥"这个操作,以及我们设计这套东西的典型场景——Agent 要部署一个还没有 token 的机器人。

为什么 Agent 需要的是 MCP 访问密钥库,而不是把 key 写进 .env

Claude Code 这类 Agent 会写入环境变量、改配置文件,有时候还会输出日志。凡是进了模型 context 的东西,都得当成已经公开了——上下文会被记录、追踪,还可能通过提示词注入被提取出来。把一个真实的 OpenAI API Key 或者 Telegram Bot Token 直接交给 Agent,跟把密钥交给网上随便一个脚本没什么区别。

ProxyKey MCP 服务在协议层面解决了这个问题,不是靠"相信 Agent 会遵守规则"这种策略。Agent 拿到的是工具,不是密钥。13 个方法里没有一个能返回密钥的明文值。Agent 可以创建、撤销、轮换凭证,查看限流和请求日志——但它读不到原始密钥,因为这个接口在 API 里根本不存在。

连接配置:Claude Code 和 Cursor

第一步需要人手动操作:登录 app.proxykey.org(GitHub OAuth 或者魔法链接,免费),打开 MCP 配置页面,创建一个 mcp_... 格式的 Token。只有这个 Token 给 Agent,真正的提供商密钥从来不离开你的控制。

Claude Code 配置,一条命令搞定:

claude mcp add --transport http proxykey https://mcp.proxykey.org/mcp \ --header "Authorization: Bearer mcp_YOUR_TOKEN"

Cursor 和 Claude Desktop 用 mcp.json 配置:

{ "mcpServers": { "proxykey": { "url": "https://mcp.proxykey.org/mcp", "headers": { "Authorization": "Bearer mcp_YOUR_TOKEN" } } }
}

配好之后,Agent 就能像调用其他 MCP 工具一样调用 ProxyKey 的接口,全程不需要人在旁边盯着。

13 个工具——为什么故意不提供"读取密钥"

  • 目录和元数据list_providers 列出提供商及其认证方式。list_secrets 显示存储的密钥,只返回元数据,值永远不暴露。get_manual_secret_setup 返回一个链接,让人类在面板里输入真实密钥。
  • 凭证管理create_passcreate_pending_passupdate_passrotate_passrevoke_passdelete_passrebind_pass_ip——虚拟令牌的完整生命周期。
  • 可观测性list_passesget_pass_logsget_pass_stats——Agent 可以查看每个凭证的状态、限流、IP 绑定和请求历史。

13 个操作里没有一个参数能返回密钥的明文。这不是"Agent 答应不看"的问题——那个能力根本不在 API 契约里。出于同样的原因,MCP 接口也不会开启请求体的日志记录,那个只能通过面板查看,否则 Agent 可以通过日志间接重建密钥。

pending-secret 场景:Agent 部署一个还没有 token 的机器人

这才是我们做这套东西的初衷。常见的纠结:Agent 在部署一个 Telegram Bot,写代码、接 Webhook——但 BotFather Token 还不存在,因为机器人还没创建。

正常流程是等人工介入,但 Agent 可以调用 create_pending_pass 直接生成一个凭证(vlt_... 格式)。这个凭证马上就能写入 Bot 配置——但真实流量会被拦截,状态是 original_key_required,直到有人补上真实的密钥。Agent 再调用 get_manual_secret_setup,把链接甩给人类。

人类打开面板,粘贴一次真实 Token,凭证自动激活——不需要 Agent 再调用任何东西。Bot 活了。整个过程 Agent 没见过密钥明文,密钥走的是面板通道,不是模型的 Context。

人类在面板里看到什么

面板是唯一出现真实密钥明文的地方——初始化设置或者补全 pending secret 都走这里。面板显示:已存储密钥列表(只有元数据,没有值)、凭证列表及状态/IP绑定/限流配置、每个凭证的请求日志——同样是元数据,不包含 Authorization 头和任何密钥材料。

分工很清晰:可能暴露密钥明文的操作,人类专用,走面板。Agent 日常需要的操作——创建、撤销、轮换、监控——全部通过 MCP 开放。

代理请求本身

凭证发出后,应用或 Agent 把请求地址改成代理,Host 和 Key 替换,其他不变——路径、请求体保持原样:

# 改之前
curl https://api.openai.com/v1/chat/completions -H "Authorization: Bearer sk-..."
# 改之后
curl https://api.proxykey.org/p/openai/v1/chat/completions -H "Authorization: Bearer vlt_openai_..."

流式响应(SSE)、请求体、Header 原样透传。Telegram Bot 保持原来的 URL 格式:/p/telegram-bot/<pass>/getMe

一个需要说清楚的限制

托管代理不可能是零知识的,这是设计决定的:要替客户端向提供商发请求,代理必须在处理请求的那一刻把密钥解密到内存里。也就是说,一个有完全访问权限的进程——顺带也包括服务运营商——原则上可以拿到明文。这不是 ProxyKey 的特有问题,是这类托管方案的共同属性。我们在安全页面详细解释过:加密实际防护的是什么(数据库泄露、被盗备份、日志泄露),以及不防护什么(服务器被完全攻破)。Agent 通过 MCP 访问并不会增加额外风险——实际上它的权限比人类通过面板访问更受限。

什么时候不需要这个

  • 一个密钥只给一个消费者用。如果密钥只在你自己完全控制的一个地方使用,没有任何 Agent 会碰到它,代理只是多了一个故障点,没什么实际好处。
  • 你的威胁模型不允许第三方出现在请求链里。代理能看到流量,即使它只记录元数据。如果这接受不了,自己实现这套架构,或者干脆不用。
  • 个位数毫秒的延迟真的重要。多一跳加上验证缓存查询会增加开销。对于 LLM 调用,这点延迟相对于生成时间可以忽略;但对于某些低延迟的非 LLM API 可能会影响明显——自己跑一下测试。

总结

核心逻辑很简单:密钥只进系统一次,走面板,之后再也不以明文形式离开服务端。Agent 拿到的工具接口是故意收窄的——自动化发放和管理访问权所需的能力全有,但任何可能通过 Context 泄露的能力全没有。对于那些自己部署服务和机器人的 Agent,这解决了最大的障碍——Agent 还没有密钥怎么办——而且全程不需要人在每个步骤介入。

ProxyKey 是 Hikmah Labs 的项目,一家小工作室。更多内容可以在官网了解。