# MCP configuration in Claude Code and Desktop

Knowing what MCP is gets you halfway. If you want the mental model first, start with [MCP fundamentals](/guides/mcp-fundamentals). This guide is the practical half: adding a
server, choosing where its config lives, and fixing it when it does not connect.
The examples use Claude Code and Claude Desktop, the two clients most people
start with.

## How do I add an MCP server in Claude Code?

The fastest way is the `claude mcp` command. Here is a local (stdio) server and a
remote (HTTP) one:

```bash
# A local server launched as a subprocess
claude mcp add --transport stdio filesystem -- npx -y @modelcontextprotocol/server-filesystem ~/projects

# A remote server with an auth header
claude mcp add --transport http github https://api.githubcopilot.com/mcp/ \
  --header "Authorization: Bearer YOUR_GITHUB_TOKEN"
```

For stdio servers, everything after `--` is the command Claude runs as a subprocess untouched.
Pass secrets with repeatable `--env KEY=value` flags rather than baking them into
the command. For a step-by-step walkthrough, see [install your first MCP server](/guides/install-your-first-mcp-server).

## Where does MCP config live, and which scope wins?

Claude Code has three scopes. Choosing the right one is most of the skill:

- **local** (the default) · just you, just this project. Stored in your
  `~/.claude.json` under the project path.
- **project** · shared with the team. Stored in a `.mcp.json` file at the
  project root, which you commit to git.
- **user** · just you, but across all your projects. Also in `~/.claude.json`.

When the same server name exists in more than one scope, the most specific wins:
local, then project, then user. Entries are replaced whole, not merged.A common time-sink is editing a server in one scope while a same-named entry in a more specific scope keeps overriding it, so your changes appear to do nothing. Run `claude mcp list` to see which scope resolved, then edit that one or rename to avoid the clash.

A committed `.mcp.json` looks like this:

```json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "${HOME}/projects"]
    },
    "stripe": {
      "type": "http",
      "url": "https://mcp.stripe.com"
    }
  }
}
```

You can reference environment variables with `${VAR}` or `${VAR:-default}` in the
command, args, url, env, and headers. A missing variable with no default fails
the parse, which is a feature: it stops a half-configured server from loading.
Because project scope lives in a committed `.mcp.json`, pasting a raw API token or bearer header straight into that file leaks it to everyone with repo access and into git history forever. Keep the secret in a `${VAR}` reference and let each person supply the value through their own environment, so the committed file only ever names the variable.

## Does Claude Desktop share config with Claude Code?

Claude Desktop reads its own file, and Claude Code does not look at it:

- macOS · `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows · `%APPDATA%\Claude\claude_desktop_config.json`

It uses the same `{ "mcpServers": { ... } }` shape and reloads on app launch. To
pull existing Desktop servers into Claude Code, run
`claude mcp add-from-claude-desktop`.

## How do I verify and debug an MCP server?

When a server does not show up, work through these. For a deeper diagnostic walkthrough, see [fix an MCP server that will not connect](/guides/fix-an-mcp-server-that-wont-connect).

```bash
claude mcp list          # every server and its status
claude mcp get filesystem  # detail for one, including pending approval
```

Inside a session, `/mcp` shows live status and is where you authenticate remote
servers over OAuth. For a server you are developing, the MCP Inspector gives you
a UI to poke at it directly:

```bash
npx @modelcontextprotocol/inspector
```

## Why won't my MCP server connect?

Most broken servers are one of these:

- **PATH** · the subprocess cannot find `node`, `npx`, or `python`. Use absolute
  paths or make sure the binary is on PATH for the launching shell.
- **Missing env** · a `${VAR}` with no value and no default. Set it, or give a
  default.
- **Stale npx cache or version drift** · pin a version, or clear the cache.
- **Pending approval** · project-scoped servers wait for you to approve them once
  before they load. Approve them in-session or with `claude mcp get`.
- **Unauthenticated remote** · the server needs OAuth you have not done yet. Run
  `/mcp` and sign in.

Once a server connects cleanly, its tools appear to the model. Before you
hand an MCP server real access, decide which of its tools Claude may call: see
[MCP security: what to allow and what to block](/guides/mcp-security-basics). The next
guide [builds one of these servers from scratch](/guides/build-an-mcp-server).
