Skip to content
AI Dev Toolkit.
Esc
  • AI Token CounterCount tokens for GPT, Claude, Gemini, DeepSeek, Qwen and more.Tool
  • LLM API Cost CalculatorEstimate per-request, daily and monthly API costs.Tool
  • AI Model ComparisonCompare prices, context windows and features across models.Tool
  • AI Model Pricing PagesSpecs, real costs and cheaper alternatives for popular models.Tool
  • Context Window CheckerSee whether your text fits each model's context window.Tool
  • Subscription vs API CalculatorFind out whether a chat plan or the API is cheaper for you.Tool
  • GPU / VRAM CalculatorCheck how much VRAM a local model needs and which GPUs fit.Tool
  • Claude Code Error DatabaseExact Claude Code error messages with tested fixes.Tool

Guide · Coding agents

How to set up MCP servers in Claude Code

To add an MCP server to Claude Code, run claude mcp add in your terminal: claude mcp add --transport http <name> <url> for a remote server, or claude mcp add <name> -- <command> for a local one. Then run claude mcp list to check it shows Connected, and use /mcp inside a session to sign in or switch servers off.

By Tahir NazirUpdated 12 min read

On this page
  1. How to add a remote (HTTP) MCP server
  2. How to add a local (stdio) MCP server
  3. Local, project or user scope: where servers are saved
  4. Share servers with your team in .mcp.json
  5. API keys and secrets: keep tokens out of git
  6. Three worked examples: GitHub, Playwright and a database
  7. Check status and sign in with /mcp
  8. Claude Code MCP on Windows
  9. Troubleshooting: when an MCP server won’t connect
  10. Questions people ask

How to add a remote (HTTP) MCP server

A remote server is a web service with an MCP URL. Run this in your terminal, not inside a claude session. The name is yours to choose; Claude Code uses it to label the server’s tools:

Remote server (Streamable HTTP)
# Syntax
claude mcp add --transport http <name> <url>

# Anthropic's hosted Claude Code docs server: no sign-in needed
claude mcp add --transport http claude-code-docs https://code.claude.com/docs/mcp

# A server that takes a token in a header
claude mcp add --transport http my-api https://api.example.com/mcp \
  --header "Authorization: Bearer your-token"

Many hosted servers, including Sentry, Notion and Linear, use OAuth instead of a token. Add them with just the URL; claude mcp list then shows ! Needs authentication. Start claude, run /mcp, pick the server and choose Authenticate to sign in in your browser. From the shell, claude mcp login <name> does the same. Claude Code stores the tokens and refreshes them.

Some services still publish an SSE URL. The SSE transport is deprecated, but since v2.1.265 --transport http falls back to SSE on its own when the server needs it. WebSocket (wss://) servers can’t be added with --transport; use claude mcp add-json with "type":"ws".

How to add a local (stdio) MCP server

A local server is a program Claude Code starts on your machine, usually with npx or uvx. Everything after -- is the command that starts it, passed through untouched:

Local server (stdio)
# Syntax
claude mcp add [options] <name> -- <command> [args...]

# Playwright: a browser Claude can drive (needs Node.js 18 or later)
claude mcp add playwright -- npx -y @playwright/mcp@latest

# With an environment variable for the server
claude mcp add --env API_KEY=your-key --scope local my-server -- npx -y some-mcp-package

The -- matters. Without it, Claude Code tries to read the server’s own flags, such as -y or --port, as its options. The other trap is --env: it accepts several KEY=value pairs, so a name placed straight after it is read as one more pair. We got Invalid environment variable format: myserver from claude mcp add --env API_KEY=abc myserver -- node server.js. Put another option, such as --scope local, between the last --env and the name.

The success line, Added stdio MCP server playwright with command: npx -y @playwright/mcp@latest to local config, only means the entry was saved. Run claude mcp list to check the server actually starts. The first check can fail while npx downloads the package: ours timed out after 30 seconds on the first run and showed ✔ Connected on the second.

Local, project or user scope: where servers are saved

Every server lives in one of three scopes, chosen with --scope when you add it. Local is the default:

Pick the scope by who should get the server. When the same name appears twice, the higher scope’s whole entry wins, then plugins, then claude.ai connectors.
  • Local suits personal or experimental servers and anything holding your own credentials.
  • Project is for servers the whole team should have, such as the project’s database or issue tracker.
  • User is for tools you want in every repository, such as a docs server or a browser.

On Windows, ~/.claude.json is %USERPROFILE%\.claude.json. Claude Code doesn’t read files such as ~/.claude/mcp.json or ~/.claude/.mcp.json, a common reason a hand-edited server never appears. A scope is fixed when you add a server, so to move one, remove it (claude mcp remove <name> --scope local) and add it again with the new scope.

Share servers with your team in .mcp.json

claude mcp add --scope project writes .mcp.json in the project root, and you can also write it by hand. Commit it, and everyone who clones the repository gets the same servers:

.mcp.json
{
  "mcpServers": {
    "claude-code-docs": {
      "type": "http",
      "url": "https://code.claude.com/docs/mcp"
    },
    "playwright": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@playwright/mcp@latest"]
    }
  }
}
  • Approval. The first time someone opens the project interactively, Claude Code asks them to approve each project server, so a cloned repository can’t start processes on their machine unasked. Until then, claude mcp list shows it as “⏸ Pending approval”. Run claude mcp reset-project-choices to undo a rejection.
  • Non-interactive runs skip that prompt. claude -p, Agent SDK and cloud sessions load project servers without asking. Use disabledMcpjsonServers or --strict-mcp-config to keep one out.
  • Remote entries need a `type`. An entry with a url but no type is read as stdio and skipped with a message telling you to add "type": "http".
  • Restart after editing. Claude Code reads .mcp.json at session start.

