多AI Agent零配置同步:MCP注册表统一管理Claude Code、Codex与Cursor 先问一句你现在手上一共维护着几个 AI 编码 agent 的配置我把自己机器上的 Claude Code、Codex、Cursor还有自己动手写的 Hermes Agent 全部折腾到“同一套 MCP 工具和技能同步可用”的状态之前光是 MCP server 地址就重复写了不下十遍。每次新增一个工具都要打开四个配置文件一个一个地加 JSON 片段改完还得记住每个工具各自的加载逻辑稍不留神就有一个 agent 还在用旧配置。后来我把整套流程重构成了“0 配置同步”的模式本机只维护一份 MCP 注册表所有 agent 全部从这里生成配置、共享技能。这篇文章把方案设计、落地脚本和踩过的坑完整写一遍希望能帮到同样在多个 agent 之间反复横跳的人。1. 先还原现场每个 agent 都在逼你维护一份独立配置1.1 四类配置文件四种不一样的脾气MCP 本身是一个协议但 MCP 的“配置表达”在不同的 agent 里并不统一。我这半年实测下来每个工具几乎都有自己的配置路径和格式偏好。Agent常见配置文件配置结构重点作用域Claude Code~/.claude.json或项目根目录的.mcp.jsonmcpServers里的 stdio 服务列表全局/项目级Codex~/.codex/mcp_config.jsonmcpServers对象字段与 Claude 接近但细节不同全局Cursor~/.cursor/mcp.json或项目根目录.cursor/mcp.jsonmcpServers对象带 enabled 开关全局/项目级Hermes Agent自定义目录比如~/.hermes/mcp.json完全由你定义取决于 agent 实现取决于你的 Hermes 设计我最早的做法很简单粗暴哪个 agent 缺工具就打开对应的配置文件往里粘一段。但时间一长问题就暴露了——不是“配置不会写”而是“重复配置的次数太多必然出错”。比如同一个 GitHub MCP server在四个地方各写一遍任何一处的地址、token、参数不一致都会导致行为差异。排查的时候还得先搞清楚“到底哪个 agent 读的是哪份文件”。1.2 技能skills本质上也属于配置MCP 解决的是“agent 能调用哪些外部工具”而技能skills解决的是“agent 知道怎么按固定流程完成任务”。技能通常是一组带描述的 Markdown 文件和目录结构agent 通过扫描技能目录来加载这些能力。不同 agent 对技能目录的支持差异很大有的有默认目录有的需要在配置里指定搜索路径有的甚至只认目录里的特定文件名比如SKILL.md。手动维护技能配置比维护 MCP 配置更隐蔽。MCP 不生效时工具调用会直接报错你很容易发现技能目录配置错了agent 只是“装不知道”行为上表现为“该会的技能不会了”排查成本反而更高。所以技能的同步不能靠“想起来就手动拷贝目录”必须有一个可控的机制。1.3 手动维护翻车的三个典型瞬间我可以毫不夸张地说只要你有两个以上 agent手动维护配置必然遇到下面三种情况第一新增 server 时漏改某个 agent。我遇到最典型的一次是给 Cursor 加了数据库 MCP但忘了同步 Claude Code结果同一天里两个 agent 对同一个数据库问题的处理结果完全不一样我还以为是自己 prompt 写得有问题。第二token 轮换后只更新了一处。很多 MCP server 通过环境变量注入认证信息比如GITHUB_PERSONAL_ACCESS_TOKEN。轮换 token 是常规操作但你会发现自己要在四个配置文件里找同一个环境变量少改一处就是一次静默故障。第三启用了过期的 server 地址。本地开发的 MCP server 换了端口或改了命令参数老配置往往还留在旧文件里agent 反复连接失败浪费大量排查时间。这些问题的根源都一样配置散落在多个 agent 各自维护的文件里没有“单一事实来源”。想根治就得让配置从“四处手写”变成“一处维护、全局生成”。2. 零配置同步的整体设计思路2.1 先拆概念“0 配置”不是不写配置“0 配置”这句话容易让人误解以为装完任何文件都不用写了。实际不是这样。这里的“0”指的是你不再需要针对每个 agent 逐一手工修改配置文件你只需要维护一份统一的注册表然后由脚本把这份注册表翻译成每个 agent 需要的内容。所以这里面其实是两种模式的取舍配置生成器模式用注册表文件作为唯一输入生成各 agent 的最终配置文件。优点是格式可控、diff 清晰缺点是生成后需要确认 agent 是否重新加载。共享路径/软链模式如果 agent 支持直接指定配置目录或技能目录就用软链把多个 agent 指向同一份内容。优点是真正的“零维护”缺点是取决于 agent 的加载实现有些 agent 会用realpath递归解析反而破坏软链。我最终的方案是混合模式MCP 配置用“生成器模式”技能目录用“软链模式”。MCP 的 JSON 格式每个 agent 不同硬用同一个文件不可能但技能目录本质就是一堆 Markdown完全可以用软链统一指向。这样既保证兼容性又减少生成器需要处理的内容。2.2 单一注册表的结构设计我建议把注册表放在~/.config/agent-mcp/registry.json。这个路径不属于任何特定 agent完全是自己定制的管理目录。注册表内部我分成两个部分mcpServers和skills。{ mcpServers: { github: { type: stdio, command: npx, args: [-y, modelcontextprotocol/server-github], env: { GITHUB_PERSONAL_ACCESS_TOKEN: your_token }, enabled: true, description: GitHub 仓库与 Issue 操作 }, playwright: { type: stdio, command: npx, args: [-y, playwright/mcplatest], enabled: true }, filesystem: { type: stdio, command: npx, args: [-y, modelcontextprotocol/server-filesystem, /path/to/projects] } }, skills: { source: ~/.agents/skills, targets: { claude: ~/.claude/skills, codex: ~/.codex/skills } } }注意我特意给每个 server 增加了description字段。JSON 本身不支持注释这个字段就承担了“后人理解这段配置是干嘛用的”这个职责。内部维护的注册表最大的敌人就是几个月后你自己看不懂它description 能帮你少踩很多坑。2.3 为什么选 JSON 而不是 YAML/TOML我并不是 JSON 的狂热粉丝。但选 JSON 只有一个原因所有 agent 的最终配置文件都是 JSON 格式。如果注册表本身用 YAML那生成器脚本里就要多一层 YAML 到 JSON 的转换而且 YAML 的缩进和类型转换容易在不知不觉间改变配置语义。注册表直接用 JSON生成器的工作就只剩下“读取 JSON、按模板输出 JSON”心智负担最小。另一个隐性好处是JSON 可以用jq工具在命令行直接校验和查询。每次改完注册表跑一句jq . ~/.config/agent-mcp/registry.json如果输出正常说明语法没有问题。这对后续自动化脚本非常友好。2.4 同步策略的取舍对照生成配置文件时我遇到过三种思路这里做个对照策略做法优点风险完全覆写每次用注册表整体覆盖目标配置保证目标文件与注册表绝对一致会抹掉 agent 侧手工追加的非 MCP 内容合并写入只覆盖注册表管理的字段保留其他字段兼顾手工配置需要针对每个 agent 写合并逻辑复杂度高软链共享直接让 agent 指向注册表派生目录最省事内容实时同步部分 agent 不支持或加载异常对大多数本地开发场景我推荐“完全覆写 备份轮转”的组合。先把目标文件复制成.bak再写入新配置一旦出问题可以秒回滚。合并写入看起来很美好但四个 agent 的配置结构不同合并逻辑每个都要单独维护反而违背了“0 配置”的初衷。3. 落地实现从注册表到四端同步3.1 初始化目录与注册表先把目录建好然后创建上面的registry.json。这个文件就是你之后唯一需要手工维护的东西。mkdir -p ~/.config/agent-mcp mkdir -p ~/.agents/skills mkdir -p ~/.local/bin我的习惯是把整个~/.config/agent-mcp和~/.agents/skills都纳入同一个 Git 仓库管理。这样注册表、技能、以及后面提到的脚本都能一起备份和版本回滚。如果你有个人 NAS 或私有 Git这个仓库还能让你在新电脑上一键恢复整套 agent 能力。3.2 同步脚本的核心逻辑我选择用 Node.js 写这个同步脚本主要是依赖少、JSON 原生支持好、跨平台也稳。脚本放在~/.local/bin/mcp-sync全局可执行。核心代码如下#!/usr/bin/env node const fs require(fs); const path require(path); const os require(os); const REGISTRY_PATH path.join(os.homedir(), .config, agent-mcp, registry.json); const registry JSON.parse(fs.readFileSync(REGISTRY_PATH, utf8)); const enabledServers Object.fromEntries( Object.entries(registry.mcpServers || {}) .filter(([name, conf]) conf.enabled ! false) ); function writeWithBackup(targetPath, content) { const fullPath path.resolve(targetPath); fs.mkdirSync(path.dirname(fullPath), { recursive: true }); if (fs.existsSync(fullPath)) { fs.copyFileSync(fullPath, ${fullPath}.bak); } fs.writeFileSync(fullPath, JSON.stringify(content, null, 2)); } // Claude Code 全局配置 writeWithBackup( path.join(os.homedir(), .claude.json), { mcpServers: enabledServers } ); // Codex 全局配置 writeWithBackup( path.join(os.homedir(), .codex, mcp_config.json), { mcpServers: enabledServers } ); // Cursor 全局配置 writeWithBackup( path.join(os.homedir(), .cursor, mcp.json), { mcpServers: enabledServers } ); // Hermes Agent 配置 writeWithBackup( path.join(os.homedir(), .hermes, mcp.json), { mcpServers: enabledServers } ); console.log(MCP registry synced to all agents.);这个脚本把每个 agent 的配置文件都完整覆写为注册表的内容并且每次写入前都会生成.bak备份。我实测下来这比手工编辑四个文件高效得多而且脚本可以随时跑跑完自动备份出问题直接cp xxx.bak xxx回滚。3.3 自动同步监听文件变化手动跑脚本已经能省 90% 的功夫但既然目标是“0 配置”最好连“跑脚本”这一步都省了。我这里用的是文件监听工具持续监控注册表文件的变化一变就自动执行同步脚本watchexec -w ~/.config/agent-mcp/registry.json ~/.local/bin/mcp-sync这样你只需要改注册表保存的那一瞬间脚本会自动把新配置推给所有 agent。但这里有个关键前提必须说清楚配置文件更新了不代表运行中的 agent 进程会自动重新读取。大部分 agent 都是在启动时加载配置所以你需要重启当前正在运行的 agent 会话或者使用它自身的 reload 命令。自动同步解决的是“配置一定是最新的”而不是“agent 运行时热更新”。理解了这一点你才不会在改完配置后发现 agent 没变化时产生困惑。如果你不想常驻 watcher也可以退而求其次用定时任务比如每 5 分钟同步一次。但我个人体验下来监听式方案更符合直觉——文件一改配置就已同步完成。3.4 新机器一键初始化这套方案的另一个隐藏福利是“换机零成本”。新机器上只要把 Git 仓库 clone 下来然后跑一次同步脚本所有 agent 的 MCP 配置就全部就位技能目录也通过软链指向统一位置。不需要回忆“Claude Code 的配置在哪、Codex 的配置在哪”不需要从旧电脑拷贝零散文件一次脚本解决。我把这步封装成一个bootstrap.sh#!/usr/bin/env bash set -euo pipefail git clone gityour-git-host:me/agent-mcp.git ~/.config/agent-mcp git clone gityour-git-host:me/agent-skills.git ~/.agents/skills mkdir -p ~/.local/bin ln -sf ~/.config/agent-mcp/mcp-sync.js ~/.local/bin/mcp-sync mcp-sync这里唯一要确认的是脚本里的同步逻辑要在目标机器上可执行。如果新机器没有 Node.js就得先把 Node 装好或者把脚本改写为纯 bash 加jq的实现。我的建议是别过度优化Node 是大部分开发机必备的运行时直接用就好。4. 各 Agent 工具的适配与验证4.1 Claude Code注意别和自带命令打架Claude Code 既支持通过配置文件加载 MCP也支持用claude mcp add这条命令动态添加。这两条路虽然最终效果类似但实现上会互相影响。我的建议是既然注册表方案已经接管了~/.claude.json就不要再用claude mcp add手工添加了否则你下次跑同步脚本的时候手工添加的内容会被整体覆写掉造成“我明明添加过怎么不见了”的困惑。验证方式也很直接在终端跑claude mcp list如果结果里能看到注册表中的 server就说明配置加载成功。这里需要提醒的是~/.claude.json里可能不只包含 MCP 配置Claude Code 的部分会话状态也在这个文件里。完全覆写前备份逻辑不能省。我在脚本里做了.bak备份但如果你之前用claude mcp add添加过不少内容第一次跑同步前最好手动备份一次。4.2 Codex注意配置目录要先存在Codex 的配置路径是~/.codex/mcp_config.json。这个文件不会自动创建第一次同步时如果~/.codex目录还不存在直接写文件会失败。我在脚本里已经用fs.mkdirSync(path.dirname(fullPath), { recursive: true })解决了这个问题但如果你是自己手工维护很容易在这一步踩坑。Codex 的另一个特点是它对stdio类型的 server 支持相对保守如果某个 server 的参数格式不正确它会在启动时标记为失败而不是直接忽略。排查时建议先看 Codex 的日志输出确认 MCP connected 的 server 数量和注册表是否一致。4.3 Cursor全局和项目级要分清Cursor 比较特殊它同时支持全局配置~/.cursor/mcp.json和项目级配置.cursor/mcp.json。我给注册表方案的默认选择是写全局配置因为大多数个人开发场景下你希望所有项目都能用到同一套 MCP 工具。但这里有个安全陷阱项目级配置会跟随项目进入 Git 仓库如果 MCP server 的配置里带有访问 token等于把密钥提交到代码库了。所以我建议项目级配置只放不需要认证的内网工具凡是带 token 的 server 一律放全局配置。同步脚本里的 Cursor 部分我只写全局路径不会碰任何项目内的.cursor目录。验证方式也简单在 Cursor 的 MCP 配置界面里能看到已启用的 server 列表确认范围是否和注册表一致。4.4 Hermes Agent如果你自己写 agentHermes Agent 这类自有 agent 是最灵活的因为它的配置结构完全可以由你说了算。我的做法是让 Hermes 直接读取注册表文件而不是生成一份副本。这样一来Hermes 自身就变成“零配置”的——它每次启动时加载~/.config/agent-mcp/registry.json天然和其他 agent 保持同步。如果你也在开发自己的 agent我强烈建议直接采用“读注册表”而不是“生成配置”的方式。因为自己写的 agent 不受第三方格式约束直接消费统一注册表就是最简洁的架构同时还能省掉一次脚本生成逻辑。等以后有其他团队合作再考虑把注册表转换为他们的标准格式。5. 技能Skills目录的同步方案5.1 Skills 的加载机制不同 agent 对技能的加载机制并不完全一致但主流做法都大同小异在规定目录下放置技能文件每个技能至少包含一个SKILL.md文件文件头通过 frontmatter 声明技能的名称、描述、适用场景。agent 启动时会扫描这些技能文件把它们作为候选能力注入到上下文中。我踩过最深的坑是有些 agent 会严格校验扫描目录必须是真实目录软链过去它会警告甚至忽略。最开始我用ln -s ~/.agents/skills ~/.claude/skills这条软链方案发现部分 agent 表现稳定部分 agent 完全不响应。后来我调整了方案优先在 agent 配置里通过字段指定技能目录路径不支持指定路径的 agent 才用软链。5.2 软链方案的注意点如果你决定用软链务必注意几点不要对技能根目录做软链后又往里面创建二级软链递归解析容易出问题。软链目标必须是绝对路径相对路径在 agent 切换工作目录时容易失效。清理旧软链时要用unlink而不是rm -rf防止误删源目录内容。我现在实际操作时技能目录的同步已经简化成注册表里的skills.targets字段脚本遍历目标列表用fs.symlinkSync保证软链存在。如果某个 agent 不支持软链就在生成器里把它对应的技能路径直接配置成~/.agents/skills。5.3 用 Git 管理技能内容技能文件本质上是文本天然适合用 Git 管理。我建议单独建一个agent-skills仓库把 SKILL.md 和相关辅助文件放进去本地 clone 到~/.agents/skills。每次修改技能后提交推送多台设备之间共享技能就变成了正常的 Git 操作。我还会在技能仓库里加一个简单的post-merge钩子每次git pull后自动执行一次同步脚本确保技能变更立刻反映到所有 agent。这样“技能同步”也基本做到了零手工干预。5.4 技能和 MCP 工具的能力边界最后说明一下为什么技能要单独管理。MCP 工具是确定性的函数式能力比如“读取文件”、“执行命令”、“调用 API”技能则是可复用的工作流提示比如“如何做一次 Code Review”、“如何整理一个项目结构”。两者在 agent 里的加载方式、生效机制都不同所以在注册表里它们也应该分开管理。我的注册表结构里mcpServers段落负责工具skills段落负责技能目录。这样读注册表的人一眼就能分清当前 agent 有哪些工具可用、有哪些流程模板可用。这种分离在后期的维护中非常重要你不用担心改技能同步逻辑时影响 MCP 配置反过来也一样。6. 常见问题与排查技巧实录6.1 配置改了但 agent 不生效这是我被问得最多的问题。改完注册表、跑完同步脚本agent 还是老样子。最常见的原因是agent 进程没有重新加载配置。解决办法是重启当前会话或者查看 agent 是否提供配置刷新命令。现象可能原因解决方式改注册表后 agent 无变化运行中的进程还在用旧配置重启 agent 会话新增 server 在其他 agent 可用某 agent 不可用该 agent 的配置文件没被正确生成检查对应路径的配置内容server 显示已连接但调用超时server 启动慢或网络受限检查 npx 下载缓存与网络6.2 JSON 的注释和尾逗号问题注册表和生成后的配置文件都是 JSON 格式JSON 标准不支持注释也不允许尾逗号。我在自己的注册表里用description字段代替注释已经足够清晰。如果你实在想在维护时写注释可以保留一份registry.jsonc作为源同步脚本在读取前先剥离注释再解析。但我建议别把流程搞复杂一个带 description 字段的纯 JSON 会省去很多麻烦。每次改完注册表在跑同步脚本之前先执行一次jq . ~/.config/agent-mcp/registry.json /dev/null echo ok这句命令能快速判断 JSON 是否合法。如果你手头没有 jq用 Node 一行的JSON.parse也可以。千万别拿一个语法错误的注册表直接喂给同步脚本不然备份没生成原配置还可能被写坏。6.3 路径与环境变量的常见坑MCP 配置里的路径解析是另一个高频坑点。~符号在很多配置里不会自动展开你得写完整绝对路径或者在脚本读取时用os.homedir()拼接。Windows 下还需要注意反斜杠转义路径建议用正斜杠绝大多数 agent 和 Node 运行时都兼容。环境变量部分要特别强调stdio 类型的 MCP server 在启动时会继承 agent 进程的环境变量。如果你在 shell 里通过export设置过 token在终端启动 agent 通常没问题但如果你从 GUI 启动 agent比如 macOS 的应用程序方式启动 Cursor它可能读不到~/.bashrc或~/.zshrc里的导出项。解决方案就是把关键环境变量直接写进注册表的env字段让同步脚本统一注入到每个配置文件。6.4 团队协作时的 token 与作用域问题这套方案沉淀下来后大概率会被团队成员拿去复刻。这时候必须做两件事第一注册表仓库里绝对不能出现真实 token。所有敏感值一律用占位符比如${GITHUB_TOKEN}同步脚本从本机环境变量读取后替换。这样仓库可以放心推到远端token 只存在于各人自己的环境里。第二明确哪些配置是全局的、哪些是项目级的。个人工具走全局配置团队共享工具走项目级配置但项目级配置要加入.gitignore防止 token 泄漏。这个原则在 Cursor 场景里尤其重要否则你一不小心就把带密钥的配置提交上去了。6.5 同步过程自身出问题的兜底脚本本身也会出故障备份机制就是最后的救命稻草。我在脚本里每次写入都会生成.bak文件但这还不够。我后来加了一个--dry-run参数只比较注册表生成的预期内容与当前配置文件的差异不会真正写入。这样在批量升级脚本逻辑时可以先看 diff 再决定是否执行。如果你和我一样用监听模式自动同步建议把 watcher 和脚本的日志独立输出到文件比如~/.agents/logs/mcp-sync.log。出问题时翻日志比猜原因高效得多。同步这类自动化操作最忌讳的是“黑盒执行”——脚本一旦自动化运行的透明度必须跟上否则它反而会成为新的不确定因素。这套方案我从单机四 agent 用到现在最大的感受是配置管理这件事重要的不是你会不会写某个 agent 的配置而是你能不能少写。新人接手环境时不需要再问“这个 MCP 配在哪”只需要 clone 仓库、跑一次同步脚本整个世界就安静了。如果你也在多个 agent 之间折腾配置我建议先把注册表建立起来哪怕最开始只放两个 server也比继续在四个文件里来回手工编辑强。等跑顺了你会回来感谢这份“单一来源”的。