How to Add a Claude Code MCP Server and Fix Common Errors
Add MCP servers to Claude Code with claude mcp add, choose a scope, write .mcp.json, convert other clients' JSON, and fix servers that won't connect.
To add an MCP server to Claude Code, run claude mcp add with a transport, a name, and either a URL or a launch command. Then run claude mcp list to confirm it connected. Remote servers use --transport http. Local servers put the launch command after a -- separator.
The config lives in one of three scopes (local, project, user). Local is the default, and --scope project writes a .mcp.json file at your project root that you can commit. The rest of this post covers each add pattern, the JSON format, and what to check when a server doesn't show up.
Claude Code MCP add: the three commands you'll use#
Most setup instructions boil down to a URL, a launch command, or a JSON block. Each one maps to a command.
A URL means a remote server. Use --transport http:
claude mcp add --transport http example https://mcp.example.com/mcp
If the instructions give an API key or token header, pass it with --header. If they say the endpoint uses SSE, follow the SSE option in the Claude Code MCP docs. For a wss:// endpoint, --transport doesn't accept ws, so the docs have a separate WebSocket option.
A launch command means a local stdio server. Put the whole command after -- so flags like -y go to the command, not to Claude Code. Environment variables go with --env, after the server name and before --:
claude mcp add example --env API_KEY=your-key -- npx -y @example/mcp-server
A JSON block means add-json. Pass the object that sits inside mcpServers, not the wrapper:
claude mcp add-json example '{"command":"npx","args":["-y","@example/mcp-server"]}'
Each successful add or add-json prints an Added ... line. That means the configuration was written, not that the server is healthy. Check health next.
Check that it actually connected#
# List all configured servers
claude mcp list
# Details for one server
claude mcp get example
# Inside Claude Code
/mcp
claude mcp list shows a status beside each server, such as ✔ Connected, ! Needs authentication, or ✘ Failed to connect. A failure status means Claude Code couldn't reach that server. It doesn't mean the list command broke.
For a failed server, claude mcp list appends the failure detail to the status line, and claude mcp get <name> shows it on an Issue: line. That's the HTTP status or error code plus any error text the server returned. Read that line before you change anything.
The /mcp panel also shows a tool count for each connected server and flags servers that advertise tools but expose none.
Claude Code MCP scopes: local, project, user#
Every add command writes to local scope unless you pass --scope project or --scope user.
| Scope | Flag | Use it for |
|---|---|---|
| Local | (default) | Servers you're trying out |
| Project | --scope project |
Servers the whole team should share, stored in .mcp.json |
| User | --scope user |
Servers you want configured at the user level |
My advice: start in local scope while you test. Once a server is stable and the team needs it, move it to project scope and commit the file.
claude mcp add --transport http example --scope project https://mcp.example.com/mcp
The same server name can exist in more than one scope. If the endpoints differ, Claude Code warns about the conflict in claude mcp list and /mcp. OAuth sign-ins are stored per endpoint, so you may have to sign in again in a project where a different definition loads. Keep the one you want and remove the others.
The Claude Code MCP config file: .mcp.json#
The project-scope file is .mcp.json at your project root, with entries under mcpServers. A minimal example with one stdio server and one remote server:
{
"mcpServers": {
"local-tool": {
"command": "npx",
"args": ["-y", "@example/mcp-server"]
},
"remote-tool": {
"type": "http",
"url": "https://mcp.example.com/mcp"
}
}
}
Two rules matter here:
- An entry with no
typeis read as stdio. Aurlentry withouttypetherefore fails. Add"type": "http","sse", or"ws"to match the endpoint. - Server names should use only letters, numbers, hyphens, and underscores.
You can reference environment variables in this file with ${VAR}, and give a fallback with ${VAR:-default}. That keeps secrets out of the committed file. If a variable isn't set and has no default, Claude Code warns you in claude mcp list and /mcp, and still loads the server with the ${VAR} text unexpanded.
Convert JSON from another client#
Setup pages for Claude Desktop or Cursor often show only an mcpServers block. Claude Code reads the same wrapper and entry shape, but add-json wants the inner object. The script below does the conversion and flags the two problems that bite most often: a url with no type, and a key with characters outside the allowed set. It uses no network and just prints.
const block = {
mcpServers: {
example: { command: "npx", args: ["-y", "@example/mcp-server"] },
"bad name!": { command: "node", args: ["server.js"] },
remote: { url: "https://mcp.example.com/mcp" },
},
};
for (const [name, entry] of Object.entries(block.mcpServers)) {
const problems = [];
if (!/^[A-Za-z0-9_-]+$/.test(name)) {
problems.push("rename: use only letters, numbers, hyphens, underscores");
}
if (entry.url && !entry.type) {
problems.push('add "type": "http", "sse", or "ws"');
}
if (problems.length) {
console.log(`# ${name}: ${problems.join("; ")}`);
continue;
}
console.log(`claude mcp add-json ${name} '${JSON.stringify(entry)}'`);
}
Shell quoting is the usual trap with add-json. Wrap the JSON in single quotes, as above, so the double quotes survive.
Remove or disable a server#
claude mcp remove example --scope local
Pass the scope the server was added in. When you remove a remote server, Claude Code also deletes the OAuth tokens and client registration it stored for it.
If you want a server off without deleting it, the project's disabledMcpServers list handles that, and you can turn it back on from the /mcp panel.
Claude Code MCP not working or not showing#
Work through these in order. The status text usually names the cause.
Status says ⏸ Pending approval. This is a project-scoped server from .mcp.json that you haven't approved. Run claude interactively in the project and approve it. A cloned repository can't approve its own servers: enableAllProjectMcpServers or enabledMcpjsonServers committed in the project's .claude/settings.json is ignored until you trust the workspace.
Status says ✘ Rejected. A disabledMcpjsonServers entry in a settings file rejects it. That entry wins even in an untrusted folder. It shows in claude mcp get <name>.
Status says ⊘ Disabled for this project. The project's disabledMcpServers list names it. Re-enable it from /mcp.
✘ Failed to connect. Run claude mcp get <name> and read the Issue: line for the status code and server message. A ✘ Connection error status carries no detail on purpose, because the exception text could embed a URL with secrets.
Server is skipped at load. Claude Code reserves some names, including workspace, claude-in-chrome, computer-use, Claude Preview, and Claude Browser. A config using one is skipped with a warning. claude mcp add rejects them outright. Rename the server.
Hidden whitespace. Pasting a token with a trailing newline is common. Claude Code warns, for example Leading or trailing whitespace in: headers.Authorization, but it doesn't trim anything. Edit the value yourself.
Needs authentication. Complete sign-in from /mcp. If the connection still fails afterward, the message includes the HTTP status or error code and the origin of the server URL, never the path or query.
This applies to any server, Figma included. If a Figma server fails, the same checks apply: status, Issue: line, scope conflicts, then auth. The pack here doesn't cover Figma-specific setup, so use that server's own instructions for the endpoint and credentials.
Common mistakes#
- Putting flags after the server name without
--. For stdio servers, everything that starts the server goes after--. Otherwise-yis parsed as a Claude Code option. - Forgetting
typeon aurlentry. It gets read as stdio and fails. - Pasting the whole
mcpServerswrapper intoadd-json. Pass only the inner object. - Defining one name in two scopes with different endpoints. You get the conflict warning and separate OAuth sign-ins.
- Committing secrets to
.mcp.json. Use${VAR}or${VAR:-default}instead. - Assuming
Added ...means working. It only means the config was saved. Runclaude mcp get <name>. - Expecting prompts from a server named
anthropic-skills. Claude Code reserves that name for skills synced from claude.ai, so its prompts don't appear as commands, although its tools still work. Rename the server to list its prompts.
Two smaller notes. A remote server you've used before can show a cached status in /mcp, meaning the tool list came from a discovery cache and the server connects on first use. That needs Claude Code v2.1.221 or later and isn't an error. And an empty url shows as not configured, which is normal for plugin placeholders.
For the full reference, see the Claude Code MCP documentation.
Quick reference#
| Task | Command |
|---|---|
| Add remote server | claude mcp add --transport http NAME URL |
| Add with header | add --header (see the docs for the exact value format) |
| Add stdio server | claude mcp add NAME --env KEY=val -- npx -y PKG |
| Add from JSON | claude mcp add-json NAME '{...}' |
| Share with team | add --scope project |
| List and check | claude mcp list |
| Inspect one | claude mcp get NAME |
| Remove | claude mcp remove NAME --scope SCOPE |
| In-session panel | /mcp |
Checklist when a server won't show up:
- Run
claude mcp get NAMEand read the status andIssue:line. - If pending, run
claudein the project and approve it. - Confirm the name is allowed and not reserved.
- Confirm
urlentries have atype. - Look for whitespace in tokens and unset
${VAR}values. - Check for the same name in another scope.
Quick answers
How do I add an MCP server to Claude Code?
Run claude mcp add --transport http NAME URL for a remote server, or claude mcp add NAME -- npx -y PACKAGE for a local one. Then confirm with claude mcp list.
Where is the Claude Code MCP config file for a project?
Project-scoped servers live in .mcp.json at the project root under mcpServers. Add them with --scope project or edit the file directly and commit it.
How do I remove a Claude Code MCP server?
Run claude mcp remove NAME --scope SCOPE using the scope it was added in. For a remote server this also deletes its stored OAuth tokens and client registration.
Why is my Claude Code MCP server not showing up?
Check claude mcp get NAME. Common causes are a project server pending approval, a server disabled or rejected in settings, a reserved name, or a url entry missing its type.
Did this solve it?
One tap. No account.
Sorry about that. What was missing?
from 0 readers
Saved you an hour? Send a tip.
USDC or ETH on Base. Keeps the notes free and the examples running.

0x9dFD2Ee86182f92464b50809C6702B999a0Cd54f
On a computer? Scan the code with your phone wallet, or copy the address.
USDC or ETH on Base works best. Other tokens on Base, Ethereum or Arbitrum also reach this address. Tips are optional and unlock nothing; every guide stays free.
Discussion
Start the discussion
Next note