← All Blog articles
SaaSClaude CodeMCP

Claude Code MCP configuration: .mcp.json and local, project, user scopes

8 min read

Go deeper on this topic

SaaS integrations

Give AI the context to continue the work: source conversations, open tasks, and unresolved details, from adoption decisions to integration code.

Article 3 of 8 in this series.

View topic page

Use the topic hub as a map, then continue to the next article in the series. New here? Start at the home hub →

Your team updates .mcp.json, yet your machine still uses an older MCP endpoint. Before changing the shared URL again, check whether another scope defines the same server name. A work handoff can include the intended configuration source alongside the conversation history.

This guide covers local, project, and user in the Claude Code CLI. We checked the official documentation on October 24, 2026, and implemented a small explanation model using synthetic inputs. We did not run Claude Code, authenticate, connect a server, or change any real configuration.

Where Claude Code stores MCP configuration

Scope Applies to Stored in
local, the default Your current project Project-specific entries in ~/.claude.json
project The current project, shared with the team .mcp.json at the project root
user All your projects ~/.claude.json

For a duplicate server name, local takes precedence over project, then user. The winning entry replaces the whole server definition; fields are not merged. See the official scope reference.

This comparison excludes managed settings, plugins, and claude.ai connectors. The documentation also describes an exception for duplicate stdio servers in the Desktop Code tab; do not apply this CLI model there unchanged.

An offline experiment with three servers called notes

We gave notes three synthetic URLs. The .invalid endpoints are example data; the code sends no requests. Only the project entry contains an X-Demo header, making it possible to see whether a lower-priority field survives.

Download mcp-scope.mjs and mcp-scope-demo.mjs into one folder. Run the demo with Node.js 22+ or Bun:

node mcp-scope-demo.mjs
# or
bun mcp-scope-demo.mjs

The input is our own JSON shape containing three server maps, rather than an actual Claude Code configuration file:

{
  "local": { "notes": { "type": "http", "url": "https://local.example.invalid/mcp" } },
  "project": {
    "notes": {
      "type": "http",
      "url": "https://project.example.invalid/mcp",
      "headers": { "X-Demo": "project-only" }
    }
  },
  "user": { "notes": { "type": "http", "url": "https://user.example.invalid/mcp" } }
}

In the output, localWins has scope local and server URL https://local.example.invalid/mcp. Its server has no headers. With an empty local map, projectWins selects project and keeps X-Demo. Emptying the project map as well makes userWins select user.

absent returns not-found, while malformed JSON in invalid returns invalid-input. These are names from our function, not Claude Code error messages. On October 24, 2026, Node.js v26.12.1 and Bun 1.3.11 produced identical JSON.

When a shared configuration appears to be ignored

Start with the intended server name and the revision of the shared .mcp.json. A personal local entry with that name may take precedence. Compare the complete entry, including headers, instead of assuming only the URL changes.

Then confirm the endpoint, required permissions, and who owns the configuration. Our suggested workflow is to inspect a difference that contains no credentials before trying to fix the shared file by adding secrets. Treat approval and authentication as separate checks. A matching name does not demonstrate a successful connection.

For the next person or AI session, record the project, server name, intended scope, shared-file revision, and whether the connection has actually been verified. Continue with Circleback MCP setup and read-only checks for meeting context, or the Claude Code context handoff guide for records across sessions.

What the model cannot tell you

The function reads only the supplied JSON. It does not read home configuration or environment variables, write files, or execute command strings. It rejects malformed JSON and invalid scope-map types, but is not a full MCP schema validator. It accepts an empty server object as data, so selected does not mean the configuration is usable.

This experiment implements the documented three-scope rule for explanation. It does not reproduce every CLI configuration source, authentication, approval, organization policy, or environment-variable expansion. Endpoint correctness and whether AI uses a tool as intended require separate verification.

FAQ

Q. Where is the Claude Code MCP configuration file?
In the CLI, project scope uses .mcp.json at the project root. Local and user scopes use ~/.claude.json. Local applies to the current project; user applies across your projects. Local is the default.
Q. Are duplicate server definitions merged?
Across the three CLI scopes, local wins over project, then user. The entire entry is selected; lower-priority headers are not merged. See the article and official documentation for exceptions such as managed settings and the Desktop Code tab.
Q. Does selected in the experiment mean a server will connect?
It only means our explanation model selected an entry. Full configuration validity, authentication, approval, and actual connections are untested. The model does not read real configuration files.