One2rule them all mcps
Skill yakhandler/one2rule_them_all/.claude/skills/one2rule_them_all-mcps
Two Claude Code Agent Skills that sync MCP server definitions and Agent Skills across every AI tool on your machine (Claude, Codex, Cursor, Gemini, Antigravity, .agents) — additively, in each tool's native format, with backups.
npx -y skills add yakhandler/one2rule_them_all --skill one2rule_them_all-mcpsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Merge and sync MCP server definitions across every MCP client config on the machine (Claude Desktop/Cowork, Claude Code, Codex, Gemini CLI, Antigravity, Cursor) so each client ends up with the full union of servers, written in that client's native format, with nothing lost. Use this whenever the user wants to reconcile, sync, merge, consolidate, copy, or "share" MCP servers between clients/apps/tools — e.g. "I added a server in Cursor but Claude Desktop doesn't have it", "get all my MCP servers into every tool", "my MCP configs are out of sync", "one config to rule them all", or any request involving MCP server lists drifting apart across clients. Trigger even if the user names only one or two clients or doesn't say the word "reconcile."
SKILL.md
14.3 KB, ~3.4k tokens by cl100k_base, as published. Nobody here has run it
Reconcile MCP Servers Across Clients
Each MCP client keeps its own list of MCP servers in its own file and format, so the lists drift: a server you add in Cursor never shows up in Codex, one you set up for Claude Desktop is missing from Gemini, and so on. This skill computes the union of every server across every client present on the machine and writes that complete list back into each client — in the format that client expects — without losing or silently changing anything.
All the real work is done by scripts/reconcile_mcp.py. Your job is to run it,
interpret its output for the user, and handle conflicts. Do not hand-edit config files
yourself — the script handles format conversion, file preservation, and backups
correctly, and hand-editing risks corrupting large files like ~/.claude.json or
Codex's config.toml.
What it guarantees
These properties are why the tool exists; keep them in mind when explaining results:
- No server is ever deleted. Every client ends with at least the servers it started with. The merge is purely additive (plus conflict resolution you approve).
- Only the MCP section is touched. Everything else in each file — Codex profiles,
Claude Code's
projects/history, Gemini settings, etc. — is preserved. Project-scoped servers inside~/.claude.json'sprojectsblock are intentionally left alone; only the top-level globalmcpServersis reconciled. - Every file is backed up before it's written (
<file>.bak-<timestamp>). - Conflicts stop the process. If the same server name has different definitions in two clients, the tool refuses to guess — it reports both and writes nothing until the user decides.
Workflow
1. Run a plan first (always)
Never start with --apply. Run the default dry-run so you and the user can see exactly
what would change:
python3 <skill_dir>/scripts/reconcile_mcp.py
Use
python3on macOS/Linux; on Windows usepython(orpy -3). The engine needs Python 3.11+ for Codex (stdlibtomllib); if launched on an older interpreter it auto-re-execs into the newestpython3.xon PATH. If none is found, the JSON clients still sync but Codex is skipped (with a message telling you how to fix it).
The script auto-discovers each client's config from standard locations (see
references/client-config-paths.md). It only considers clients whose config file
actually exists; ones that aren't installed are listed as skipped.
Read the output and summarize for the user: how many clients were found, how many unique
servers make up the union, and which servers are missing from which clients. The
"Per-client plan" section shows + add, ~ change, and = unchanged counts per client.
2. Handle conflicts (exit code 2)
If the report shows BLOCKING CONFLICTS (and the script exits with code 2), do not
apply anything by default. Show the user the conflicting definitions the script printed
(it also prints a ready-to-use --prefer suggestion and lists the clients involved) and
ask how they want to resolve each one. There are three ways forward:
- Pick a winning client — re-run with
--prefer, a comma-separated priority list of client keys. For each conflicting name, the first client in the list that defines it wins. Example:--prefer cursor,claude-codemeans "use Cursor's version; if Cursor doesn't have it, use Claude Code's." - Edit to match — the user edits one config so both definitions are identical, then you re-run the plan and the conflict disappears.
- Skip them for now — re-run with
--skip-conflictsto sync everything except the conflicting names, leaving each client's own copy of those untouched (nothing is overwritten or deleted). The conflicts are still reported and the exit code stays 2 so they aren't forgotten. Good when the user wants the non-conflicting servers in place immediately and will reconcile the rest later. Confirm with the user before using it, since it leaves real divergence unresolved.
When only one or two servers are the problem, prefer the per-server flags over the
blunt --skip-conflicts (which skips every conflict). These can be combined in one run:
--skip-servers <name[,name...]>— leave those servers completely untouched in every client (each keeps its own copy); they never block the run and don't count toward the exit code. This is the right tool for app-managed servers a tool regenerates on its own. The canonical example isnode_repl: Codex and Antigravity rewrite it per install with machine-specific binary paths and a session pipe, so it can't be unified and shouldn't be — when you seenode_replas the only remaining conflict, the expected resolution is simply--skip-servers node_repl.--pin <server>@<client>— keep one client's copy of a server as-is (never changed, never added there) while still syncing that server to the other clients. Use when a single client intentionally needs a different definition (a different transport, account, or credential) than everyone else.--prefer-server <server>=<client>[,client]— pick the winner for one specific server, overriding the global--preferorder. Handy when different servers should be won by different clients in the same run.
Valid client keys: claude-desktop, claude-code, codex, gemini, antigravity,
cursor, agents. Resolving a conflict by preference will change the losing clients'
entries to match the winner — call that out explicitly before applying, since it's the one
case where an existing definition gets overwritten.
agents is the vendor-neutral .agents standard config at
~/.agents/mcp.json (same mcpServers JSON schema). It's a first-class source and
destination and is created if missing, so the standard location always exists.
3. Apply on confirmation
Once the plan looks right and any conflicts are resolved, get the user's go-ahead and
run with --apply (carry over the same --prefer you used in the plan):
python3 <skill_dir>/scripts/reconcile_mcp.py --apply [--prefer <keys>]
Report back: which files changed, what was added to each, and where the backups were written. Remind the user that clients which were running may need a restart to pick up the new servers.
Useful options
--prefer <keys>— priority order to auto-resolve name conflicts (see above).--skip-conflicts— sync the non-conflicting servers and leave conflicting names alone instead of blocking the whole run (see above). Exit code stays 2; nothing is overwritten.--skip-servers <names>— leave specific server names untouched everywhere (each client keeps its own); they never block the run. For app-managed servers likenode_repl.--pin <server>@<client>— keep that client's own copy of the server, while still syncing it to the others. Repeatable; comma-separated tokens allowed.--prefer-server <server>=<client>[,...]— per-server winner, overriding--preferfor that one server. Repeatable.--only <keys>/--exclude <keys>— limit which clients participate. Use--excludeif the user wants to leave a particular client out of the sync.--create-missing— also create config files for clients that don't have one yet. Off by default, because fabricating a config for an app that isn't installed is usually not what the user wants. Only use it if they explicitly ask to set up a client that has no config.--json— machine-readable summary instead of the text report; handy if you need to reason programmatically about the plan before deciding next steps.--home,--appdata,--localappdata— override path roots (used for testing; not needed in normal runs).
Things worth knowing
- Cosmetic differences are normalized away so they don't surface as false conflicts.
The tool compares servers by their functional definition and ignores fields that are
defaults or client-specific decoration:
type: "stdio"— a command-based server is stdio by definition; Antigravity records it explicitly, others omit it. Dropped for comparison, re-added only when writing Antigravity.enabled: true— the universal default (noenabledkey = enabled).enabled: falseis meaningful and kept.gallery/version— GitHub MCP-registry provenance some installers stamp on and Antigravity strips; the real version lives in the command/args, so these are noise.- Remote transport —
{type:"http", url}, a bare{url}, and Antigravity's{serverUrl}for the same endpoint compare equal. On write, each client gets its native shape (type+urlfor most,serverUrlfor Antigravity). An explicittype:"sse"is a real transport difference and is kept. Existing entries are never reflowed just to shed these — a client is only rewritten when it has a genuine add/change, and pinned /--skip-servers/ unresolved entries are written from their raw original, not the normalized form.
- Codex is the only non-JSON target. Its
config.tomluses anmcp_serverstable with snake_case. The tool reads it with stdlibtomllib, surgically replaces just the[mcp_servers.*]tables, and leaves the rest of the file (comments, model settings, profiles) intact. - JSON files are edited surgically. Only the top-level
mcpServersvalue is replaced in the raw text (or inserted if absent); every other byte — other keys, whitespace, key order, even project-scoped servers underprojects.*.mcpServers— is left exactly as it was. This matters most for~/.claude.json, which holds auth tokens and a lot of other state. The replaced block is re-serialized to match the file's own indentation. The edit is verified by re-parsing before writing; if that ever fails (it shouldn't), that file is left untouched and reported rather than reformatted — the run exits non-zero (code 3) and the other clients still sync. Tell the user which file was skipped so they can re-run or report it. - Scope is the six clients above, global configs only. Project-local configs (e.g. a
.cursor/mcp.jsoninside a repo, or per-project servers in~/.claude.json) are out of scope and untouched.
Running the same server twice (aliasing for multiple accounts)
An entry's key ("supabase-personal", "marq-snowflake", …) is an arbitrary label you
choose — nothing validates it against the package or env underneath. So you can point
several keys at the same MCP package with different settings, and they all run side by
side. The common case is one account per key:
"supabase-work": { "command": "npx", "args": ["-y", "@supabase/mcp-server-supabase@latest"],
"env": { "SUPABASE_ACCESS_TOKEN": "sbp_…work" } },
"supabase-personal": { "command": "npx", "args": ["-y", "@supabase/mcp-server-supabase@latest"],
"env": { "SUPABASE_ACCESS_TOKEN": "sbp_…personal" } }
Why this works, and how to do it cleanly:
- A credential is fixed at launch. A server reads its token from
envonce when it starts — there's no runtime account switch — so two accounts genuinely need two entries. - Tools are namespaced by key. The client exposes each entry's tools as
mcp__<key>__<tool>, somcp__supabase-work__execute_sqlandmcp__supabase-personal__execute_sqlnever collide. Name keys by account/purpose so both you and the agent can tell them apart. - Keys must be unique per file (it's a dict — a duplicate silently overwrites) and
should stick to
[A-Za-z0-9_-], since the key becomes part of the tool names. - Reconciling treats aliases as ordinary, distinct servers. To have an alias in every
client, just let the union spread it. To keep one alias in only one client (e.g. a work
account only in Claude Code), that's an intentional divergence —
--pin <alias>@<client>the others, or--skip-servers <alias>, so a later run doesn't copy it everywhere.
Creating aliases with scripts/clone_server.py
To avoid hand-editing every client to set this up, use the companion clone_server.py.
It duplicates an existing server into new aliased entries across clients, applying field
overrides, in each client's native format — reusing reconcile's writers, adaptation, and
.bak-<stamp> backups, with the same dry-run-first / --apply flow. Run a plan first.
# Split one entry into two account-scoped aliases everywhere, dropping the original:
python <skill_dir>/scripts/clone_server.py --from supabase-mcp-server \
--to supabase-work --set supabase-work.env.SUPABASE_ACCESS_TOKEN=sbp_work \
--to supabase-personal --set supabase-personal.env.SUPABASE_ACCESS_TOKEN=sbp_personal \
--remove-source --apply
Key points:
--from <name>is the template (resolved from whichever client has it; if it differs across clients, pass--from-client <key>to choose).--to <name>is repeatable.--set <alias>.<field.path>=<value>overrides a field on one alias (the first segment is the alias name; the rest is a dotted path, e.g.env.SUPABASE_ACCESS_TOKEN). Values are strings; prefix withjson:for a non-string (--set a.disabled=json:true).--clients <keys>limits which clients are written (default: all that exist).--remove-sourcedeletes the--fromserver after creating the aliases — the one delete in the toolkit, opt-in, still backed up. Omit it to keep the original alongside the copies.- Existing alias names are not clobbered unless you pass
--force.
For the exact paths, formats, and per-client quirks, see
references/client-config-paths.md.
What ships with it: 5 files
78.0 KB alongside SKILL.md, 4 of them executable
references/
- client-config-paths.md5.2 KB
scripts/
- clone_server.pyruns12.1 KB
- reconcile_mcp.pyruns47.5 KB
tests/
- test_clone.pyruns6.5 KB
- test_reconcile.pyruns6.7 KB
Gives 0 of the 12 instructions most mcp tooling skills give in ~3.4k tokens
Counted across 638 of the 750 authors here whose files we hold, read 2026-08-07
- Create ten complex or independent read-only evaluation questionsin 69 of 638, across 15 files
- Test servers using MCP Inspectorin 61 of 638, across 19 files
- Provide actionable error messages with specific next stepsin 54 of 638, across 12 files
- Prioritize comprehensive API coverage over specific workflows or workflow toolsin 54 of 638, across 12 files
- Use TypeScript and Streamable HTTP for remote servers or clientsin 54 of 638, across 8 files
- Define structured output schemas where possiblein 50 of 638, across 8 files
- Use Zod or Pydantic for input schemasin 47 of 638, across 5 files
- Fetch MCP specification pages with markdown suffixin 46 of 638, across 4 files
- Load framework documentation using WebFetchin 45 of 638, across 3 files
- Verify each evaluation answer independentlyin 45 of 638, across 3 files
- Implement API client with authentication and paginationin 45 of 638, across 3 files
- Define input schemas with validationin 27 of 638, across 9 files
Said here and by no other author read
- summarize the dry-run plan for the user
- ask the user to resolve any blocking conflicts
- apply changes only after explicit confirmation
- carry over conflict flags when applying
- skip app-managed servers like node_repl
- use --prefer to specify winning clients
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.