To configure MCP in Claude Code, run claude mcp add in your terminal. Remote server: claude mcp add --transport http <name> <url>. Local server: claude mcp add <name> -- <command>. By default the config goes to the local scope, stored in ~/.claude.json and visible only to you in that project. With --scope project it goes to .mcp.json and your team gets it through git; with --scope user the server shows up in all your projects. Check with claude mcp list.
I tested every command in this guide on Claude Code 2.1.296, on a Linux machine with no login, against two public servers: DeepWiki (HTTP, no auth) and the official @modelcontextprotocol/server-filesystem (stdio, via npx). The output below is what the terminal returned. Anything that needs a logged-in session, like the /mcp panel and OAuth sign-in, comes from the official Claude Code MCP docs.
If you want to write your own server, the walkthrough is in how to build an MCP server in Python. This page is about configuring servers that already exist.
How do you add a remote MCP server (HTTP)?
A remote server is a URL. The docs recommend the HTTP transport for it and mark SSE as deprecated.
$ claude mcp add --transport http deepwiki https://mcp.deepwiki.com/mcp
Added HTTP MCP server deepwiki with URL: https://mcp.deepwiki.com/mcp to local config
File modified: /home/box/.claude.json [project: /tmp/mcp-lab]
$ claude mcp list
Checking MCP server health…
deepwiki: https://mcp.deepwiki.com/mcp (HTTP) - ✔ ConnectedIf the server needs a sign-in, claude mcp list shows ! Needs authentication. That is what happened with the Notion server:
$ claude mcp add --transport http notion https://mcp.notion.com/mcp
Added HTTP MCP server notion with URL: https://mcp.notion.com/mcp to local config
$ claude mcp list
...
notion: https://mcp.notion.com/mcp (HTTP) - ! Needs authenticationTo sign in, open Claude Code and run /mcp, or run claude mcp login <name> from your shell. I did not test those two steps, because the test machine had no browser and no logged-in account. They are in the authentication section of the docs.
A server with a token in the header
For an API that uses a fixed token, pass --header. Note the difference between the two outputs:
$ claude mcp add --transport http secure-api https://mcp.deepwiki.com/mcp \
--header "Authorization: Bearer token-de-teste"
Added HTTP MCP server secure-api with URL: https://mcp.deepwiki.com/mcp to local config
Headers: {
"Authorization": "[REDACTED]"
}
$ claude mcp get secure-api
secure-api:
Scope: Local config (private to you in this project)
Status: ✔ Connected
Type: http
URL: https://mcp.deepwiki.com/mcp
Headers:
Authorization: Bearer token-de-testeadd hides the value. claude mcp get prints the token in plain text, and ~/.claude.json stores it that way too. Check the get output before you paste it into an issue or a screenshot.
How do you add a local MCP server (stdio)?
A local server is a process Claude Code starts on your machine. The -- separates Claude Code's options from the server command, and everything after it goes to the server untouched.
$ claude mcp add --transport stdio fs -- npx -y @modelcontextprotocol/server-filesystem /tmp/mcp-lab
Added stdio MCP server fs with command: npx -y @modelcontextprotocol/server-filesystem /tmp/mcp-lab to local config
$ claude mcp list
...
fs: npx -y @modelcontextprotocol/server-filesystem /tmp/mcp-lab - ✔ ConnectedTo pass an environment variable, use --env (or -e). Order matters. --env takes several pairs, so if the server name comes right after it, the CLI reads the name as one more pair:
$ claude mcp add --env API_KEY=abc123 api-env -- npx -y @modelcontextprotocol/server-filesystem /tmp/mcp-lab
Invalid environment variable format: api-env, environment variables should be added as: -e KEY1=value1 -e KEY2=value2
$ claude mcp add --env API_KEY=abc123 --transport stdio api-env -- npx -y @modelcontextprotocol/server-filesystem /tmp/mcp-lab
Added stdio MCP server api-env with command: npx -y @modelcontextprotocol/server-filesystem /tmp/mcp-lab to local configWith --transport stdio in between, it works. The docs describe exactly this case.
What is the difference between the local, project and user scopes?
The scope decides where the config is stored and which projects the server shows up in. The default is local.
| Scope | Stored in | Shows up in | Goes to git? |
|---|---|---|---|
local (default) | ~/.claude.json, under projects → the project path | This project only | No |
project | .mcp.json at the project root | This project, for anyone who clones it | Yes, if you commit it |
user | ~/.claude.json, at the top level | All your projects | No |
I tested all three. claude mcp get tells you each server's scope:
$ claude mcp add --transport http deepwiki --scope user https://mcp.deepwiki.com/mcp
Added HTTP MCP server deepwiki with URL: https://mcp.deepwiki.com/mcp to user config
$ claude mcp get deepwiki
deepwiki:
Scope: User config (available in all your projects)
Status: ✔ Connected
Type: http
URL: https://mcp.deepwiki.com/mcp
To remove this server, run: claude mcp remove deepwiki -s userThe user server added in one folder showed up in another folder's list. The first folder's local servers did not. In a folder with nothing configured, this was the answer:
$ cd /tmp/another-folder && claude mcp list
No MCP servers configured. Use `claude mcp add` to add a server.A naming trap: the MCP local scope lives in ~/.claude.json, in your home directory. It has nothing to do with the project's .claude/settings.local.json. The docs call this out themselves. And global is not a scope:
$ claude mcp add --transport http stripe --scope global https://mcp.stripe.com
Invalid scope: global. Must be one of: local, user, project, dynamic, enterprise, claudeai, managed, agentHow do you share servers with your team using .mcp.json?
--scope project creates or updates .mcp.json at the project root:
$ claude mcp add --scope project --env ROOT_DIR=/tmp/mcp-lab --transport stdio files \
-- npx -y @modelcontextprotocol/server-filesystem /tmp/mcp-lab
Added stdio MCP server files with command: npx -y @modelcontextprotocol/server-filesystem /tmp/mcp-lab to project config
File modified: /tmp/mcp-lab/.mcp.json
$ cat .mcp.json
{
"mcpServers": {
"files": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/tmp/mcp-lab"
],
"env": {
"ROOT_DIR": "/tmp/mcp-lab"
}
}
}
}Commit that file and anyone who clones the repo gets the same servers. For safety, Claude Code asks for approval before it uses a server from .mcp.json. Until then, it shows up like this:
$ claude mcp get deepwiki
deepwiki:
Scope: Project config (shared via .mcp.json)
Status: ⏸ Pending approval (run `claude` to approve)
Type: http
URL: https://mcp.deepwiki.com/mcp
To remove this server, run: claude mcp remove deepwiki -s projectTo approve, run claude in the folder and accept. To reset your choices, run claude mcp reset-project-choices. A cloned repo cannot approve itself: an enableAllProjectMcpServers committed to .claude/settings.json is ignored until you trust the folder.
One warning I saw in practice. In claude -p, the Agent SDK and cloud sessions there is no approval prompt, and the docs say .mcp.json servers load without asking. In my test, claude -p "/context" listed the tools of two servers that claude mcp list still showed as pending. If you run Claude Code in CI, review .mcp.json the way you review code.
How do you keep secrets out of .mcp.json?
Use environment variables. .mcp.json accepts ${VAR} and ${VAR:-default} in command, args, env, url and headers:
{
"mcpServers": {
"deepwiki": {
"type": "http",
"url": "${DEEPWIKI_URL:-https://mcp.deepwiki.com/mcp}"
},
"interno": {
"type": "http",
"url": "https://mcp.deepwiki.com/mcp",
"headers": { "Authorization": "Bearer ${INTERNAL_TOKEN}" }
}
}
}If the variable is not set and has no default, the server still loads, with the literal ${VAR} text, and claude mcp list warns you:
$ claude mcp list
...
MCP config diagnostics ⚠
[Contains warnings] Project config (shared via .mcp.json)
Location: /tmp/mcp-lab/.mcp.json
└ [Warning] [interno] mcpServers.interno: Missing environment variables: INTERNAL_TOKENA security detail from the docs: in a remote server's url and headers, variables holding Claude Code's own or your cloud provider's credentials, like ANTHROPIC_API_KEY, read as empty on purpose. That stops a third-party .mcp.json from sending your key to some other server. If you need to pass one of them, copy the value into a variable with a different name.
What happens when the same name exists in more than one scope?
Per the docs, Claude Code uses one definition, whole, in this order: local, project, user, then plugin servers and claude.ai connectors. Fields are not merged across scopes. In my test, with deepwiki in both local and project, get showed the local one, and remove without a scope refused to pick:
$ claude mcp remove deepwiki
MCP server "deepwiki" exists in multiple scopes:
- Local config (private to you in this project) (/home/box/.claude.json [project: /tmp/mcp-lab])
- Project config (shared via .mcp.json) (/tmp/mcp-lab/.mcp.json)
To remove from a specific scope, use:
claude mcp remove deepwiki -s local
claude mcp remove deepwiki -s projectWith deepwiki in user scope and another deepwiki still pending in .mcp.json, get showed the user one as connected. The docs do not cover this case explicitly, so do not rely on it. Use different names per scope.
How do you add a server from JSON?
If the server's docs give you a JSON block, use add-json. The type field is required for a remote server: without it, Claude Code reads the entry as stdio. From the CLI, the error is terse:
$ claude mcp add-json weather '{"type":"http","url":"https://mcp.deepwiki.com/mcp"}'
Added http MCP server weather to local config
$ claude mcp add-json broken '{"url":"https://mcp.deepwiki.com/mcp"}'
Invalid configuration: : Invalid inputHow do you list, inspect and remove MCP servers?
claude mcp list # every server, with status
claude mcp get deepwiki # details and scope of one server
claude mcp remove deepwiki -s local # remove it from one scope
claude mcp reset-project-choices # reset the .mcp.json approvalsThe statuses that showed up in claude mcp list during the test:
✔ Connected: Claude Code connected and health-checked the server.! Needs authentication: the server wants OAuth. Run/mcporclaude mcp login <name>.⏸ Pending approval: a.mcp.jsonserver you have not approved yet. Claude Code does not even try to connect.
The docs list others, like ✘ Failed to connect, with the error detail on an Issue: line in get. To turn a server off without deleting its config, use the /mcp panel inside Claude Code. The choice is saved per project in ~/.claude.json.
One more real error, hit by accident: some names are reserved for Claude Code's built-in servers.
$ claude mcp add --transport http workspace https://mcp.deepwiki.com/mcp
Cannot add MCP server "workspace": this name is reserved.How much context does an MCP server take?
Not much, at first. With tool search, on by default on supported models, only tool names and server instructions enter the context when the session opens. Full definitions load when Claude uses the tool. I measured with claude -p "/context" in an empty folder, then with DeepWiki added:
| /context category | No MCP | With DeepWiki |
|---|---|---|
| MCP server instructions | (not shown) | 1.2k |
| MCP tools (deferred) | (not shown) | 555 |
| Total | 15.7k | 16.9k |
The (deferred) rows do not count toward the total. These are Claude Code 2.1.296 numbers on this machine, and they change with version, model and server. To measure yours and trim the rest, see how to save tokens in Claude Code.
Frequently asked questions
What command installs an MCP server in Claude Code?▼
claude mcp add. For a remote server: claude mcp add --transport http <name> <url>. For a local one: claude mcp add <name> -- <command> [args]. Check with claude mcp list, which shows each server's status.
Where is the MCP config stored in Claude Code?▼
It depends on the scope. The local (default) and user scopes live in ~/.claude.json, in your home directory. The project scope lives in .mcp.json at the project root, and it is the only one meant for git.
Why does my .mcp.json server show Pending approval?▼
Because .mcp.json servers need approval before first use. Run claude in the project folder and approve it. Settings committed to the repo itself approve nothing until you trust the folder.
What is the difference between configuring MCP and building an MCP server?▼
Configuring means telling Claude Code where an existing server is, which is what this page covers. Building means writing the server. For that, see how to build an MCP server in Python.
Read next
- Claude Code is a harness, the main Claude Code guide
- How to build an MCP server in Python, for when the server you need does not exist
- How to save tokens in Claude Code: /context, /compact, subagents and cache
- How to configure hooks in Claude Code
- Harness, RAG and context engineering
Need to connect agents to your company's internal systems? Talk to Capiva.