·

Configuring MCP In Claude Code Cli

Step-by-step setup of MCP servers in Claude Code CLI, so your AI agent can reach external tools and data from day one.

Claude Code's CLI is, in my experience running it across a dozen production repos, the most predictable of the four tools when it comes to MCP configuration. It has a first-class claude mcp subcommand, a clear scoping model (user, project, local), and settings files that are plain JSON rather than some bespoke format you have to reverse-engineer. This topic walks through the full setup — from install to a working, verified connection — the way I'd walk a new hire through it on day one.

Prerequisites: Installing Claude Code CLI and Preparing Your Environment

Before touching MCP, get the base CLI installed and authenticated. Claude Code ships as an npm package and requires Node.js 18 or newer (Node 20 LTS is what I run in CI to avoid surprises with native module resolution).

node --version

npm install -g @anthropic-ai/claude-code
claude --version

Log in once, interactively, so the CLI has a valid session before you start wiring up servers:

claude

Two things matter before you add any MCP server:

  1. Know your working directory. Claude Code resolves project-scoped MCP config relative to the directory you launch claude from — usually your repo root. If you run claude from a subfolder, project-scoped servers defined at the repo root won't be picked up unless you're in that exact directory tree Claude Code recognizes as the project root (it walks up looking for a .git folder).
  2. Have your MCP server's run command ready. For a local stdio server this is typically an npx or uvx invocation; for a remote server it's a URL plus auth header. Test that command standalone first — e.g., run npx -y @modelcontextprotocol/server-filesystem /path directly in a terminal — before wiring it into Claude Code. Debugging a broken server binary through the MCP layer is much harder than debugging it directly.
npx -y @modelcontextprotocol/server-filesystem ~/projects

Tips
- Pin your Node version with nvm or .nvmrc — MCP server child processes inherit whatever Node is on PATH, and a stale global Node causes cryptic ENOENT errors that look like MCP bugs but aren't.
- Run claude doctor after install; it flags missing dependencies (like uv for Python-based MCP servers) before you waste time debugging a "server failed to start" error.


Adding an MCP Server with the claude mcp add Command

The claude mcp add command is the fastest path and the one I default to. Syntax:

claude mcp add <name> [--scope local|project|user] [--transport stdio|sse|http] -- <command> [args...]

For a local stdio server (the most common case — most reference MCP servers run this way):

claude mcp add filesystem --scope project -- npx -y @modelcontextprotocol/server-filesystem /Users/me/projects

For a remote HTTP/SSE server, such as a hosted Sentry or Linear MCP endpoint:

claude mcp add sentry --transport sse --scope user \
  https://mcp.sentry.dev/sse

If the remote server needs an auth header, pass it with --header:

claude mcp add linear --transport http --scope user \
  --header "Authorization: Bearer ${LINEAR_MCP_TOKEN}" \
  https://mcp.linear.app/http

Scope matters and this is where I've seen the most confusion on teams:

Scope Stored in Shared with team? Use for
local ~/.claude.json under the project path No Personal experiments, secrets you don't want committed
project .claude/settings.json (or .mcp.json at repo root) Yes, via git Team-standard servers everyone needs (Figma, internal docs)
user ~/.claude/settings.json No, but follows you across projects Personal tools you use everywhere (a personal Notion, personal GitHub PAT-based server)

Check what's registered at any time:

claude mcp list
filesystem   npx -y @modelcontextprotocol/server-filesystem /Users/me/projects   ✓ connected
sentry       https://mcp.sentry.dev/sse (sse)                                     ✓ connected
linear       https://mcp.linear.app/http (http)                                   ✗ failed

Remove a server you no longer need:

claude mcp remove linear

Tips
- Default to project scope for anything the whole team should have — it turns MCP setup into a git pull instead of a Slack thread of "which command do I run again?"
- Never bake a secret token directly into a project-scope command string that gets committed. Use --header with an env var reference (${VAR}) or keep the server at local/user scope.


Configuring MCP Servers Manually in .claude/settings.json

