How to Add an MCP Server to Claude: A Step-by-Step Setup Guide

If you have Claude Desktop, Claude Code, Cursor, or another MCP client open and want it to actually do things — read your files, query a database, hit an internal API — you need to connect a server. This guide covers how to add an MCP server to Claude step by step: where the config file lives, the exact JSON shape the client expects, how to restart and verify, and the small mistakes that make a perfectly good server silently fail to appear. Everything here applies to any MCP client; Claude Desktop is just the most common starting point.

How to add an MCP server to Claude: what you're actually doing

The Model Context Protocol (MCP) is an open standard, introduced by Anthropic in late 2024, that lets an AI assistant talk to external tools over a consistent interface. Your client — Claude Desktop, Claude Code, Cursor, Windsurf, Continue, VS Code, and others — is the host. Each thing you connect is an MCP server, and a server exposes some mix of tools (actions the model can call), resources (data it can read), and prompts. "Adding a server" simply means writing a small block of JSON that tells the client how to launch or reach it. Once connected, the tool descriptions are read by the model, not by you, and the model decides when to call them.

There are two transports you'll encounter. A stdio server runs as a local subprocess — the client starts a command (usually npx, node, uvx, or python) and talks to it over standard input/output. A Streamable HTTP server is remote: the client connects to a URL, often behind OAuth sign-in. The config shape differs slightly between the two, and knowing which one you have is the first thing to get straight.

Step 1: Find the config file

Claude Desktop stores its server list in a single JSON file called claude_desktop_config.json. The easiest way to open it is from inside the app: go to Settings → Developer → Edit Config, which reveals (and creates, if missing) the file in your editor. If you'd rather find it directly, it lives here:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Other clients keep their own file in their own place — Cursor uses ~/.cursor/mcp.json, and Claude Code reads a project-scoped .mcp.json (or its own user config). The shape of the JSON is the same everywhere, so once you can write one, you can write them all. If the file is brand new, it may be completely empty or just contain {}. That's fine — you're about to fill it in.

Step 2: Understand the mcpServers JSON shape

Every client keys its servers under a top-level mcpServers object. Each entry is named by you (that label is just a handle) and describes how to start or reach the server.

For a stdio server, you provide three things:

  • command — the executable to run (e.g. npx, node, uvx).
  • args — an array of arguments passed to that command, including the package name and any paths or flags.
  • env — an optional object of environment variables (API keys, tokens, config) the server needs.

For an HTTP server, you provide a url instead of a command. Here is a complete, real config with one of each:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/you/Documents",
        "/Users/you/Projects"
      ]
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token_here"
      }
    },
    "my-remote-api": {
      "url": "https://mcp.example.com/mcp"
    }
  }
}

A few things to notice. The filesystem server takes the directories it's allowed to touch as plain arguments — everything after the package name in args is passed straight through to the server. The github server needs a token, so it goes in env. The remote server needs only a url; if it requires authentication, the client will prompt you to sign in through the browser on first use. Keep the JSON valid: a trailing comma or a missing brace will make the whole file fail to load, and most clients won't tell you why.

Step 3: Restart the client

MCP clients read the config once at launch. After you save the file, you must fully restart the app — and on macOS, "close the window" is not enough; quit it entirely (Cmd+Q, or right-click the dock/tray icon and choose Quit) so the background process exits, then reopen. Claude Code picks up .mcp.json when you start a new session in that project. If you edited the config while the app was running and nothing changed, an incomplete restart is the single most common reason.

Step 4: Verify the tools appear

In Claude Desktop, once the app reopens you'll see an indicator (a small tools/plug icon) near the message input; clicking it lists every connected server and the tools it exposes. If your server is there with its tools, you're done — ask Claude to use one and watch it call the tool. In Claude Code, verify from the terminal:

claude mcp list

That prints each configured server and whether it connected successfully. A server that loaded but reports zero tools usually started fine but hit a runtime error (a bad token, a missing path) — check the client's logs. On macOS, Claude Desktop writes per-server logs to ~/Library/Logs/Claude/, and mcp-server-<name>.log is the first place to look when something connects but misbehaves.

Step 5: The faster path in Claude Code

If you're using Claude Code, you rarely need to hand-edit JSON at all. The CLI writes the config for you:

# stdio server
claude mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem ~/Documents

# with an environment variable
claude mcp add github -e GITHUB_PERSONAL_ACCESS_TOKEN=ghp_xxx -- npx -y @modelcontextprotocol/server-github

