Claude Code can read your files and run your shell, but it can't see your issue tracker, your database or a browser until you connect them. MCP (Model Context Protocol) servers are how you connect them. Adding one takes a single command. The choice that needs thought is the scope, which decides who gets the server and in which projects.
Two kinds of server
An MCP server either runs somewhere else and you reach it over HTTP, or it runs on your machine as a local process that Claude Code starts and talks to over stdio.
A remote server needs a name and a URL:
claude mcp add --transport http notion https://mcp.notion.com/mcpA local server needs a name and the command that starts it. Everything after -- is passed to the server untouched:
claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable \
-- npx -y airtable-mcp-serverTwo details in that second command are easy to get wrong:
- Without the
--, Claude Code tries to parse the server's own flags as its options and fails. --envaccepts severalKEY=valuepairs, so if the server name comes straight after it, the CLI reads the name as another pair. Put another option, such as--transport stdio, between them.
If you leave out --transport, the CLI assumes stdio. There is also an SSE transport, but the docs mark it deprecated: use HTTP where the server offers it.
If a server's documentation gives you a JSON block instead of a command, use claude mcp add-json:
claude mcp add-json my-server '{"type":"http","url":"https://api.example.com/mcp"}'A JSON entry with a url must also have a type. Without one, Claude Code reads the entry as a stdio server and reports an error.
The three scopes
Every server you add lands in one of three scopes. You set it with --scope (or -s), and the default is local.
| Scope | Loads in | Shared with others | Stored in |
|---|---|---|---|
local (default) |
The current project only | No | ~/.claude.json, under that project's path |
project |
The current project only | Yes, through git | .mcp.json at the project root |
user |
Every project on your machine | No | ~/.claude.json |
The names are confusing here. MCP's "local" scope lives in ~/.claude.json in your home directory, not in the project's .claude/settings.local.json. Nothing about a local-scoped server is written into the repository.
Which scope to choose
Pick by asking two questions: does this server belong to the project or to you, and does it carry a credential?
- Use
localfor a server you are trying out, a personal tool in one repository, or anything that needs your own API key. - Use
projectwhen everyone working on the repository needs the same server, such as the database or staging API the codebase depends on. Commit.mcp.json. - Use
userfor tools you want everywhere, whatever the project: a browser automation server, a GitHub server, a documentation lookup.
I keep all six of my servers at user scope, because they are tools I use across every repository rather than parts of any one project. Two of them are heavy, so I don't let each session start its own copy. Each of those entries runs a small wrapper that starts one shared server process per git checkout for every session working in it, and stops it after 30 idle minutes. Claude Code doesn't do that sharing for you. Each session starts its own stdio processes.
Sharing a server with .mcp.json
Adding a server with --scope project creates or updates .mcp.json at the project root. You can also write it by hand:
{
"mcpServers": {
"api-server": {
"type": "http",
"url": "${API_BASE_URL:-https://api.example.com}/mcp",
"headers": {
"Authorization": "Bearer ${API_KEY}"
}
}
}
}Keep secrets out of the file with environment variables. ${VAR} expands to the variable, and ${VAR:-default} falls back to the default when it isn't set. Expansion works in command, args, env, url and headers. If a variable is unset and has no default, the server still loads with the literal ${VAR} text, and claude mcp list shows a warning.
Because a cloned repository could name any server, Claude Code asks you to approve project-scoped servers before an interactive session uses them. Until you do, claude mcp list shows them as pending approval. If you change your mind later, claude mcp reset-project-choices clears those decisions. claude -p runs and Agent SDK sessions can't show that prompt, so they load project servers without asking.
When the same name is in two scopes
Claude Code connects to a server once, using the definition from the highest-ranked source. It takes the whole entry from that source, and doesn't merge fields across scopes. The order, highest first:
- Local scope
- Project scope
- User scope
- Plugin-provided servers
- claude.ai connectors
So a local entry overrides the team's .mcp.json entry of the same name, which is handy for pointing a shared server at your own test instance. If two scopes define the same name with different endpoints, claude mcp list and /mcp warn you about the conflict.
Check and manage what you added
claude mcp list # every server, with a health status
claude mcp get notion # details for one server
claude mcp remove notion --scope local # remove it from one scopeInside a session, /mcp shows the same status, signs you in to servers that use OAuth, and lets you switch a server off for the current project without deleting its configuration. If a server shows ! Needs authentication, run /mcp or claude mcp login <name> from your shell.
How many servers is too many?
As far as context goes, more than most people expect. Tool search is on by default: at the start of a session Claude only gets each server's tool names and instructions, and loads a tool's full definition when it needs it. In my sessions the tools from my servers arrive as a list of names, and a full definition loads only when a task needs that tool. A server you rarely use costs little, and Claude Code sets no fixed cap on tools per server.
Tool output is a different budget. Claude Code warns when one MCP tool result passes 10,000 tokens and caps it at 25,000 by default. If a server needs to return more, raise the cap with the MAX_MCP_OUTPUT_TOKENS environment variable.
To run your own check before or after an MCP call, use hooks: MCP tools are named mcp__<server>__<tool>, and a hook matcher can target them. For instructions that apply on every turn, put them in memory, and for a repeatable procedure that uses a server's tools, write a skill.
Questions
Where does Claude Code store MCP servers?
Claude Code keeps local- and user-scoped servers in ~/.claude.json in your home directory. Local ones sit under the project's path, and user ones apply everywhere. Project-scoped servers live in .mcp.json at the root of the repository.
How do I share an MCP server with my team?
Add it with --scope project, or write the entry into .mcp.json by hand, and commit the file. Use ${VAR} references for keys so each person supplies their own. Each teammate approves the server the first time they open a session in the project.
Why doesn't my MCP server show up?
Run claude mcp list from the project directory. A local-scoped server only appears in the project you added it from, a project server waits for approval, and a stdio server added without -- before its command won't start. /mcp in a session shows each server's status and lets you reconnect.
Sources
- Claude Code docs: Connect Claude Code to tools via MCP
- Claude Code CLI 2.1.306:
claude mcp --helpandclaude mcp add --help