
How Do You Add an MCP Server to Claude Code?
Carlos GarciaPublished How Do You Add an MCP Server to Claude Code?
Adding an MCP server to Claude Code is one command. Choosing where that command writes the configuration is what decides whether it works for you, for your team, or for neither.
Most guides show the command and stop. The result is a config that works on the machine it was created on and silently fails for everyone who clones the repository, for a reason that has nothing to do with the server. This covers the commands for each transport, what the three scopes do, and the approval behaviour that catches teams out.
What Is the Short Answer?
For a remote server, run claude mcp add --transport http <name> <url>. For a local one, run claude mcp add <name> -- <command> [args...].
Both default to local scope, which means the server loads only in the current project and stays private to you. Add --scope project to share it with your team through a .mcp.json file, or --scope user to get it in every project on your machine.
Then run /mcp inside Claude Code to check it connected.
Running an SEO or analytics stack you want Claude to reach directly? Get a free audit and see what is worth wiring up first.
Free audit
Where do you stand in AI search?
A manual SEO + AI search audit of your site: how ChatGPT, Gemini, Perplexity and Claude read and cite it today, and what to fix first. Report within 48 hours, no credit card.
Get my free auditOr have it all done: AI SEO services, $999 once
What the Transports Are, and Which One You Need
MCP servers reach Claude Code over one of four transports. The server's own documentation tells you which; you do not get to pick.
HTTP, for Hosted Servers
This is the modern default for anything running on someone else's infrastructure. If the server needs a static credential rather than an OAuth flow, pass it as a header.
claude mcp add --transport http notion https://mcp.notion.com/mcp
claude mcp add --transport http secure-api https://api.example.com/mcp \
--header "Authorization: Bearer your-token"In a .mcp.json file the type field "accepts streamable-http as an alias for http", so both spellings are valid if you are copying someone else's config.
SSE, Which Is on the Way Out
Server-Sent Events still works, and the docs are blunt about its status: "The SSE (Server-Sent Events) transport is deprecated. Use HTTP servers instead, where available."
You mostly do not need to think about it. Claude Code "tries the HTTP transport first and switches to SSE when the server doesn't accept it", and that automatic switch "requires Claude Code v2.1.265 or later". On an older build you pass --transport sse yourself, as in claude mcp add --transport sse asana https://mcp.asana.com/sse.
stdio, for Anything Running Locally
A stdio server is a process on your own machine that Claude Code starts and talks to over standard input and output. The form is claude mcp add [options] <name> -- <command> [args...].
The double dash is load-bearing. Per the docs, "the -- (double dash) separates Claude's own options, such as --transport, --env, and --scope, from the command and arguments that run the server." Everything after it belongs to the server process, including that process's own flags.
claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable \
-- npx -y airtable-mcp-serverWebSocket, Which the Add Command Will Not Take
There is a fourth transport and it has no shorthand: "The claude mcp add --transport flag doesn't accept ws." Configure it as JSON instead.
claude mcp add-json events-server \
'{"type":"ws","url":"wss://mcp.example.com/socket","headers":{"Authorization":"Bearer YOUR_TOKEN"}}'The --env Trap That Rejects Your Command
This one is worth knowing before it happens to you, because the error gives no hint about the cause.
If you put the server name directly after --env, the command fails. The docs explain why: "--env accepts multiple KEY=value pairs. If the server name comes directly after --env, the CLI reads the name as another pair and rejects it, so place at least one other option, such as --transport stdio, between --env and the server name."
The first of these is rejected and the second works.
claude mcp add --env API_KEY=abc myserver -- npx server
claude mcp add --env API_KEY=abc --transport stdio myserver -- npx serverThe flags also have short forms: -t for --transport, -H for --header, -e for --env, and -s for --scope.
The Three Scopes, and Where Each One Writes
This is the decision that matters, and the file paths are not where most people assume.
- Local scope is the default. It "loads only in the project where you added it and stays private to you", stored in
~/.claude.jsonunder that project's path. Not shared. - Project scope stores the configuration "in a
.mcp.jsonfile at your project's root directory" and is shared via version control. - User scope is also "stored in
~/.claude.json" but loads across every project on your machine, still private to you.
There is a genuine naming collision here that Claude Code's own docs call out: "The term 'local scope' for MCP servers differs from general local settings. MCP local-scoped servers are stored in ~/.claude.json (your home directory), while general local settings use .claude/settings.local.json (in the project directory)."
If you have been looking for your MCP servers in .claude/settings.local.json, that is why they are not there — no MCP scope writes to a settings.json file at all.
claude mcp add --transport http stripe --scope local https://mcp.stripe.com
claude mcp add --transport http shared-server --scope project https://example.com/mcp
claude mcp add --transport http hubspot --scope user https://mcp.hubspot.com/anthropicWondering which of your tools are worth connecting to an AI assistant at all? Start with a free audit.
What Happens When Two Scopes Define the Same Server
Nothing merges. The rule is explicit: "When the same server is defined in more than one place, Claude Code connects to it once, using the definition from the highest-precedence source. The entire server entry from that source is used; fields are not merged across scopes." The order, highest first, is local scope, then project scope, then user scope, then plugin-provided servers, then claude.ai connectors.
Matching works differently at different levels. Claude Code "matches duplicates across the three scopes by name", but it "matches plugins and connectors by endpoint, so one that points at the same URL or command as an enabled server above counts as a duplicate".
Above all of them sits an administrator option: a server provided "through the managedMcpServers managed setting ranks above all of these, so when one of them duplicates it, Claude Code connects the organization's definition." That requires v2.1.259 or later.
The Approval Trap: Why a Cloned Repo Cannot Approve Its Own Servers
Project-scoped servers are not trusted automatically: "For security reasons, Claude Code prompts for approval in interactive sessions before using project-scoped servers from .mcp.json files." Reasonable, and you can reset your answers with claude mcp reset-project-choices.
The obvious fix is to commit an approval setting into the repository so nobody gets prompted. That does not work, and the docs say so directly: "A cloned repository can't approve its own servers: enableAllProjectMcpServers or enabledMcpjsonServers committed to the project's .claude/settings.json is ignored in an untrusted folder, and the server stays at ⏸ Pending approval."
The approvals that are honoured in an untrusted folder come from outside the repository: your own user settings at ~/.claude/settings.json, managed settings, and settings passed with --settings. That is the whole point — a repository you just cloned should not be able to grant itself trust. Rejection always applies regardless: "A disabledMcpjsonServers entry in any settings file still rejects the server."
There are also contexts with no prompt to show. In claude -p runs, Agent SDK sessions and cloud sessions outside a project's threads, "Claude Code can't show that prompt: it loads project-scoped servers without asking."
Two Settings Keys That Look Related and Are Not
Worth separating, because the names are almost identical.
enabledMcpjsonServersanddisabledMcpjsonServersgovern approval of servers coming from a project's.mcp.json.disabledMcpServersandenabledMcpServersare stored per project in~/.claude.jsonand are, per the docs, "unrelated toenabledMcpjsonServersanddisabledMcpjsonServers".
The second pair is what the /mcp panel toggles when you switch a server off.
How to Add One, Step by Step
Step 1: find out which transport the server uses. Its documentation will give you either a URL or a launch command. A URL means HTTP. A command means stdio.
Step 2: run the add command. Use --transport http with the URL, or -- followed by the command. Leave the scope alone for now so it lands in local scope.
Step 3: check it connected. Run claude mcp list. The status strings are specific and tell you exactly what to do next.
Step 4: authenticate if it asks. A status of ! Needs authentication means a sign-in is pending. Run claude mcp login <name> in your shell, or handle it from the /mcp panel.
Step 5: inspect it. claude mcp get <name> shows the stored definition, which is the fastest way to catch a typo in a URL or a header.
Step 6: promote it once it works. Re-add with --scope project to share it, or --scope user to have it everywhere. Prove it locally first.
Step 7: remove it cleanly when you are done. claude mcp remove <name> takes the config out, and for remote servers it goes further: "When you remove a remote server, Claude Code also deletes the OAuth tokens and client registration it stored for that server."
Reading claude mcp list Output
The status strings are the diagnostic, and each points somewhere different.
✔ Connected— working.! Needs authentication— sign in withclaude mcp login <name>.✘ Failed to connect— the server or the command is the problem, not the config.⏸ Pending approval (run claude to approve)— the project-scope prompt is waiting.✘ Rejected (see disabledMcpjsonServers in settings)— something is explicitly blocking it.⊘ Disabled for this project (re-enable via /mcp)— toggled off in the panel.
A dropped connection is retried for you: five attempts with exponential backoff starting at one second, and up to three retries on a first HTTP or SSE connection. To force it, /mcp reconnect all works on v2.1.284 or later; earlier builds answer MCP server "all" not found.
Want to know which parts of your marketing stack actually produce data worth automating? Request a free audit.
When to Reach for Each Scope
Use local scope while you are still finding out whether a server is any good. It is the default for a reason, and a bad server affects nobody but you.
Use project scope when the server is part of how the project is worked on — a database, an issue tracker, a design tool the team needs. Check .mcp.json into version control "so everyone on your team gets the same MCP tools and services".
Use user scope for servers that follow you rather than the work: your own notes, your own cloud account, anything you would want in a brand-new empty directory.
Leave it to managedMcpServers if you are an administrator rolling something out to an organisation — it outranks everything a user configures.
Limitations and Things That Trip People Up
Some names are taken. Claude Code reserves workspace, claude-in-chrome, computer-use, Claude Preview and Claude Browser, and "claude mcp add rejects a reserved name with an error".
A url with no type is an error, not a guess. Claude Code will tell you: MCP server "<name>" has a "url" but no "type"; add "type": "http" (or "sse" / "ws") to this entry.
add-json wants the inner object. If you are copying a block from another client's docs, "pass claude mcp add-json the object inside mcpServers, not the wrapper". Handing it the wrapper is the most common copy-paste failure.
Relative paths in a shared .mcp.json need a default. Project configs use ${CLAUDE_PROJECT_DIR:-.} so the path resolves on a teammate's machine as well as yours; stdio servers also get CLAUDE_PROJECT_DIR in their environment. Claude Code separately warns Leading or trailing whitespace in: headers.Authorization, usually a stray character from a copied token.
Trust is the real limitation. The documentation carries an explicit warning: "Verify you trust each server before connecting it. Servers that fetch external content can expose you to prompt injection risk." An MCP server is code someone else wrote, running with your credentials, reading content you did not vet. Treat it like any other dependency.
How This Compares to the Alternatives
Installing a plugin is often less work for the same result. A plugin can bundle an MCP server together with the skills that drive it, which is "considerably less work than wiring both yourself". Our guide to Claude Code plugins covers how marketplaces and install scopes work there. A raw MCP server configuration "is right when you want the connection and none of the surrounding workflow".
Writing a CLAUDE.md instruction is the right answer when you want Claude to behave differently rather than to reach something new. Memory shapes judgement; MCP adds capability. A hook is the choice when something must happen deterministically on every tool call — MCP servers are tools Claude may choose to use, hooks are rules that always fire.
Doing nothing is underrated. Every connected server adds tool definitions to the context and another thing that can fail or mislead. Connect the two or three you actually use.
Final Thoughts
The command is the easy half. Run it without a scope flag first, confirm ✔ Connected in claude mcp list, and only then decide whether it belongs to you, to the project, or to the organisation.
And if you are putting a server into a repository for a team, the approval cannot ride along with it. Each person's trust comes from their own settings or from a managed policy, never from the folder they just cloned — which is exactly the behaviour you would want if the folder were someone else's.
Not sure which data sources are worth connecting in the first place? Get a free SEO audit.
Want this done for you?
SEO Stuff gets businesses cited by ChatGPT, Gemini, Perplexity and Claude, and ranking in Google. Start with the free audit, a call, or the package.
See where you stand
A free, manual SEO + AI search audit of your site, with a report within 48 hours. No credit card, no sales call.
Get my free auditTalk it through
A free 15-minute call with the founder about whether AI search is a meaningful opportunity for your business.
Free strategy callHave it done
The Done-For-You Package: audit, 10 pages of content, 3 DR50+ placements, dashboard. $999 once, delivered in 21 business days.
See the package

