Knowing what MCP is gets you halfway. If you want the mental model first, start with MCP fundamentals. This guide is the practical half: adding a server, choosing where its config lives, and fixing it when it does not connect. The examples use Claude Code and Claude Desktop, the two clients most people start with.
How do I add an MCP server in Claude Code?
The fastest way is the claude mcp command. Here is a local (stdio) server and a
remote (HTTP) one:
# A local server launched as a subprocess
claude mcp add --transport stdio filesystem -- npx -y @modelcontextprotocol/server-filesystem ~/projects
# A remote server with an auth header
claude mcp add --transport http github https://api.githubcopilot.com/mcp/ \
--header "Authorization: Bearer YOUR_GITHUB_TOKEN"For stdio servers, everything after -- is the command Claude runs as a subprocess untouched.
Pass secrets with repeatable --env KEY=value flags rather than baking them into
the command. For a step-by-step walkthrough, see install your first MCP server.
Where does MCP config live, and which scope wins?
Claude Code has three scopes. Choosing the right one is most of the skill:
- local (the default) · just you, just this project. Stored in your
~/.claude.jsonunder the project path. - project · shared with the team. Stored in a
.mcp.jsonfile at the project root, which you commit to git. - user · just you, but across all your projects. Also in
~/.claude.json.
When the same server name exists in more than one scope, the most specific wins:
local, then project, then user. Entries are replaced whole, not merged.Common gotchaA common time-sink is editing a server in one scope while a same-named entry in a more specific scope keeps overriding it, so your changes appear to do nothing.Run claude mcp list to see which scope resolved, then edit that one or rename to avoid the clash.
A committed .mcp.json looks like this:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "${HOME}/projects"]
},
"stripe": {
"type": "http",
"url": "https://mcp.stripe.com"
}
}
}You can reference environment variables with ${VAR} or ${VAR:-default} in the
command, args, url, env, and headers. A missing variable with no default fails
the parse, which is a feature: it stops a half-configured server from loading.
Common gotchaBecause project scope lives in a committed .mcp.json, pasting a raw API token or bearer header straight into that file leaks it to everyone with repo access and into git history forever.Keep the secret in a ${VAR} reference and let each person supply the value through their own environment, so the committed file only ever names the variable.
Does Claude Desktop share config with Claude Code?
Claude Desktop reads its own file, and Claude Code does not look at it:
- macOS ·
~/Library/Application Support/Claude/claude_desktop_config.json - Windows ·
%APPDATA%\Claude\claude_desktop_config.json
It uses the same { "mcpServers": { ... } } shape and reloads on app launch. To
pull existing Desktop servers into Claude Code, run
claude mcp add-from-claude-desktop.
How do I verify and debug an MCP server?
When a server does not show up, work through these. For a deeper diagnostic walkthrough, see fix an MCP server that will not connect.
claude mcp list # every server and its status
claude mcp get filesystem # detail for one, including pending approvalInside a session, /mcp shows live status and is where you authenticate remote
servers over OAuth. For a server you are developing, the MCP Inspector gives you
a UI to poke at it directly:
npx @modelcontextprotocol/inspectorWhy won't my MCP server connect?
Most broken servers are one of these:
- PATH · the subprocess cannot find
node,npx, orpython. Use absolute paths or make sure the binary is on PATH for the launching shell. - Missing env · a
${VAR}with no value and no default. Set it, or give a default. - Stale npx cache or version drift · pin a version, or clear the cache.
- Pending approval · project-scoped servers wait for you to approve them once
before they load. Approve them in-session or with
claude mcp get. - Unauthenticated remote · the server needs OAuth you have not done yet. Run
/mcpand sign in.
Once a server connects cleanly, its tools appear to the model. Before you hand an MCP server real access, decide which of its tools Claude may call: see MCP security: what to allow and what to block. The next guide builds one of these servers from scratch.