API keys and secrets: keep tokens out of git

Never commit a token in .mcp.json. Write a reference instead: Claude Code expands ${VAR} and ${VAR:-default} in command, args, env, url and headers when the server starts, so each teammate sets the variable in their own shell. The quoting when you add the server decides what gets saved:

Single quotes save the reference, not the token
claude mcp add --scope project --transport http github https://api.githubcopilot.com/mcp/ \
  --header 'Authorization: Bearer ${GITHUB_MCP_PAT}'

That wrote "Authorization": "Bearer ${GITHUB_MCP_PAT}" to .mcp.json, safe to commit. With double quotes, Bash replaces the variable first and the real token is saved. In PowerShell, single quotes also keep ${GITHUB_MCP_PAT} literal. If the variable isn’t set, claude mcp list warns Missing environment variables: GITHUB_MCP_PAT and Claude Code sends the text unexpanded. GitHub answered that with HTTP 400 … Authorization header is badly formatted.

Local and user servers live in ~/.claude.json, outside the repository, but a token typed into the command is still stored there in plain text. Give each server its own narrow token so a leak is easy to revoke. The MCP config generator writes secrets as variable references for Claude Code and every other app that can read them.

Three worked examples: GitHub, Playwright and a database

GitHub (remote, personal access token)

Create a fine-grained token in your GitHub settings, limited to the repositories Claude should touch, and export it as GITHUB_MCP_PAT. Then add the server with the single-quoted command above, at project or local scope. For a server that can only read, use the URL https://api.githubcopilot.com/mcp/readonly. Run /mcp and check it shows connected, then ask: “Show me all open PRs assigned to me.” A bad token shows as failed, with the HTTP status in the detail.

Playwright (local browser)

claude mcp add playwright -- npx -y @playwright/mcp@latest gives Claude 25 browser tools, from browser_navigate to browser_take_screenshot. It drives the Chrome you already have; add --browser firefox after the package name for another browser. Try: “Use playwright to open http://localhost:3000 and tell me if the sign-up form renders.”

A database (DBHub, local)

DBHub (@bytebase/dbhub) connects to Postgres, MySQL, SQL Server, MariaDB, Oracle or SQLite through a connection string. It needs Node.js 22.5 or later. Use a database user that can only read, so nothing Claude runs can change data:

DBHub
# Try it first with the bundled sample database
claude mcp add db -- npx -y @bytebase/dbhub@latest --demo

# Your own database, with a read-only login
claude mcp add --transport stdio db -- npx -y @bytebase/dbhub@latest \
  --dsn "postgresql://readonly:pass@localhost:5432/analytics"

For files rather than a database, the reference filesystem server takes the folders it may use as arguments: claude mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem /path/to/project. Here is our check after adding the three examples, with the GitHub entry not yet approved:

claude mcp list output (Claude Code 2.1.293)
Checking MCP server health…

github: https://api.githubcopilot.com/mcp/ (HTTP) - ⏸ Pending approval (run `claude` to approve)
playwright: npx -y @playwright/mcp@latest - ✔ Connected
db: npx -y @bytebase/dbhub@latest --demo - ✔ Connected

Check status and sign in with /mcp

Commands for managing servers
CommandWhereWhat it does
claude mcp listShellEvery server with a health check: ✔ Connected, ! Needs authentication, ✘ Failed to connect (with the reason)
claude mcp get <name>ShellOne server’s scope, status, command or URL, and an Issue: line on failure
claude mcp remove <name>ShellDeletes the entry, plus stored OAuth tokens for a remote server
/mcpSessionStatus, tool counts, Authenticate, Reconnect and on/off toggles
/mcp disable <name>SessionStops connecting to a server for this project but keeps its config
/mcp reconnect allSessionRetries every failed server and every one that needs sign-in

