No AI coding tool reads another tool's MCP configuration. Claude Code, Cursor, and Windsurf each keep their own file in their own location, so adding one MCP server means editing three of them — four if you also run Claude Desktop. There are exactly two ways to configure a server once: keep a single source of truth and sync copies into every file, or run a local MCP hub — one endpoint that aggregates your servers, which each client connects to once and then never needs updating again.
This guide covers where each config file actually lives, the specific mechanisms that make the copies drift apart, and how to set up the one-endpoint approach on macOS.
Where each tool stores its MCP config
These are the paths as of August 2026, taken from each vendor's current documentation:
| Tool | Config file | Top-level key |
|---|---|---|
| Claude Code — user scope | ~/.claude.json | mcpServers |
| Claude Code — local scope (default) | ~/.claude.json, nested under the project's path | mcpServers |
| Claude Code — project scope | .mcp.json in the project root | mcpServers |
| Cursor — global | ~/.cursor/mcp.json | mcpServers |
| Cursor — project | .cursor/mcp.json | mcpServers |
| Windsurf (Cascade) | ~/.codeium/windsurf/mcp_config.json | mcpServers |
| Claude Desktop (macOS) | ~/Library/Application Support/Claude/claude_desktop_config.json | mcpServers |
The shared mcpServers key is why copy-paste mostly works, and why people assume this problem is smaller than it is. Claude Code alone accounts for three of those rows: it supports three installation scopes — local (the default, private to you in one project), project (.mcp.json, committed to version control), and user (available across all your projects).
One navigation note: Windsurf's MCP documentation now redirects to Cognition's Devin docs domain, where the page covers Cascade alongside the Devin Desktop naming. The config path itself is unchanged.
Why the copies drift
Duplication isn't the actual problem. Duplication that silently diverges is. Four mechanisms do most of the damage:
1. Claude Code resolves duplicate names by precedence, and does not merge
When the same server name is defined at more than one scope, Claude Code connects once using the highest-precedence definition: local beats project, project beats user. Critically, the entire entry from the winning scope is used — fields are not merged across scopes.
So if you rotate an API key in your committed .mcp.json, but an older local-scoped entry with the same name still sits in ~/.claude.json, the local one wins and your agent keeps using the stale credential. Nothing warns you, because from Claude Code's perspective nothing is wrong. Run claude mcp list to see what actually resolved.
2. Remote-server key names differ between clients
For stdio servers every client takes command and args, so copy-paste is safe. Remote servers are where it breaks. Claude Code and Cursor use url (Claude Code pairs it with a type field), while Windsurf's documented example uses serverUrl. Paste a Cursor block into Windsurf and it may simply not connect.
3. Transport names are moving
Claude Code's docs now state plainly that the SSE transport is deprecated and to use HTTP servers where available. It also accepts streamable-http as an alias for http, so configurations copied straight from a server's own README work unmodified. A config file you wrote a year ago will still work, but it won't match what today's docs tell you to write — and the next person to copy from it inherits that.
4. Every client pays for every server, and their budgets differ
Because each client loads its own copy of the full list, each one also absorbs the full tool count. Windsurf's docs state that Cascade has a limit of 100 total tools available at any given time. Claude Code takes a different tack: it warns when a single MCP tool's output exceeds 10,000 tokens and caps output at 25,000 tokens by default, adjustable via MAX_MCP_OUTPUT_TOKENS. Adding one chatty server to all four files pushes on four different limits at once.
Option 1: one source of truth you sync into each file
The lowest-tech fix is to keep a canonical mcpServers block somewhere you control — a dotfiles repo, a shell script, a Makefile target — and write it into each client's file.
This is a legitimate answer, and it costs nothing to adopt. It has two honest limits. First, you own the sync forever, including the per-client key differences above; the moment anyone hand-edits one file, drift restarts. Second, it doesn't change the runtime picture at all — every client still spawns its own copy of every stdio server, so four clients running a filesystem server means four processes and four full tool lists.
Option 2: one endpoint every client points at
The other approach is to stop distributing the list. A personal MCP hub is itself an MCP server, but instead of exposing its own tools it connects to your upstream servers and re-exposes their tools behind a single endpoint. Each client is configured exactly once, with one entry, and never touched again. Adding, removing, or re-keying a server happens in the hub, and every connected tool sees the change.
Tools are namespaced by server on the way through — a filesystem server's read_file becomes filesystem:read_file — so two upstream servers that both define search don't collide. We go deeper on the mechanics in the MCP Hub guide, and on how this compares to the other native Mac approaches in managing MCP servers in one place on Mac.
Pointing Claude Code, Cursor, and Windsurf at one hub
Here's the concrete setup with AppContext, which runs a hub as a macOS menu bar app and serves its endpoint at http://localhost:7777/sse.
Step 1 — get your existing servers into the hub. Rather than retyping them, AppContext's Servers tab imports from Claude Code (~/.claude.json), Claude Desktop, and Cursor (~/.cursor/mcp.json), and it also discovers project-level .mcp.json files under your usual code directories. Windsurf isn't an import source today, so if a server exists only in mcp_config.json, add that one by hand.
Step 2 — point each client at the hub. One entry each, then you're done.
Claude Code, at user scope so it applies to every project:
claude mcp add --transport sse --scope user appcontext http://localhost:7777/sse
Claude Code labels SSE deprecated in favour of HTTP but still supports it, and AppContext serves SSE today — so this is the correct flag to use here rather than --transport http. Verify with claude mcp list.
Cursor, in ~/.cursor/mcp.json:
{
"mcpServers": {
"appcontext": {
"url": "http://localhost:7777/sse"
}
}
}
Windsurf, in ~/.codeium/windsurf/mcp_config.json — note the different key:
{
"mcpServers": {
"appcontext": {
"serverUrl": "http://localhost:7777/sse"
}
}
}
Step 3 — remove the now-duplicated entries. This is the step people skip, and skipping it gives you the worst of both worlds: every tool exposed twice, once directly and once namespaced through the hub. Delete the direct entries from each client after you've confirmed the hub route works.
What one choke point actually buys you
Collapsing four config files into one endpoint is a maintenance win on its own, but the more useful consequence is that every tool call from every client now passes through one place you control.
That's where per-tool authorization becomes practical. Blocking an individual tool — the destructive filesystem call, the repository-creating GitHub tool — applies to every connected client at once rather than needing to be re-done in each one, and the free tier covers up to three blocks in total across all your servers. Going beyond three, allowlist mode (where only explicitly permitted tools get through), and per-tool rate limiting are Pro features. Blocked calls return a POLICY_BLOCKED error to the agent rather than failing silently; the authorization guide covers how policies evaluate.
The same endpoint also carries AppContext's own visual-context tools, so an agent can see your iOS Simulator or browser while it works — that's the live view workflow, and it's a Pro feature.
Caveats worth knowing before you commit
A hub adds a component between your agents and your tools, and that's a real tradeoff. If the hub isn't running, none of your clients have MCP tools — versus per-client configs, where a broken config only breaks one tool. Restarting one app is a smaller surface than four config files, but it is a surface.
AppContext specifically is macOS-only today; there's no Windows or Linux build. It serves SSE rather than Streamable HTTP, which works with all three clients above but does mean using Claude Code's deprecated-but-supported flag. And it has no audit log or activity dashboard yet — you can block and rate-limit tool calls, but you can't currently review a history of what was called.
If you only use one AI coding tool, none of this is worth it: edit the one file and move on. The moment you're maintaining the same server list in two or more places, though, the copies will drift, and the question is only whether you'd rather own a sync script or a single endpoint.
AppContext is a free download for macOS, and the MCP Hub is part of the free tier.