claude mcp add is really just a CLI wrapper that edits JSON files for you. Editing them directly is faster once you know the schema, and it's the only realistic way to configure a dozen servers at once or version them cleanly in a repo.

Project-scoped config lives at .claude/settings.json (or the older/root-level .mcp.json, which Claude Code also reads for backwards compatibility with team-shared configs):

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
    },
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": {
        "DATABASE_URL": "${DATABASE_URL}"
      }
    },
    "sentry": {
      "type": "sse",
      "url": "https://mcp.sentry.dev/sse"
    },
    "linear": {
      "type": "http",
      "url": "https://mcp.linear.app/http",
      "headers": {
        "Authorization": "Bearer ${LINEAR_MCP_TOKEN}"
      }
    }
  }
}

User-scoped config at ~/.claude/settings.json uses the identical mcpServers shape — Claude Code merges project and user config at startup, with project-scope entries winning on name collisions.

A few schema details that trip people up:

  • command + args is for stdio transport — no type field needed; it's inferred.
  • type: "sse" or type: "http" plus url is for remote transports.
  • env values support ${VAR} interpolation from your shell environment — Claude Code does not load a .env file automatically, so export the variable in your shell profile or prefix the launch command: DATABASE_URL=postgres://... claude.
  • Claude Code validates this JSON at startup; a syntax error silently disables MCP servers rather than crashing the whole CLI, so always run claude mcp list after a manual edit to confirm it parsed.
cat .claude/settings.json | python3 -m json.tool > /dev/null && echo "valid JSON"

Tips
- Commit .claude/settings.json to the repo for team-shared servers, but add a .claude/settings.local.json (gitignored by default) for anything personal — Claude Code merges both automatically.
- Keep one server per logical concern rather than one giant server exposing everything — it makes claude mcp list output and permission prompts much easier to reason about.


Testing and Verifying Your MCP Connection in Claude Code CLI

Once a server is registered, verify it end-to-end rather than trusting claude mcp list's green checkmark alone — that check only confirms the transport connected, not that the tools actually work.

Inside an interactive session, ask Claude to enumerate available tools:

> What MCP tools do you currently have access to?

Or check directly with the slash command:

/mcp

This opens an interactive panel showing each server's connection status, the tools it exposes, and any auth state (useful for OAuth-based remote servers where the token might have expired).

For a stdio server, if it fails to connect, run it manually with the exact same command Claude Code uses and read stderr:

npx -y @modelcontextprotocol/server-postgres

Nine times out of ten a "failed to connect" status traces back to one of:

  • A missing environment variable that only exists in your interactive shell, not in the environment Claude Code's child process inherits (this bites people using direnv or shell-specific .zshrc exports).
  • A version mismatch — some npm-based MCP servers pin exact protocol versions; running npx -y package@latest versus a pinned version can silently change behavior.
  • A remote server behind SSO/OAuth where the browser-based auth flow needs to be re-triggered via /mcp → select server → "Reauthenticate".

For a deeper trace, launch Claude Code with debug logging:

claude --mcp-debug

This prints the raw JSON-RPC handshake between Claude Code and each MCP server to stderr, which is the ground truth when a tool call silently returns nothing.

Tips
- Always test a newly added server with a trivial, side-effect-free tool call first (e.g., a list or read operation) before trusting it with anything that writes or deletes.
- If /mcp shows a server as connected but Claude never calls its tools, check that the tool's description in the server isn't vague — Claude picks tools based on how well the description matches the task, and generic descriptions get ignored in favor of built-in tools.


Tips

Tips
- Treat .claude/settings.json as infrastructure-as-code for your AI tooling — review changes to it in PRs the same way you'd review a Dockerfile change.
- Run claude mcp list right after pulling teammates' changes; a newly added project-scoped server won't connect until its underlying binary or credentials exist locally too.
- When a server needs secrets, prefer local/user scope over hardcoding, and document the required env vars in your repo's README so onboarding doesn't turn into a scavenger hunt.