MCP
Ren Okabe8 min read4 views

How to Add an MCP Server to Claude Desktop (2026)

The exact claude_desktop_config.json setup to connect a local MCP server to Claude Desktop, verify it with the MCP Inspector, and fix a server that will not show up.

Network cables plugged into a server, representing connecting an MCP server to Claude Desktop
Network cables plugged into a server, representing connecting an MCP server to Claude Desktop
On this page

Quick answer (2026)

To add an MCP server to Claude Desktop, open Settings > Developer > Edit Config, add your server under the mcpServers key in claude_desktop_config.json, save, and fully restart the app. Each entry needs a command and an args array (plus an optional env for secrets). After restart, the server shows up under the connectors menu in the message box. This guide covers the exact config for both an off-the-shelf npx server and a custom local server, how to verify the wiring with the MCP Inspector, and a troubleshooting ladder for when your server does not show up. As of July 2026 this is stdio transport for local servers; remote servers use a different setup covered at the end.

Connecting is not building

There are two separate jobs, and mixing them up is the most common reason people get stuck. Building a server means writing the code that exposes tools over the Model Context Protocol. Connecting a server means telling a client, Claude Desktop here, how to launch that code and talk to it. This tutorial is only the second job.

If you have not written a server yet, start with a working one. You can point Claude at any package from the reference server collection on GitHub, or use the one you already built as a Python MCP server. MCP is an open standard, so the same server also connects to other clients like Cursor and the OpenAI Agents SDK; the config file differs per client, but the server does not.

Prerequisites

  • Claude Desktop, updated to the latest version (Claude menu > Check for Updates). The mcpServers config only exists in the desktop app, not the web app.
  • The runtime your server needs on your PATH. Node servers need node and npx; Python servers need python or uv. Verify before you touch the config:
bash
node --version
npx --version
python --version   # or: uv --version

If a command is not found, install it and reopen your terminal before continuing. A server whose runtime is missing will fail silently at launch, and the failure looks identical to a bad config.

Open the config file

Click the Claude menu in your OS menu bar (not the settings gear inside the chat window), choose Settings, open the Developer tab, and click Edit Config. This creates the file if it does not exist and opens it in your default editor.

The file lives at:

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

You can edit it by hand at that path too. It is plain JSON.

Add your server

The whole file is one object with a single mcpServers key. Each server is a named entry. Here is the canonical off-the-shelf case, the filesystem server run through npx:

json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/you/Projects"
      ]
    }
  }
}

On Windows the paths use escaped backslashes, for example "C:\\Users\\you\\Projects".

Wiring a custom local server

The example everyone copies is the npx one, but most real work is connecting a server you wrote. The rule is simple: command plus args must be the exact terminal invocation that starts your server, using absolute paths. Claude Desktop does not run inside your project directory and does not read your shell profile, so relative paths and PATH shortcuts that work in your terminal will not work here.

A Python server launched with uv:

json
{
  "mcpServers": {
    "my-tools": {
      "command": "uv",
      "args": [
        "--directory",
        "/Users/you/code/my-mcp-server",
        "run",
        "server.py"
      ],
      "env": {
        "API_KEY": "sk-your-secret-here"
      }
    }
  }
}

Three things to notice. --directory pins the working directory so the server can find its own files. The env block is where secrets go; Claude Desktop passes it to the subprocess, so your server reads them with os.environ and you keep them out of args. And if uv itself is not found, replace "uv" with its absolute path (which uv on macOS or Linux, where uv on Windows) because, again, Claude does not inherit your PATH.

You can list several servers side by side; each gets its own named key inside mcpServers.

Restart and verify it appears

Config changes are read at launch only. Fully quit Claude Desktop, Cmd+Q on macOS or right-click the tray icon and Quit on Windows, then reopen it. A window close is not enough; the process must exit.

After restart, click the connectors control (the "Add files, connectors, and more" indicator) at the bottom-left of the message box. Your server name should be listed, and expanding it shows the tools it exposes. If it is there with its tools, the wiring is correct and you can move on.

Verify with the MCP Inspector

Before you blame Claude for a server that misbehaves, confirm the server itself is healthy in isolation. The MCP Inspector is the official debugging client. It launches your server with the same command and args Claude uses and gives you a UI to list and call tools directly:

bash
npx @modelcontextprotocol/inspector uv --directory /Users/you/code/my-mcp-server run server.py

Open the local URL it prints, click Connect, then List Tools, then call a tool with sample input. If the Inspector can see and run your tools, the server is fine and any remaining problem is in the Claude config. If the Inspector cannot connect, the problem is in the server or the command, and Claude was never going to work either. This one check removes most of the guesswork.

Troubleshooting: my server does not show up

