每个用 AI Agent 的人都有一堆 API Key,但它们散落在各处。这是一个专门解决这个问题的开源工具。


问题:Agent 找不到自己的钥匙

你用过 Hermes、Claude Code、Cursor 这些 AI Agent 吗?

如果用过,你一定经历过这个场景:

  • OpenAI 的 key 写在 .env
  • ElevenLabs 的 key 写在 config.yaml
  • 某个搜索 API 的 key 写在代码里硬编码(别笑,真有人这么干)
  • 还有几个 key 根本忘了放在哪

Agent 需要调用一个 TTS 服务,它问你:“你有 ElevenLabs 的 key 吗?” 你翻了三个文件找到了,复制粘贴给它。下次它又问了。

这不是 Agent 笨,是你没有给它一个"钥匙柜"。

现有方案的尴尬

我调研了市面上的密钥管理工具:

HashiCorp Vault

企业级秘密管理,35k+ GitHub Stars。功能强大,但你需要:一个 Go 二进制文件、一个存储后端(Consul/PostgreSQL/S3)、一堆策略配置。对个人开发者来说,这就是用大炮打蚊子。

Infisical

开源密钥管理平台,26k+ Stars,做得很好。但它需要 PostgreSQL,有用户系统、团队协作、审计日志……你只是想让 Agent 能找到你的 API key,不需要这些。

.env 文件

最原始的方案。没有结构化,没有版本控制,没有搜索功能。Agent 读不了 .env,你得手动告诉它每个 key 在哪。

尴尬的现实是:个人开发者 / AI Agent 场景下,没有一个"刚好够用"的工具。

Keyring:给 Agent 设计的钥匙柜

所以我做了 Keyring

核心设计原则:

1. Agent 优先,MCP 原生

Keyring 的核心入口是 MCP(Model Context Protocol)。这意味着任何支持 MCP 的 Agent 都能直接调用它——不需要你手动复制粘贴 key,Agent 自己就能查。

8 个 MCP 工具:

  • list_keys — 列出所有 key,按平台/功能/状态过滤
  • get_key — 获取完整 key 详情(包含实际的 API key 值)
  • search_keys — 全文搜索
  • add_key — 添加新 key
  • update_key — 更新 key(自动保存版本)
  • revoke_key — 吊销 key(软删除)
  • get_versions — 查看版本历史
  • get_summary — 概览:总数、平台、标签

Agent 说"我要用 OpenAI 的 LLM 服务",Keyring 自动找到对应的 key。换 key 了?旧版本还在。

2. 零依赖,极简部署

一个 JSON 文件就是全部存储。不需要数据库,不需要 Redis,不需要任何外部依赖。

docker compose up -d

搞定。不需要数据库,不需要 Redis,存储就是一个 JSON 文件。

3. MCP 自动发现

这是我觉得最有意思的设计。Keyring 内置了 MCP 服务发现机制:

  • /.well-known/mcp — 机器可读的 JSON
  • /llms.txt — LLM 可读的 Markdown
  • HTML <link> 标签
  • HTTP Link 响应头

一个 Agent 首次访问你的 Keyring 服务,它能自动发现 MCP 端点在哪、有哪些工具可用。你不需要手动配置任何东西。

4. 版本控制

每次修改 key,旧版本自动保存。你可以看到一个 key 的完整变更历史:什么时候换的、为什么换的、旧值是什么。

这对 API key 轮换特别有用。

5. 软删除

吊销一个 key 不会真的删除它,只是标记为 revoked。万一需要恢复,一条命令的事。

安全?看你部署在哪

这是很多人关心的问题。

内网部署(推荐):如果你在 VMware 虚拟机、家庭 NAS、或者公司内网部署 Keyring,根本没有攻击面。不需要设置任何认证,Agent 直接用。

公网部署:如果你要把 Keyring 暴露到公网,必须加认证。最简单的方案是 Nginx 反代 + Basic Auth,或者用 Tailscale/WireGuard 建 VPN 通道。

你的 API key 是明文存储的。公网暴露 = 所有 key 泄露。

我做过的另一个项目 resume-maker 有完整的邀请码认证机制,可以参考。

技术栈

  • 后端:Node.js + TypeScript + MCP SDK
  • 前端:React 19 + Vite 7 + Tailwind CSS 4
  • 存储:JSON 文件(原子写入)
  • 部署:Docker / npm / stdio

两种运行模式:

  • HTTP 模式:WebUI + REST API + MCP,适合远程/局域网
  • stdio 模式:直接嵌入 MCP 客户端,适合本地使用

适合谁

  1. AI Agent 用户:你有多个 Agent 需要共享 API key
  2. 多 key 管理者:同一个平台有多个 key,需要版本控制
  3. 极简主义者:不想装 Vault / Infisical,只想要个够用的
  4. MCP 生态开发者:需要一个 key 管理的 MCP 服务

