Claude Code MCP Server Configuration Explained
September 7, 2026

Configuring an MCP server in Claude Code comes down to two decisions: which scope (who can see it) and which transport (how it connects). Get those right and each command is one line.
The fastest possible version:
claude mcp add --transport http notion https://mcp.notion.com/mcp
That adds Notion's remote HTTP server at local scope — visible only to you, only in the current project. Everything below is the detail that decides whether you want something different.
The three scopes
Scope answers "who else gets this server?" Choosing wrong is the most common cause of "it worked yesterday" and "it works for me but not for my teammate".
| Scope | Loads in | Shared with the team | Stored in |
|---|---|---|---|
| Local (default) | Current project only | No | ~/.claude.json |
| Project | Current project only | Yes, via version control | .mcp.json in the project root |
| User | All your projects | No | ~/.claude.json |
Set it with --scope (or -s):
claude mcp add --scope project --transport http shared-db https://example.com/mcp
The practical mapping is simple:
- A tool you want everywhere — your notes app, your issue tracker — is user scope.
- A server the whole repo needs is project scope. It writes
.mcp.json, you commit it, and teammates get prompted to approve it on first run. - Anything carrying a credential you don't want in git stays local.
There's a fourth, enterprise scope, deployed by administrators through managed MCP configuration. You don't set that one yourself; it arrives with your machine.
The four transports
Transport answers "how does Claude Code reach this server?"
- HTTP — remote servers, and the recommended choice for anything cloud-hosted.
- stdio — a local process on your own machine, launched and spoken to over standard input and output.
- WebSocket — persistent bidirectional connections, for servers that push events.
- SSE — deprecated. Use HTTP where the server offers it.
The syntax differs in one meaningful way. Remote transports take a URL; stdio takes a command, and the -- separator is mandatory so Claude Code knows where its own flags stop and the server's begin:
# Remote, over HTTP, with an auth header
claude mcp add --transport http github https://api.githubcopilot.com/mcp/ \
--header "Authorization: Bearer YOUR_GITHUB_PAT"
# Local process, over stdio, with an environment variable
claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable \
-- npx -y airtable-mcp-server
Forget the -- and the arguments after it get parsed as Claude Code's own. That single character is behind a surprising share of "command not found" reports.
WebSocket is the exception to that pattern, and it's worth spelling out because the obvious command doesn't work: claude mcp add --transport does not accept ws. WebSocket servers are configured as JSON instead, either in .mcp.json or through claude mcp add-json:
claude mcp add-json events-server \
'{"type":"ws","url":"wss://mcp.example.com/socket","headers":{"Authorization":"Bearer YOUR_TOKEN"}}'
The type: "ws" entry takes the same url, headers, headersHelper, timeout, and alwaysLoad fields as an HTTP entry. Two constraints follow from that. Authentication is header-only — there's no OAuth for WebSocket, so pass a static token in headers or mint one at connect time with headersHelper. And the type is not optional: Claude Code reads a JSON entry with no type as a stdio server, so a url entry without one simply fails.
One more thing that costs people ten minutes: WebSocket servers don't appear in claude mcp list. Use claude mcp get <name> or the /mcp panel to confirm one is actually configured. If your server only answers requests rather than pushing events at you, prefer HTTP anyway — it gets OAuth and the --transport flag, and WebSocket gets neither.
The commands worth memorising
claude mcp list # what's configured
claude mcp get <name> # details for one server
claude mcp remove <name> # remove a server
claude mcp login <name> # OAuth sign-in from the CLI
claude mcp logout <name> # clear stored credentials
claude mcp add-json <name> '<json>' # paste a config block verbatim
claude mcp add-from-claude-desktop # import what Claude Desktop already has
claude mcp serve # run Claude Code itself as an MCP server
Two of those are underused.
claude mcp add-from-claude-desktop imports your existing Claude Desktop server list instead of retyping it. If you've already done this configuration once in the desktop app, do not do it again by hand.
claude mcp serve runs Claude Code as an MCP server, so another MCP client can call it as a tool. That inverts the usual relationship and is the answer to "can I serve Claude Code as MCP?" — yes, and it's one command.
Where the config actually lives
| Scope | File |
|---|---|
| Local and user | ~/.claude.json |
| Project | .mcp.json in the project root |
| Plugin-provided | .mcp.json at the plugin root, or inline in plugin.json |
| Enterprise | managed-mcp.json, deployed by an administrator |
A project-scoped entry is plain JSON and perfectly readable:
{
"mcpServers": {
"shared-db": {
"type": "http",
"url": "https://example.com/mcp"
}
}
}
Note that local and user scope share one file. ~/.claude.json holds your global servers and a per-project section, which is why editing it by hand goes wrong more often than using the CLI.
The precedence rule that explains duplicates
When the same server name is defined in more than one place, Claude Code connects once, using the highest-precedence definition:
- Local scope
- Project scope
- User scope
- Plugin-provided servers
- claude.ai connectors
This is the answer to almost every "why is it using the old URL?" question. A local-scope entry you added months ago silently outranks the .mcp.json your team just updated. Run claude mcp get <name> to see which definition actually won, rather than guessing from the file you happen to have open.
Related: when you approve or reject a project's .mcp.json, that decision is remembered. claude mcp reset-project-choices clears it, which is what you want after a repo's server list changes and you never get re-prompted.
Windows, and installing servers there
Claude Code runs natively on Windows 10 1809+ as well as inside WSL 2, and MCP configuration is identical in both. The difference is what a stdio server needs: a stdio entry launches a local process, so whatever that command requires — npx, uv, a Python interpreter — should live on the same side of the WSL boundary as Claude Code. Remote HTTP servers don't care either way.
To be precise about why, because it's often stated too strongly: WSL 2 interop does work in both directions. From a WSL shell you can call any Windows executable by its full name including the .exe extension, and Windows can reach Linux files over \\wsl$\. So a cross-boundary stdio server isn't categorically impossible — it's just a reliable source of trouble: mismatched path formats, environment variables and PATH that don't carry across, slower I/O over the boundary, and stdio pipes that behave differently than a same-side process.
There is one genuine hard stop, and it's Claude Code's own Bash sandbox rather than WSL. On WSL 2, launching a Windows binary — cmd.exe, powershell.exe, anything under /mnt/c/ — is handed to the Windows host over a Unix socket, so whether a sandboxed command may do it follows the sandbox's Unix-socket settings, and blocking it requires the optional seccomp filter to be installed. If you need those launches to work under the sandbox, allowAllUnixSockets permits them and excludedCommands takes the command out of the sandbox entirely.
If you're setting Claude Code up from scratch first, our install guide covers each platform's command.
FAQ
How do I add an MCP server to Claude Code?
claude mcp add --transport http <name> <url> for a remote server, or claude mcp add --transport stdio <name> -- <command> for a local one. Add --scope project to share it with your team through .mcp.json, or --scope user to make it available in all your projects.
How do I remove an MCP server from Claude Code?
claude mcp remove <name>. If the server keeps coming back, it's defined in more than one scope — run claude mcp list and remove it from each one. Plugin-provided servers are removed by disabling the plugin, not with this command.
Where is the Claude Code MCP config file?
Local and user scopes live in ~/.claude.json. Project scope lives in .mcp.json in the project root, and that's the one you commit.
What's the difference between local and project scope?
Both load only in the current project. Local is private to you and stored in your home directory; project is shared through version control. Put credentials in local, shared infrastructure in project.
Can I run Claude Code as an MCP server?
Yes — claude mcp serve. Other MCP clients can then call Claude Code as a tool.
Why is Claude Code connecting to the wrong version of a server?
Precedence. Local beats project, which beats user, which beats plugins and connectors. Check with claude mcp get <name> to see the definition in force.
The short version
Scope decides who sees the server, transport decides how it connects, and precedence decides which definition wins when you've configured the same thing twice. MCP itself is an open standard, so most of this knowledge transfers to any client that speaks it — see our roundup of the best MCP clients if Claude Code isn't the only one you use. The full command reference lives in Anthropic's MCP documentation.
Notice how much of this page is configuration rather than capability. Scopes, transports, precedence, a -- in the right place — none of it is the thing you actually wanted to do, and it's where most people quietly stop. Taku takes the opposite approach: someone else's tool wiring arrives already connected, and you start from a workspace that runs instead of a config file that doesn't. Our library of free apps is where most people begin. Taku is in Beta, and the Mac app is available now.