Turning off servers you aren’t using matters for context as well as speed. Claude Code defers MCP tool definitions by default, loading only names until a tool is needed, so many servers cost little. But each still adds its names and instructions, and very large tool results are capped: Claude Code warns above 10,000 tokens and, by default, saves anything over 25,000 to a file instead of the conversation (MAX_MCP_OUTPUT_TOKENS changes the limit). If a session hits Prompt is too long, unused servers are one of the first things to cut.

Claude Code MCP on Windows

  • The commands are the same. claude mcp add works in PowerShell and Command Prompt as it does in Bash.
  • `cmd /c` is no longer needed for npx. The MCP reference servers’ READMEs still say “On Windows, use cmd /c to launch npx”, but Claude Code’s current docs don’t, and the 2.1.119 release removed a false “requires cmd /c” warning. On Windows 11 with 2.1.293, -- npx -y @playwright/mcp@latest and -- cmd /c npx -y @playwright/mcp@latest both connected, so either works.
  • Environment variables use PowerShell syntax. For a longer startup timeout: $env:MCP_TIMEOUT = "60000"; claude.
  • Testing a URL. Use curl.exe -I <url> in PowerShell, since plain curl there is an alias for Invoke-WebRequest.
  • Importing from Claude Desktop with claude mcp add-from-claude-desktop works only on macOS and WSL.

Troubleshooting: when an MCP server won’t connect

Common symptoms and fixes
What you seeLikely causeFix
No MCP servers configuredAdded from another folder (local scope is per project), or a file Claude Code doesn’t readRe-add here, or use --scope user; edit only .mcp.json or ~/.claude.json
✘ Failed to connect on a stdio serverThe command fails, or -- was left outRun the command yourself, for example npx -y @playwright/mcp@latest, and compare it with claude mcp get <name>
connection timed out after 30000msFirst run while npx downloads, or a slow serverRun claude mcp list again, or start with MCP_TIMEOUT=60000 claude
! Needs authenticationAn OAuth server you haven’t signed in to/mcp → Authenticate, or claude mcp login <name>
HTTP 400 or 401 with a header you setBad, expired or unexpanded tokenCheck the variable is set and not a name Claude Code reads as empty; look for hidden whitespace warnings
MCP endpoint not foundWrong URL pathCheck the full URL with claude mcp get <name> against the server’s docs
Connected but no toolsA required environment variable is missingPass it with --env KEY=value or in the entry’s env field
.mcp.json changes ignoredRead only at startup, or rejected earlierRestart; run claude mcp reset-project-choices

New to MCP itself? What is MCP explains servers, tools and transports, and the risks of connecting servers you don’t control. And once your servers work, a short CLAUDE.md is the place to tell Claude when to use them.

FAQ

Questions people ask

Where does Claude Code store MCP server configuration?

Local and user servers are stored in ~/.claude.json in your home folder (%USERPROFILE%\.claude.json on Windows): local ones under the project’s path, user ones under the top-level mcpServers key. Project servers are stored in .mcp.json in the project root. Run claude mcp get <name> to see which scope holds a server.

How do I add an MCP server to Claude Code for all projects?

Add it at user scope: claude mcp add --scope user --transport http <name> <url>, or claude mcp add --scope user <name> -- <command> for a local server. User-scoped servers load in every project on your machine and stay private to you. To share a server with a team instead, use --scope project.

Why doesn’t my .mcp.json server show up in Claude Code?

Claude Code reads .mcp.json only at startup and asks you to approve each project server first, so restart and accept the prompt. Check the file is in the project root and valid JSON: claude mcp list names any field it couldn’t parse. If you rejected the server before, run claude mcp reset-project-choices.

Does .mcp.json support environment variables?

Yes. Claude Code expands ${VAR} and ${VAR:-default} in command, args, env, url and headers. Use them for tokens and machine-specific paths so the file is safe to commit. Some credential variables, such as ANTHROPIC_API_KEY, read as empty in a remote server’s URL and headers, so use a variable name of your own.

Can I use my claude.ai connectors in Claude Code?

Yes. When you sign in to Claude Code with a claude.ai account, connectors you added at claude.ai appear in /mcp automatically. They don’t load when an API key, apiKeyHelper or a cloud provider such as Bedrock is the active login. A server you add in Claude Code takes precedence over a connector with the same URL.

How do I remove or turn off an MCP server in Claude Code?

claude mcp remove <name> deletes it, and for a remote server also deletes stored OAuth tokens. Add --scope if the name exists in more than one scope. To keep the config but stop connecting, toggle it off in /mcp or run /mcp disable <name> inside a session; it stays off for that project until you turn it back on.

Try it

Tools from this guide

Keep reading