开源地址

GitHub: https://github.com/Leeson-Wong/Keyring

MIT 协议,随便用。


实测:让 AI Agent 自己来试用 Keyring

以下是一个真实 AI Agent(Claude Code)测试 Keyring 的完整过程。我只给了一个局域网地址,其余全靠它自己探索。所有敏感信息已脱敏。

第一步:自动发现

拿到地址后,Agent 第一个动作不是打开浏览器,而是直接探测服务端点:

curl http://192.168.x.x:5179/health
# → {"name":"keyring","version":"1.0.0","status":"running","keys":7}

curl http://192.168.x.x:5179/.well-known/mcp
# → 返回完整的 MCP 服务描述,包括 8 个工具、端点地址、认证方式

curl http://192.168.x.x:5179/llms.txt
# → 返回人类可读的 Markdown 文档

思考过程:Agent 说"先探测基本信息"——它并行发了 5 个请求(health、well-known、llms.txt、meta、首页),几秒内就摸清了整个服务的结构。这就是 MCP 发现机制的价值:Agent 不需要读文档,它自己就能找到路。

第二步:REST API 全链路测试

Agent 用 GET /api/keys 拿到了 7 条 key 的完整信息,然后逐个验证 CRUD:

# 创建
curl -X POST /api/keys -d '{"platform":"TestPlatform","function":"test","apiKey":"sk-test-xxx",...}'
# → 返回自动生成的 ID 和 name("TestPlatform-test")

# 更新(触发版本快照)
curl -X PUT /api/keys/{id} -d '{"notes":"Updated","tags":["test","updated"]}'
# → updatedAt 更新,versions 数组自动增加一条快照

# 查看版本历史
curl /api/keys/{id}/versions
# → 完整的版本链,每条包含 timestamp 和 snapshot

# 撤销(软删除)
curl -X DELETE /api/keys/{id}
# → status 变为 "revoked",revokedAt 时间戳记录

思考过程:Agent 创建了一条测试 key,更新它,检查版本历史,然后撤销。验证了整个生命周期。发现 updatedAtrevokedAt 都正确记录,版本快照也完整保留了修改前的状态。

第三步:MCP 协议验证

这是最关键的部分——Agent 通过 MCP 协议直接调用工具:

# 初始化握手
curl -X POST /mcp -H "Accept: application/json, text/event-stream" \
  -d '{"method":"initialize","params":{"protocolVersion":"2025-03-26",...}}'
# → SSE 格式响应,返回服务端能力声明

# 列出所有 key(掩码显示)
curl -X POST /mcp -d '{"method":"tools/call","params":{"name":"list_keys","arguments":{}}}'
# → Key 显示为 "cea3...AOeC",做了掩码处理

# 搜索
curl -X POST /mcp -d '{"method":"tools/call","params":{"name":"search_keys","arguments":{"keyword":"TTS"}}}'
# → 精准返回 2 条结果:TTS 语音合成、音乐生成

# 获取完整 key(明文,设计如此——Agent 需要实际使用 key)
curl -X POST /mcp -d '{"method":"tools/call","params":{"name":"get_key","arguments":{"id":"xxx"}}}'
# → 返回完整 API key 值

思考过程:Agent 第一次调用 MCP 时忘了加 Accept: text/event-stream 头,被服务端拒绝了。加上之后握手成功。然后它发现 MCP 工具的参数命名用了 snake_case(api_keykeyword),而 REST API 用 camelCase(apiKey)——这是因为 MCP 工具遵循 MCP 协议的命名规范,不是 bug。Agent 试错两次后搞清楚了,正确调用了所有工具。

第四步:发现的问题

Agent 在测试中发现了一些问题并直接反馈:

  1. 空 body 能创建 keyPOST {} 会生成一条名为 undefined-undefined 的空记录,没有输入校验。已被作者修复。

  2. list_keys 崩溃:MCP 的 list_keys 工具调用时内部报错 Cannot read properties of undefined。已被作者修复。

  3. REST 搜索/过滤不生效?search=TTS?platform=Pexels 参数被忽略,始终返回全部结果。MCP 的 search_keys 正常工作。待修复。

Agent 主动创建了测试数据,发现问题,验证修复后又把测试数据全部清理干净。

Agent 的总结

“核心流程验证通过:发现 → 列表 → 搜索 → 取值 → 新增 → 更新 → 版本回溯 → 撤销,整个链路跑通。MCP 协议交互正常,AI Agent 可以通过这套工具自主管理 API Key。”

整个过程我(人类)只说了一句话:“地址是 http://192.168.x.x:5179/”。其余全是 Agent 自己完成的——发现服务、理解结构、设计测试用例、执行验证、发现问题、清理数据。

这就是给 Agent 一个"钥匙柜"的意义。


如果你觉得有用,给个 Star 吧。有问题直接提 Issue。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