claude-code configuration beginner 5 minutes

Your MCP Server Isn't Broken — Your Config Is in the Wrong File

Two config files that look the same. Two silent failures that stack. Zero error messages. This is the kind of bug where you question your own sanity before you question the tooling — and the tooling was the problem the whole time.

Dates are simple. Config files are simple. Two config files that do almost the same thing but silently diverge on one critical behavior — that’s where you lose an afternoon.

Claude Code has two places you can define MCP servers. One of them doesn’t actually work the way you’d expect. There’s no error, no warning, no indication that anything is wrong. The server starts, the API calls fail, and you start debugging the wrong thing.

Here’s the three-attempt debugging journey that led to the fix — and the two rules that would have saved the trip.

The Problem

Claude Code supports MCP (Model Context Protocol) servers — external tools that extend what Claude can do. You configure them with a command, arguments, and environment variables (typically API keys). The config looks identical whether you put it in settings.json or .mcp.json. But the behavior isn’t identical at all.

settings.json silently ignores env blocks for MCP servers. The process spawns. It runs. But it never receives the environment variables you defined. Every API call that depends on those secrets fails — and the error comes from the downstream service, not from Claude Code. You’ll see auth errors, 401s, or cryptic API failures that point you toward the MCP server itself, not the config.

The Debugging Journey

Attempt 1 — settings.json (env silently ignored)

The natural place to put MCP config. It’s where Claude Code settings live. It even has an mcpServers key. So you add your server:

// ~/.claude/settings.json
{
  "mcpServers": {
    "stitch": {
      "command": "npx",
      "args": ["@_davideast/stitch-mcp", "proxy"],
      "env": {
        "STITCH_API_KEY": "your-key-here"
      }
    }
  }
}

Server starts. Every API call fails. No indication that STITCH_API_KEY was never passed to the process.

Attempt 2 — .mcp.json in the wrong location

You learn that .mcp.json is the right file for MCP servers. You create it — but in ~/.claude/.mcp.json, next to settings.json. Seems logical.

// ~/.claude/.mcp.json — WRONG PLACE for project-scoped servers
{
  "mcpServers": {
    "stitch": {
      "type": "stdio",
      "command": "npx",
      "args": ["@_davideast/stitch-mcp", "proxy"],
      "env": {
        "STITCH_API_KEY": "your-key-here"
      }
    }
  }
}

Claude Code doesn’t see it. No “new server found” prompt. No error. Nothing.

Attempt 3 — .mcp.json at the project root (works)

Move the file to the root of your project — the directory where you launch Claude Code:

// /path/to/your/project/.mcp.json — RIGHT PLACE
{
  "mcpServers": {
    "stitch": {
      "type": "stdio",
      "command": "npx",
      "args": ["@_davideast/stitch-mcp", "proxy"],
      "env": {
        "STITCH_API_KEY": "your-key-here"
      }
    }
  }
}

Next session start: “New MCP server found in .mcp.json: stitch” — the confirmation prompt that means it’s actually working.

The Rules

Two things to know. That’s it.

1. MCP env vars only work in .mcp.json, not settings.json. The settings.json file is for Claude Code preferences and permissions. MCP server definitions belong in .mcp.json. Both files accept an mcpServers key — only one of them passes env vars to the spawned process.

2. Project-scoped .mcp.json must be at the repo root. The directory where you launch Claude Code. Not in a subdirectory, not in ~/.claude/ (that’s for user-scoped servers that apply everywhere). Claude Code scans the working directory root on startup. If the file isn’t there, it’s invisible.

The Confirmation Signal

When Claude Code finds a new MCP server, it shows:

New MCP server found in .mcp.json: {name}

If you don’t see this prompt on startup after adding a new server, the file isn’t being read. Check the location.

Bonus: Cached Failure State

One more gotcha. If an MCP server fails to connect on first attempt, Claude Code may cache that failure. Subsequent /mcp reconnect attempts can fail instantly without re-spawning the process — even after you’ve fixed the underlying issue.

The fix: rename the server key in .mcp.json (e.g., stitch to google-stitch). Claude Code treats it as a new server and makes a fresh connection attempt. Restart the session after renaming.

Pro Tips

  • Use the full path to npx if you’re on nvm (e.g., /Users/you/.nvm/versions/node/v24.14.0/bin/npx). Claude Code’s shell may not inherit your nvm setup.
  • Use variable expansion to keep secrets out of config: "STITCH_API_KEY": "${STITCH_API_KEY}" references your shell environment.
  • Test the MCP server manually first — run the command with the env var exported and confirm it works. Then narrow the problem to config placement.
  • Two valid .mcp.json scopes exist: user-scoped (~/.claude/.mcp.json) applies to all projects, project-scoped (.mcp.json at repo root) applies to that project only.

FAQ

Why does my MCP server start but fail every API call in Claude Code?

You likely have the env vars in settings.json instead of .mcp.json. Claude Code silently ignores env blocks in settings.json for MCP servers — the process starts but never receives its secrets. Move the entire MCP server config to .mcp.json at your project root.

Where does .mcp.json need to be for Claude Code to find it?

At the root of the directory where you launch Claude Code. Project-scoped .mcp.json files must be at the repo root — not in a subdirectory, not in ~/.claude/. When Claude Code discovers it, you'll see 'New MCP server found in .mcp.json' on startup.

What's the difference between settings.json and .mcp.json for MCP servers?

settings.json is for Claude Code settings (preferences, permissions). .mcp.json is for MCP server definitions. Both support an mcpServers key, but only .mcp.json correctly passes env vars to the spawned server process. Two valid .mcp.json scopes exist: user (~/.claude/.mcp.json) and project (.mcp.json at repo root).

Can I use variable expansion in .mcp.json instead of hardcoding API keys?

Yes. Use ${STITCH_API_KEY} syntax to reference shell environment variables instead of hardcoding secrets. This keeps keys out of committed config files.