Connect an MCP server to Claude Code
- Spec
2026-07-28- Evidence
- E3Tested in a real clientarm64
- Verified
Tested with Claude Code 2.1.312 on Linux (arm64), using our TypeScript example server. To keep the test away from a real setup, we pointed CLAUDE_CONFIG_DIR at an empty directory.
Three scopes
Section titled “Three scopes”Claude Code stores each server in one of three scopes. Pick the scope first, because it decides which file the server goes into.
| Scope | Flag | Where it is stored | Who sees it |
|---|---|---|---|
| Local (default) | --scope local |
~/.claude.json, under the current project |
You, in this project |
| Project | --scope project |
.mcp.json in the project root |
Everyone who clones the project |
| User | --scope user |
~/.claude.json |
You, in every project |
Use project for servers the whole team needs and commit .mcp.json. Use local or user for anything that carries your own credentials.
Add a local (stdio) server
Section titled “Add a local (stdio) server”claude mcp add --scope project hello-ts -- node /absolute/path/to/hello-server/src/server.tsExpectedAdded stdio MCP server hello-ts with command: node … to project config
Everything after -- is the command that starts the server, passed through unchanged. Claude Code writes:
{ "mcpServers": { "hello-ts": { "type": "stdio", "command": "node", "args": ["/absolute/path/to/hello-server/src/server.ts"], "env": {} } }}Environment variables without putting secrets in the file
Section titled “Environment variables without putting secrets in the file”.mcp.json is meant to be committed, so do not write API keys into it. Claude Code replaces ${NAME} with a variable from its own environment when it starts the server:
claude mcp add -e 'API_KEY=${API_KEY}' --scope project my-server -- npx -y my-mcp-serverThe single quotes keep your shell from expanding ${API_KEY} itself, so the file stores the reference, not the key. We checked this with a server that refuses to start unless the variable has a specific value: it connected when we started Claude Code with the variable set. When the variable was missing, the server received the literal text ${API_KEY} and exited. ${NAME:-default} supplies a default.
Add a remote (Streamable HTTP) server
Section titled “Add a remote (Streamable HTTP) server”claude mcp add --scope project --transport http my-remote https://mcp.example.com/mcp \ --header 'Authorization: Bearer ${MCP_TOKEN}'{ "mcpServers": { "my-remote": { "type": "http", "url": "https://mcp.example.com/mcp", "headers": { "Authorization": "Bearer ${MCP_TOKEN}" } } }}If MCP_TOKEN is not set, claude mcp list warns: Missing environment variables: MCP_TOKEN. Servers that use OAuth instead of a fixed token are signed in from /mcp inside a session, or with claude mcp login <name>. --transport sse still exists for old servers; it is deprecated.
Approve project servers
Section titled “Approve project servers”A server from .mcp.json does not start until you approve it. Until then it shows:
Status: ⏸ Pending approval (run `claude` to approve)Run claude in the project and accept the prompt. To undo your choices, run claude mcp reset-project-choices. A repository cannot approve its own servers: approval settings committed to the project’s .claude/settings.json are ignored until you trust the folder.
Check what Claude Code sees
Section titled “Check what Claude Code sees”claude mcp list # every server with a health statusclaude mcp get hello-ts # one server, with the failure reason if anyFor approved servers, both commands start the server and report its health. These are the statuses we saw:
| Status | What it meant in our test |
|---|---|
✔ Connected |
The server started and answered |
✘ Failed to connect with Issue: ENOENT: Executable not found in $PATH: "…" |
The command does not exist in the PATH Claude Code uses |
✘ Failed to connect with Issue: CONNECTION_CLOSED: Connection closed |
The server started and exited, here because a required variable was missing. See Connection closed |
⏸ Pending approval |
A project server you have not approved yet |
Inside a session, /mcp shows the same status, lets you reconnect or disable a server, and starts OAuth sign-in for remote servers. The server’s own error output goes to a log file; see where clients write MCP logs.
Timeouts and large results
Section titled “Timeouts and large results”- Startup: set
MCP_TIMEOUTin milliseconds when you start Claude Code, for exampleMCP_TIMEOUT=30000 claudefor slow servers such as JVM ones. Our log showed a 30-second connection timeout by default. - Tool calls: a per-server
"timeout"in milliseconds in the server’s entry limits each call. - Output size: Claude Code warns when a tool result exceeds 10,000 tokens and cuts it at 25,000 by default;
MAX_MCP_OUTPUT_TOKENSchanges the limit.
Windows
Section titled “Windows”We have not tested Claude Code on Windows. Claude Code’s documentation does not currently mention a special rule for npx. If a server started with npx fails on native Windows, wrap it in cmd /c, as described in Connection closed. The config generator does this for Windows.
Related
Section titled “Related”Sources
MCPDev is community documentation. It is not affiliated with the Model Context Protocol project or with the vendors of the clients it covers.