Claude Code MCP Config: Setup, Scopes & JSON
Where the config actually lives, the three scopes that trip people up, and the add commands that just work.

The Claude Code MCP config lives in a .mcp.json file (project scope) or in your user-level settings, and the fastest way to write it correctly is claude mcp add rather than hand-editing JSON. Get the scope wrong and your server either leaks into every repo or vanishes when you switch projects. This is the config that matters, minus the guesswork.
If you've never touched MCP before, read what an MCP server actually is first. Everyone else: here's exactly where the config lives, the three scopes, and the commands that don't waste your time.
Where the Claude Code MCP config lives
There is no single file — Claude Code merges config from three locations, and knowing which one you're writing to is 80% of the battle. The claude mcp add command picks the location for you based on the --scope flag; you rarely need to open a JSON file by hand.
The three sources, in plain terms:
- Local (default): stored in your project's private settings. Only you, only this project. Good for secrets and experiments.
- Project: written to
.mcp.jsonat the repo root. Committed to git, shared with your team. This is the file people mean when they say "the MCP config." - User: global to your machine, available in every project you open.
Run claude mcp list inside a project to see every server that resolves, and claude mcp get <name> to see which scope a specific one came from. When two scopes define the same server name, the narrower one wins — local overrides project overrides user.
The three scopes, and which to actually use
Use project scope for anything your teammates also need, user scope for your personal always-on tools, and local for anything with a secret in it. Most confusion comes from defaulting to local and then wondering why the server isn't there on another machine.
| Scope | Flag | Where it's stored | Shared? | Use it for |
|---|---|---|---|---|
| Local | --scope local (default) | Project private settings | No | Secrets, throwaway tests |
| Project | --scope project | .mcp.json (git-tracked) | Yes, via git | Team-standard servers |
| User | --scope user | Global user config | Across your projects | Your personal defaults |
One rule saves the most pain: never commit tokens into .mcp.json. Project scope is git-tracked, so put the server definition there but reference secrets via ${VAR} env expansion and keep the actual value in your environment. When a shared server misbehaves, check the scope resolution first — a duplicate name in local scope silently shadowing the project one is the classic culprit.
The commands that actually work
Skip hand-writing JSON — claude mcp add generates a valid entry every time. The one flag people miss is --transport, which tells Claude Code whether the server is a local process or a remote URL.
Add a local stdio server (a command Claude Code spawns and talks to over stdin/stdout):
claude mcp add filesystem --scope project \
-- npx -y @modelcontextprotocol/server-filesystem /path/to/allowed/dir
Everything after the -- is the command Claude Code runs. That's the Filesystem reference server, the official example for scoped local read/write inside directories you name — and a fair mental model for the roughly 90% of MCP servers that run locally over stdio.
Add a remote HTTP server (a hosted URL, no local process):
claude mcp add --transport http context7 https://mcp.context7.com/mcp
That's Context7, which injects version-specific library docs so your agent stops hallucinating APIs from three years ago. For servers that ship both ways — like the GitHub MCP server, which runs as local Docker or a hosted remote — the remote saves you a container but sends your repo context to someone else's host. Pick deliberately; see local vs remote MCP for the trade-off in full.
What a minimal .mcp.json looks like
Here is the entire shape — a top-level mcpServers object keyed by server name. Anything more is optional.
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "./src"]
},
"context7": {
"type": "http",
"url": "https://mcp.context7.com/mcp"
}
}
}
Local servers use command + args; remote servers use type and url. Pass secrets through an env block that reads from your shell ("env": {"GITHUB_TOKEN": "${GITHUB_TOKEN}"}) rather than pasting the literal token. If you'd rather not memorize the schema, the config generator writes a valid block for any server on this site. Prefer copy-paste steps? See how to add an MCP server.
What to skip
Don't wire up every server you find — each one spends part of a fixed budget. Coding clients keep a working set of around 40 tools before the model starts fumbling tool selection, and a single chatty server can eat a dozen of those slots. The math is unforgiving; see the tool-limit breakdown.
My shortlist for a real coding setup: Filesystem for scoped file access, GitHub for repo and PR work, Context7 for docs. That's it to start. Add the fourth server only when you feel the specific gap it fills — not because it looked interesting in a list of the best MCP servers. Prune anything you haven't invoked in a week; the tool budget is the real constraint, not the config file.