Work down this ladder in order. Most failures are one of the first three.

  1. Validate the JSON. A single trailing comma or unquoted key makes the whole file invalid and Claude silently loads zero servers. Paste the file into any JSON validator, or run python -m json.tool claude_desktop_config.json, which prints the first syntax error.
  2. Use absolute paths everywhere. Both the command (if the binary is not globally installed) and any file-path args must be absolute. Relative paths resolve against an unknown directory and fail.
  3. Confirm you fully restarted. Reopening a closed window does not reload the config. Quit the process and relaunch.
  4. Run the exact command by hand. Copy the command and args into your terminal and run them. Any error you see, a missing module, a bad path, a permissions issue, is the same error Claude is hitting.
  5. Read the logs. Claude writes MCP logs to ~/Library/Logs/Claude/ on macOS and %APPDATA%\Claude\logs\ on Windows. mcp.log covers connection attempts; mcp-server-NAME.log holds your server's stderr. Tail them while you restart:
bash
tail -n 20 -f ~/Library/Logs/Claude/mcp*.log
  1. Windows ${APPDATA} / ENOENT. If the log shows an unresolved ${APPDATA} in a path, add an explicit env block with the expanded value, and make sure npm is installed globally so %APPDATA%\npm exists:
json
"env": { "APPDATA": "C:\\Users\\you\\AppData\\Roaming\\" }

Tools appear but fail when called

If the server connects but every tool call errors, the wiring is right and the bug is in the server: check its own logs, confirm it builds and runs clean under the Inspector, and restart Claude once more after fixing it.

Verify your setup (break it on purpose)

A tutorial that only shows the happy path teaches you nothing about failure. Run these three checks so you can recognize each failure mode later:

  • Break the JSON. Add a trailing comma after your server entry, restart, and confirm the server disappears entirely. That is what an invalid config looks like: not an error dialog, just nothing.
  • Break the path. Point --directory at a folder that does not exist, restart, and read mcp-server-NAME.log to see the launch failure. Now you know where the real errors live.
  • Break the runtime. Rename uv to something Claude cannot find (or use a bogus command), restart, and confirm the server fails to appear. This is the "runtime not on PATH" case, the single most common silent failure.

Fix all three back to the working config and you have a server you can trust and debug.

Connecting a remote server

Everything above is stdio transport: Claude launches a local process and talks to it over standard input and output. Servers that run in the cloud use HTTP instead, and the client-side setup is different. If your server is remote, follow the pattern in connect a remote server over Streamable HTTP rather than the command/args shape here.

Limitations and open questions

  • The config is per client. This file only configures Claude Desktop. Cursor, VS Code, and the OpenAI Agents SDK each read their own config; the server is portable, the wiring is not.
  • No hot reload. Every config change needs a full restart. There is no way to add a server to a running Claude session as of July 2026.
  • stdio is single-machine. Local command/args servers only run tools on the same computer as Claude Desktop. Anything shared across a team or triggered from the cloud belongs on a remote server.
  • Secrets sit in plaintext. The env block stores API keys unencrypted in a JSON file in your home directory. Treat it like a dotfile: never commit it, and prefer scoped keys you can revoke.

If you followed the official steps and still cannot get a server to appear, compare your config field by field against the official MCP user quickstart; a single mismatched key is usually the culprit.

R

Written by

Ren Okabe

Ren Okabe builds and breaks agent systems, then writes down the runnable version. Principal-engineer voice, code first.

Frequently asked questions

Where is the claude_desktop_config.json file located?

On macOS it lives at ~/Library/Application Support/Claude/claude_desktop_config.json, and on Windows at %APPDATA%\Claude\claude_desktop_config.json. The fastest way to open it is Settings > Developer > Edit Config inside Claude Desktop, which creates the file if it does not exist. The mcpServers configuration only exists in the desktop app, not the Claude web app.

Why does my MCP server not show up in Claude Desktop?

The three most common causes, in order, are invalid JSON in the config file (a trailing comma silently disables every server), relative instead of absolute paths in command or args, and not fully quitting and restarting the app after editing. Validate the file with python -m json.tool, use absolute paths everywhere, quit the process completely, then check ~/Library/Logs/Claude/mcp*.log for the launch error.

Do I need to restart Claude Desktop after editing the config?

Yes. Claude Desktop reads claude_desktop_config.json only at launch, so any change requires a full restart. Closing the window is not enough; you must quit the process (Cmd+Q on macOS, Quit from the tray on Windows) and reopen it before the new or edited server is loaded.

How do I test an MCP server before connecting it to Claude?

Use the MCP Inspector, the official debugging client. Run npx @modelcontextprotocol/inspector followed by the same command and args you would put in the config, open the URL it prints, and list and call the tools directly. If the Inspector can run your tools, the server is healthy and any remaining problem is in the Claude config; if it cannot connect, the bug is in the server.

What is the difference between a local and a remote MCP server in Claude Desktop?

Local servers use stdio transport: Claude launches a process on your machine via the command and args fields and talks to it over standard input and output. Remote servers run in the cloud and communicate over HTTP with a different client-side setup. The command/args config shown here is only for local stdio servers.

AI agents

Remote MCP Server Tutorial (2026): Serve Tools over Streamable HTTP

A runnable 2026 tutorial for turning a local MCP server into a remote one over Streamable HTTP. Serve tools with FastMCP, test the endpoint with curl and MCP Inspector, validate the Origin header, add a bearer token, then connect Claude. Covers the Mcp-Session-Id requirement and the DNS-rebinding gotcha the docs warn about but most walkthroughs skip.

9 min read43