Claude Code MCP Server Configuration: Step-by-Step Setup (2026)
The Model Context Protocol SDK crossed 97 million monthly downloads in March 2026, up from roughly 2 million at launch — a 4,750% climb in 16 months (Digital Applied citing Anthropic, 2026). The protocol is everywhere now. The official registry lists 9,400+ servers (MCP Manager, 2026), and Anthropic's reference repo carries 85.7k GitHub stars. Yet the average Claude Code user I talk to has exactly one MCP server installed.
I've been running a six-server setup across macOS and Windows for eight months and have hit nearly every config gotcha along the way. This Claude Code MCP server configuration guide is the working playbook: the scope hierarchy that finally clicked, the JSON anatomy that maps to it, three real server walkthroughs, and the debugging loop that takes you from "server isn't showing up" to "fixed" in under five minutes. For the broader landscape — what MCP is, which 30 servers are worth knowing, and where the ecosystem is heading — see the complete 2026 guide to MCP servers and the Model Context Protocol.
Key Takeaways
- Claude Code reads three config locations in priority order: local (
~/.claude.jsonkeyed to project), project (.mcp.jsonat repo root, team-shared), and user (~/.claude.jsonglobal block). Highest priority wins.claude_desktop_config.jsonis Claude Desktop's file — Claude Code never reads it. Importing requiresclaude mcp add-from-claude-desktop.- Three transports exist: stdio (local subprocess, fastest), HTTP (remote with OAuth or bearer tokens), and SSE (legacy, deprecated). Pick stdio for local tools, HTTP for everything else.
- Pin versions in production configs. OX Security disclosed a systemic SDK flaw in April 2026 that put ~200,000 servers at risk (OX Security via The Register, 2026).
npx -y pkg@latestis a rug-pull waiting to happen.
Where Does Claude Code MCP Server Configuration Live?
Claude Code reads MCP configuration from three locations with a strict precedence order, and getting the hierarchy wrong is responsible for about 80% of the "my server won't show up" reports I see in issue trackers. The three scopes are local, project, and user (Claude Code MCP docs, 2026).
Local scope lives in ~/.claude.json, keyed by the absolute path of the current project. It's the default when you run claude mcp add without a --scope flag. It applies only when you're working in that folder, and nothing in it gets committed. Use it for personal credentials and one-off experiments. Project scope is .mcp.json at the repo root, designed to be checked into git so the whole team picks up the same servers. Claude Code prompts each user to approve project servers on first run — a guardrail you want to keep, not bypass. User scope also lives in ~/.claude.json but applies globally. Use it for general-purpose servers like filesystem, fetch, or memory that you want available everywhere.
Source: Claude Code MCP documentation, 2026
The trap most people hit is assuming claude_desktop_config.json is the right file. It isn't — that's the Desktop app's config, living at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS or %APPDATA%\Claude\claude_desktop_config.json on Windows. Claude Code never reads it. If you've already configured the Desktop app and you're on macOS or WSL, run claude mcp add-from-claude-desktop and it imports the lot. Otherwise you'll be editing the wrong file all afternoon.
Per Anthropic's own docs: "Project servers in .mcp.json take precedence over user servers with the same name; local-scoped servers take precedence over project-scoped servers" (code.claude.com, 2026). The mental model that works: narrower scope wins. Your personal override beats the team config, the team config beats the global default. That's intentional — you might need to temporarily disable a project server without committing the change.
What Does the MCP Config JSON Actually Look Like?
The fast path is claude mcp add from your terminal, but knowing what it writes saves you when something breaks. Every Claude Code MCP server configuration entry sits under the mcpServers key with a stable shape: a command (or url for HTTP), optional args, optional env for environment variables, and optional headers for HTTP auth. Claude Code supports ${VAR} and ${VAR:-default} expansion in all string values, which means you can commit .mcp.json without leaking secrets.
Here's an annotated config covering all three transport types in one file:
{
"mcpServers": {
"fs": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"${HOME}/code",
"${HOME}/Documents/notes"
]
},
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer ${GH_PAT}"
}
},
"notion": {
"type": "http",
"url": "https://mcp.notion.com/mcp"
},
"supabase": {
"command": "npx",
"args": [
"-y",
"@supabase/mcp-server-supabase@0.4.5",
"--access-token",
"${SUPABASE_TOKEN}"
],
"env": {
"NODE_NO_WARNINGS": "1"
}
}
}
}
Four things to notice. First, type is http, sse, or omitted (stdio is the default — no type field means it's a local subprocess). Second, env-var expansion works in command, args, url, headers, and the env block; keep secrets in your shell, not in the JSON. Third, pinned versions: @0.4.5 on Supabase, not @latest. The @latest tag is exactly the supply-chain footgun the security section gets to in a minute. Fourth, the env block lets you set runtime variables the server sees but Claude Code itself doesn't.
According to Anthropic's documentation, the JSON form via claude mcp add-json is the safest install path on Windows because it sidesteps a known shell-quoting bug where -- rewrites /c to C:/ in the saved config (anthropics/claude-code #4019, 2026). On Mac and Linux either form works.
How Do You Add Your First Three MCP Servers?
Let's wire up three real servers that cover the full spectrum: filesystem (stdio, no auth), GitHub (HTTP with bearer token), and Notion (HTTP with browser OAuth). User scope so they're available everywhere.
# 1. Filesystem (Anthropic reference) — stdio, paths whitelisted as args
claude mcp add --scope user fs -- \
npx -y @modelcontextprotocol/server-filesystem ~/code ~/Documents/notes
# 2. GitHub — HTTP, bearer token from a fine-grained PAT
export GH_PAT="ghp_xxxxxxxxxxxxxxxxxxxx"
claude mcp add --transport http --scope user github \
https://api.githubcopilot.com/mcp/ \
--header "Authorization: Bearer $GH_PAT"
# 3. Notion — HTTP, opens OAuth in your browser
claude mcp add --transport http --scope user notion https://mcp.notion.com/mcp
# Verify
claude mcp list
claude mcp get github
Every flag must appear before the server name. The -- separates Claude Code's flags from the server command itself, and forgetting it is the single most common cause of "my server won't connect" reports in the issue tracker. After claude mcp add the server is registered but not yet running — Claude spawns it on the next session start.
The filesystem server is your "hello world" — it's the smallest reference implementation and it surfaces every scope and pathing gotcha in one shot. Whitelist only the directories Claude actually needs; granting it your whole home directory is the MCP equivalent of chmod 777. The GitHub server uses a bearer token from a fine-grained personal access token. Scope it to repo:read for most workflows; never grant repo:write unless you specifically want Claude pushing commits. For the full surface — toolset trimming, PAT-vs-App rate-limit math, and the 7 use cases worth the schema overhead — see the GitHub MCP server field-notes guide. The Notion server demonstrates the OAuth flow — claude mcp add opens your browser, you approve, and the token lands in ~/.claude.json under the server's oauth.token field. Never commit that file.
Stdio, HTTP, or SSE — Which Transport Should You Pick?
MCP supports three wire transports and the choice matters more than it looks. Stdio launches a subprocess and pipes JSON-RPC over stdin/stdout — fastest, but the server must live on your machine. HTTP uses regular requests and is the only option for remote servers and OAuth flows. SSE (Server-Sent Events) was the original streaming transport and is now deprecated in favor of streamable HTTP (Claude Code MCP docs, 2026). The decision tree is short: local tool → stdio, remote service → HTTP, anything labeled SSE → use it for now but expect migration to HTTP.
Source: Claude Code MCP transport documentation, 2026
The practical implication is auth surface. A stdio server runs as a subprocess of Claude Code with your full user privileges — no network auth needed, but anything that process can read, the model can read. An HTTP server lives behind whatever auth you configure (OAuth, bearer token, mTLS), which is more setup but a tighter blast radius. Per Anthropic's own security guidance, "MCP servers may execute arbitrary code and access local resources — only install servers you trust" (code.claude.com, 2026). That sentence is doing more work than it looks like.
Why Doesn't My Server Show Up in /mcp list?
When a server you just added doesn't appear, failures cluster into four buckets. The diagnostic loop is short.
Bucket 1 — wrong file, wrong scope. Run claude mcp list in the project directory. If your server isn't there, it's in the wrong scope. Run claude mcp get <name> for the server you expect to see; the output tells you exactly which scope file it lives in. Move it with claude mcp remove <name> and re-add with an explicit --scope flag. This catches maybe half of "missing server" reports on its own.
Bucket 2 — server crashes on startup. Open the in-session /mcp panel and you'll see the server status. Red means it failed to start. The actual error lives in Claude Code's logs at ~/.claude/logs/. Common causes: missing env vars (Supabase needs --access-token), wrong Node version (most servers require ≥ 18), or npx hasn't cached the package and the 10-second startup timeout fires first. Bump MCP_TIMEOUT=15000 (milliseconds) in your shell environment if cold starts are killing you.
Bucket 3 — server starts but no tools appear. This is almost always ENABLE_TOOL_SEARCH deferring schema load. Claude Code v2.x ships with auto:5 as the default, which means tool schemas only register after the model actively searches for them. Either invoke a tool by name in your prompt (@supabase list_tables) or set ENABLE_TOOL_SEARCH=off to force eager loading. Trade-off: you pay the schema cost on every turn.
Bucket 4 — OAuth flow hangs. Most common with Notion, Linear, or Atlassian remote servers. The callback port (default 8765) is often taken by another process. Pass --callback-port 9876 to claude mcp add to pick a free port, or kill whatever's bound to 8765 with lsof -i :8765. After OAuth completes, the token lives in ~/.claude.json under the server's oauth.token field.
# The reliable diagnostic sequence
claude mcp list # is it registered?
claude mcp get supabase # which scope, what command?
claude --debug # run with verbose logs
tail -f ~/.claude/logs/mcp-*.log # watch logs in another window
If all four buckets are clean and the server still doesn't work, run it manually outside Claude Code (npx -y @supabase/mcp-server-supabase@latest --access-token $TOKEN) and check that it responds to a basic initialize JSON-RPC call. If the standalone server is broken, it's the server's bug, not yours. For failures outside MCP itself — API errors, process exits, OAuth 403s, and file-editing problems — keep the Claude Code errors troubleshooting guide open in the next tab.
What Are the Most Common MCP Config Mistakes?
After eight months of running this setup, the same handful of mistakes account for most of the lost time. They're worth memorizing because they're invisible until you know what to look for.
Mistake 1 — bare npx on Windows. Claude Code spawns server processes via Windows' native CreateProcess API, which doesn't resolve .cmd shims, and npx on Windows is exactly that. The result is spawn npx ENOENT or, worse, a silent disconnect with no error in the logs. Wrap explicitly in cmd /c:
{
"mcpServers": {
"seq-thinking": {
"command": "cmd",
"args": ["/c", "npx", "-y", "@modelcontextprotocol/server-sequential-thinking"]
}
}
}
The cleanest answer for Windows is WSL2. Inside the Linux subsystem, npx works natively, configs live in the Linux filesystem, and claude mcp add-from-claude-desktop even bulk-imports existing Desktop configs (Mads Hovgaard, 2026). The 20-minute setup is cheaper than the bug surface.
Mistake 2 — secrets in plaintext JSON. Per Anthropic, "only install servers you trust" isn't advice, it's a requirement. A stdio MCP server runs with your full user privileges, and a remote HTTP server receives whatever you put in headers. Use ${VAR} expansion so secrets stay in your shell environment, or — better on macOS — store them in Keychain and pull through a wrapper script:
# Five-line wrapper, called from .mcp.json
#!/usr/bin/env bash
exec npx -y @supabase/mcp-server-supabase@0.4.5 \
--access-token "$(security find-generic-password -s supabase-mcp -w)"
Five lines, no secrets in dotfiles (Kahunam, 2026).
Mistake 3 — npx -y pkg@latest. OX Security disclosed a systemic flaw in Anthropic's official MCP SDK (TypeScript, Python, Java, and Rust) in April 2026 that put approximately 200,000 servers at risk via STDIO command injection, affecting 150 million combined SDK downloads (OX Security via The Register, 2026). Patched, but the lesson: a compromised maintainer can push malware to your next session if you never pin versions. Pin them.
Mistake 4 — token bloat from unused servers. Every server you connect re-registers its tool schemas at every conversation turn. MindStudio's 2026 benchmark found that a Supabase + GitHub + Linear stack of 81 tools consumed over 20,000 tokens before the user typed a single character — about 16% of a 128k context window (MindStudio, 2026). If you call a server twice a week, it's costing you 100+ schema-loads to save 2 paste operations. Use the CLI version instead and expose it via Bash. Same result, near-zero overhead. If the job is really about reusable prompt behavior rather than external tools, use this Claude Skills vs MCP Servers decision guide before adding another server.
Mistake 5 — forgetting the project-approval reset. When you pull a teammate's .mcp.json, Claude Code shows you the approval prompt once and remembers your choice. If the team later changes the server set, you may not get re-prompted. Run claude mcp reset-project-choices after pulling changes so you can re-approve from scratch.
What's the Working Strategy for Most Developers?
After eight months of running MCP across two laptops, here's what holds up. Run four servers at user scope: filesystem, fetch, memory, and Context7. They're cheap on tokens, useful everywhere, and not worth re-configuring per project. Add GitHub at user scope if you ship code. Add Playwright at user scope if you do any browser testing. Add Sequential Thinking only when you actually need structured reasoning traces; the trade-offs are covered in the Sequential Thinking MCP guide for Claude Code. Then put project-specific servers — Supabase, Notion, Linear — in .mcp.json at the repo root with env-var references, commit it, and document the required environment variables in your README.
In raw numbers: my user-scope config runs six servers and consumes roughly 8,000 tokens of schema overhead per turn. Project .mcp.json files add another 15,000–28,000 depending on the project. The 16% context threshold the MindStudio benchmark flagged is real but manageable. If you find yourself there, the answer isn't usually fewer servers — it's enabling ENABLE_TOOL_SEARCH=auto:5 (the default) and letting Claude lazy-load schemas on demand.
The Microsoft Playwright server has 32.5k GitHub stars and ships an update every five days as of May 2026 — by far the most maintained browser-automation MCP. GitHub's official server sits around 29.7k stars (The Agent Times, 2026). Both are well past "experimental" and worth your day-one install slot.
Frequently Asked Questions
Is .mcp.json the same as claude_desktop_config.json?
No. claude_desktop_config.json is Claude Desktop's config file at ~/Library/Application Support/Claude/ on macOS or %APPDATA%\Claude\ on Windows. Claude Code never reads it. Claude Code uses .mcp.json at the repo root for project-scoped servers and ~/.claude.json for local and user scopes. To import existing Desktop servers into Claude Code, run claude mcp add-from-claude-desktop (macOS or WSL only).
How many MCP servers should I run?
Six to eight is the sweet spot for solo developers, based on token-budget analysis. Four at user scope (filesystem, fetch, memory, Context7) covers daily generalist work, two more (GitHub, Playwright) if you ship code or test in browsers, and 2–4 at project scope for whatever's specific to that repo. More than ten servers and you'll burn 20%+ of your context window on tool schemas before typing a prompt (MindStudio, 2026).
Why does npx fail on Windows but work everywhere else?
Claude Code spawns processes via Windows' CreateProcess, which doesn't resolve .cmd shims like npx.cmd. Wrap the command in cmd /c (e.g., "command": "cmd", "args": ["/c", "npx", "-y", "package"]) or — strongly recommended — install Claude Code inside WSL2 where npx works natively. The CLI form has a known parser bug that mangles cmd /c quoting on Windows; use claude mcp add-json or hand-edit the JSON (anthropics/claude-code #4019, 2026).
How do I share an MCP server config with my team?
Add it to .mcp.json at the repo root with ${VAR} placeholders for any secrets, commit the file, and document the required environment variables in your README. Claude Code prompts each team member to approve project-scoped servers on first run — a security guardrail you want to keep. Each teammate can override locally in ~/.claude.json if a specific server isn't useful for them. Run claude mcp reset-project-choices if the team config changes and you need to re-approve.
Can MCP servers see my API keys?
Yes, if you put them in the env block or command args. A stdio MCP server runs as a subprocess of Claude Code with your full user privileges, and a remote HTTP server receives whatever you pass in headers. Store sensitive credentials in macOS Keychain or Windows Credential Manager and pull them through a wrapper script, or use shell env-var expansion (${VAR}) so secrets never land in dotfiles. Anthropic's guidance — "only install servers you trust" (Claude Code MCP docs, 2026) — is a hard requirement, not a suggestion.
The Bottom Line
MCP is the layer where Claude Code stops being a chat window and starts being a workspace. The config looks dense the first time you open .mcp.json, but the mental model is small: three scopes, three transports, a handful of servers that earn their context-window cost. Most users install one server. The gap between "one server" and "the right six" is where Claude Code goes from "useful sometimes" to "I can't work without this."
If you do nothing else after reading this:
- Install filesystem at user scope tonight as your "hello world"
- Add GitHub at user scope if you push code, scoped to
repo:read - Pin versions in
.mcp.jsonso a compromised maintainer can't ship malware to your next session - Run
claude mcp listwhenever something feels off andclaude --debugwhen it actually breaks
The protocol is still evolving — 30+ CVEs filed in the first year, an SDK supply-chain flaw patched in April 2026, OAuth scopes still tightening. Pin what you can, scope what you can't pin, and review the /mcp panel before approving a new project's servers. Most friction is on the configuration side, not the protocol side, and most of that friction is the kind this guide covers.
The next time someone asks why their claude_desktop_config.json "isn't working," you'll already know what to tell them.
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "BlogPosting",
"headline": "Claude Code MCP Server Configuration: 2026 Setup Guide",
"description": "Learn Claude Code MCP server configuration across local, project, and user scopes. Use proven JSON patterns to fix 80% of setup failures before wasting hours.",
"datePublished": "2026-05-15",
"dateModified": "2026-05-15",
"author": {
"@type": "Person",
"name": "Nishil Bhave"
},
"image": "https://images.unsplash.com/photo-1558494949-ef010cbdcc31?w=1200&h=630&fit=crop&q=80",
"url": "https://maketocreate.com/claude-code-mcp-configuration-complete-guide/",
"keywords": ["claude code mcp server configuration", "claude code mcp setup", "configure mcp server claude", "model context protocol", "claude code"]
},
{
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Is .mcp.json the same as claude_desktop_config.json?",
"acceptedAnswer": {
"@type": "Answer",
"text": "No. claude_desktop_config.json is Claude Desktop's config file at ~/Library/Application Support/Claude/ on macOS or %APPDATA%\Claude\ on Windows. Claude Code never reads it. Claude Code uses .mcp.json at the repo root for project-scoped servers and ~/.claude.json for local and user scopes. To import existing Desktop servers into Claude Code, run claude mcp add-from-claude-desktop (macOS or WSL only)."
}
},
{
"@type": "Question",
"name": "How many MCP servers should I run?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Six to eight is the sweet spot for solo developers, based on token-budget analysis. Four at user scope (filesystem, fetch, memory, Context7) covers daily generalist work, two more (GitHub, Playwright) if you ship code or test in browsers, and 2-4 at project scope for whatever's specific to that repo. More than ten servers and you'll burn 20%+ of your context window on tool schemas before typing a prompt."
}
},
{
"@type": "Question",
"name": "Why does npx fail on Windows but work everywhere else?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Claude Code spawns processes via Windows' CreateProcess, which doesn't resolve .cmd shims like npx.cmd. Wrap the command in cmd /c (e.g., \"command\": \"cmd\", \"args\": [\"/c\", \"npx\", \"-y\", \"package\"]) or — strongly recommended — install Claude Code inside WSL2 where npx works natively. The CLI form has a known parser bug that mangles cmd /c quoting on Windows; use claude mcp add-json or hand-edit the JSON."
}
},
{
"@type": "Question",
"name": "How do I share an MCP server config with my team?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Add it to .mcp.json at the repo root with ${VAR} placeholders for any secrets, commit the file, and document the required environment variables in your README. Claude Code prompts each team member to approve project-scoped servers on first run — a security guardrail you want to keep. Each teammate can override locally in ~/.claude.json if a specific server isn't useful for them. Run claude mcp reset-project-choices if the team config changes and you need to re-approve."
}
},
{
"@type": "Question",
"name": "Can MCP servers see my API keys?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, if you put them in the env block or command args. A stdio MCP server runs as a subprocess of Claude Code with your full user privileges, and a remote HTTP server receives whatever you pass in headers. Store sensitive credentials in macOS Keychain or Windows Credential Manager and pull them through a wrapper script, or use shell env-var expansion (${VAR}) so secrets never land in dotfiles. Anthropic's guidance — 'only install servers you trust' — is a hard requirement, not a suggestion."
}
}
]
}
]
}




Top comments (0)