Skip to content

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.

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.

TerminalAdd the server to the project
Terminal window
claude mcp add --scope project hello-ts -- node /absolute/path/to/hello-server/src/server.ts

ExpectedAdded 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:

.mcp.json
{
"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:

Terminal window
claude mcp add -e 'API_KEY=${API_KEY}' --scope project my-server -- npx -y my-mcp-server

The 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.

Terminal window
claude mcp add --scope project --transport http my-remote https://mcp.example.com/mcp \
--header 'Authorization: Bearer ${MCP_TOKEN}'
.mcp.json
{
"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.

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.

Terminal window
claude mcp list # every server with a health status
claude mcp get hello-ts # one server, with the failure reason if any

For 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.

  • Startup: set MCP_TIMEOUT in milliseconds when you start Claude Code, for example MCP_TIMEOUT=30000 claude for 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_TOKENS changes the limit.

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.

Sources

MCPDev is community documentation. It is not affiliated with the Model Context Protocol project or with the vendors of the clients it covers.