# remote HTTP server
claude mcp add --transport http my-remote-api https://mcp.example.com/mcp

The -- separates Claude Code's own flags from the command that launches the server, which matters when the server takes flags of its own. Everything after -- becomes the command plus args you saw earlier.

Common gotchas when the server won't show up

Ninety percent of failed setups come down to one of these:

  • Paths must be absolute. Config files don't reliably expand ~ or relative paths. Write out the full path (/Users/you/Documents, not ~/Documents) in both args and any path-bearing env var.
  • The client can't find npx or node. GUI apps launched from the dock don't inherit your shell's PATH, so a version manager like nvm can hide Node from Claude Desktop. If a stdio server refuses to start, set command to the absolute binary path — find it with which node / which npx in your terminal and paste the result.
  • Invalid JSON. One trailing comma silently breaks the entire file and every server in it. Paste it into a JSON validator if a server that "should" work never appears.
  • Env vars in the wrong place. Secrets go in the env object, not in args. Putting a token in args both fails to configure the server and leaks the value into process listings.
  • You didn't fully quit. Covered above, but it's worth repeating because it's the most frequent one.

Before you paste that command: check the server is safe

Here's the part most setup guides skip. When you add a stdio server, you are handing an unaudited third-party process the exact scopes in your config — your files, your tokens, your network — and its tool descriptions are read by the model, where a hidden instruction can quietly redirect what Claude does. That's the lethal trifecta: private data, untrusted content, and an exfiltration path, all in one agent. So before you commit a random npx command from a README into claude_desktop_config.json, scan it first. It's one command, free, and takes seconds:

npx mcptrustchecker scan @some/mcp-server --online

MCP Trust Checker is a local-first, open-source (MIT) scanner. With --online it fetches and reads the real published npm or PyPI source in memory — it never installs or executes the package — and returns a deterministic A–F trust grade covering prompt injection, hidden Unicode payloads, install-script and supply-chain risk, and cross-tool toxic flows. Run it with no arguments and it audits every server already in your installed clients' configs. If you want the full walkthrough, see how to scan an MCP server. Adding a server takes thirty seconds; knowing it's safe takes about the same.

Wrapping up

That's the whole loop for how to add an MCP server to Claude: find claude_desktop_config.json (or run claude mcp add), write the mcpServers entry with command/args/env for stdio or url for HTTP, fully quit and reopen the client, then verify the tools show up. Once you've done it once, connecting the next server — a database, a ticketing system, your own internal API — is the same five steps. The one habit worth building from day one: treat every new server as untrusted code with access to your data, and vet it before you connect it. Wire up the tools, keep the checker in your setup flow, and let Claude do the rest.

Frequently asked questions

Where is claude_desktop_config.json located?

On macOS it's at ~/Library/Application Support/Claude/claude_desktop_config.json, and on Windows at %APPDATA%\Claude\claude_desktop_config.json. The easiest way to open (or create) it is from inside Claude Desktop: Settings → Developer → Edit Config.

Why doesn't my MCP server show up after editing the config?

The most common causes are: you didn't fully quit and reopen the client (closing the window isn't enough on macOS — use Cmd+Q), the JSON is invalid (a trailing comma breaks the whole file), you used a relative path or ~ instead of an absolute path, or the app can't find npx/node because GUI apps don't inherit your shell's PATH. Set command to the absolute binary path from `which node` if needed.

What's the difference between a stdio and an HTTP MCP server in the config?

A stdio server runs locally as a subprocess, so you give it command, args, and optional env. An HTTP (Streamable HTTP) server is remote, so you give it a url instead — and the client will prompt you to sign in via the browser if it needs authentication.

Can I add an MCP server without editing JSON by hand?

Yes, in Claude Code. Use the CLI: `claude mcp add <name> -- npx -y <package>` for a stdio server, add `-e KEY=value` for environment variables, or `--transport http <name> <url>` for a remote server. It writes the config for you, and `claude mcp list` verifies the connection.

Is it safe to add any MCP server I find online?

Not blindly. A stdio server is third-party code that gets the file, token, and network access you grant it, and its tool descriptions are read by the model — so a poisoned description can redirect the agent. Before connecting one, scan it with a tool like MCP Trust Checker (`npx mcptrustchecker scan <package> --online`), which reads the real published source without installing it and flags prompt injection, hidden payloads, and supply-chain risk.

Scan your MCP server now

MCP Trust Checker is free, open-source and runs entirely on your machine. Get an A–F Trust Score for any MCP server in seconds.

npx mcptrustchecker

Get started → Or use the free API