DEV Community

hao li
hao li

Posted on

I pasted the same MCP server into 4 config files. Then I wrote a tool to clean up the mess.

I pasted the same MCP server into 4 config files. Then I wrote a tool to clean up the mess.

If you use Claude Desktop, Cursor, VS Code, and Codex side by side, your MCP setup is probably a mess. Mine was. The same filesystem server lived in three different config files. One copy had different args than the others. And one entry pointed at a command I'd uninstalled months ago — a dead link sitting there silently.

Editing four JSON/TOML files by hand to fix this is nobody's idea of fun. So I built mcp-config-dedupe: a stdlib-only Python CLI that scans every client config, reports duplicates, drift, and dead links, and dedupes them in one command.

What it does

# Scan all clients (read-only) and print findings
mcp-dedupe scan

# Preview what dedupe would change (default; writes nothing)
mcp-dedupe dedupe

# Actually dedupe — backups first, explicit confirmation required
mcp-dedupe dedupe --apply --yes
Enter fullscreen mode Exit fullscreen mode

A typical scan looks like this:

MCP config scan
============================================================
- claude-desktop  3 server(s)
- cursor          2 server(s)
- vscode          1 server(s)
- codex           2 server(s)
------------------------------------------------------------
[DUPLICATE] filesystem (claude-desktop, cursor, codex): identical config in multiple clients; safe to dedupe
[DRIFT] brave-search (claude-desktop, vscode): same name but different config across clients
[DEAD-LINK] old-tool (cursor): command not found on PATH: old-tool-bin
Enter fullscreen mode Exit fullscreen mode

Three kinds of rot, three responses:

  • DUPLICATE — same name, byte-identical config in multiple clients. Dedupe keeps one canonical copy (priority: Claude Desktop → Cursor → VS Code → Codex, overridable with --prefer) and removes the rest.
  • DRIFT — same name, different config. This is the dangerous one: which copy is "right" is a judgment call, so the tool only reports it by default. Pass --include-drift (plus --prefer <client> to pick the winner) to resolve it.
  • DEAD-LINK — the configured command isn't on PATH or the path doesn't exist, or cwd is gone. Reported always; removed only with --prune-dead.

The safety model

Config-writing tools earn trust by being boring about safety:

  1. scan and default dedupe (dry-run) never write anything.
  2. --apply refuses to run without --yes.
  3. Every touched file is backed up to ~/.mcp-dedupe/backups/<timestamp>/ before rewriting.
  4. Only configs that parsed cleanly are ever rewritten; malformed files are reported as UNREADABLE and left alone.
  5. Drifted duplicates are never auto-merged.

How it's different

  • vs config security auditors (e.g. mcp-audit-tool): auditing tells you a config looks risky. This tool takes action — it removes the duplicate and dead entries across clients in one command.
  • vs editing JSON by hand: one scan gives you a unified cross-client view with drift highlighted, instead of diffing four files in four different locations.
  • vs merge-everything sync tools (e.g. mcp-config-sync): syncing unions every server into every client. Dedupe does the opposite job — collapse redundant copies to one canonical entry and prune what's dead.

Notes

  • Stdlib only: argparse, json, tomllib, shutil, pathlib. No dependencies, no network calls, no telemetry.
  • Codex's ~/.codex/config.toml is parsed with tomllib; a minimal built-in TOML emitter writes it back (backups taken first, as always).
  • URL-based (remote) servers are listed as REMOTE for visibility but never flagged dead — they can't be verified offline.
  • 14 smoke tests, all green. python3 -m unittest discover -s tests -v.

If your MCP configs have quietly rotted across clients, pip install mcp-config-dedupe and run mcp-dedupe scan. You might be surprised what's in there.

Top comments (0)