Claude Desktop MCP Config: The JSON File, With Examples

Where claude_desktop_config.json lives on macOS and Windows, the exact mcpServers format, working examples for npx, uvx, node and Python, environment variables, Windows paths, and why remote servers now go in as connectors instead.

7 min read

Claude Desktop reads its local MCP servers from one file, claude_desktop_config.json. It holds a single JSON object with one key, mcpServers; inside it, each server has a name you choose, a command to run, an args array and, optionally, an env object of environment variables. When the app starts, it launches every server in the file as a process on your computer and talks to it over standard input and output. Two things catch most people: the file only describes servers the app starts itself, so a remote server with a URL is added as a connector instead; and nothing changes until you quit Claude Desktop completely and open it again.

Where the file lives, and how to open it

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json, which is usually C:\Users\<you>\AppData\Roaming\Claude.

You do not need to find it by hand. The MCP guide to connecting local servers (opens in a new tab) opens it from the app: choose the Claude menu in your system’s menu bar, not the settings inside the chat window, then Settings…, then the Developer tab, then Edit Config. If the file does not exist yet, that button creates it.

The same Developer area is where Anthropic’s help page on local MCP servers in Claude Desktop (opens in a new tab) sends you to check each server’s connection status and view its logs. Keep it open while you work through the examples below.

The format

claude_desktop_config.json — the shape
{
  "mcpServers": {
    "server-name": {
      "command": "program-to-run",
      "args": ["first-argument", "second-argument"],
      "env": { "SOME_KEY": "some value" }
    }
  }
}
  • The key, here server-name, is the label the app shows. Stick to letters, digits, hyphens and underscores; that keeps it valid if you later copy the server into another client.
  • command is the program that starts the server: npx, uvx, uv, node, python, docker or the full path to an executable.
  • args is a list, one string per argument. ["-y", "some-package"] is right; ["-y some-package"] passes one argument with a space in it and fails.
  • env is optional. It sets environment variables for that one server and nobody else.

It is strict JSON. No comments, no trailing comma after the last server, double quotes only, and one mcpServers object with every server inside it as a sibling. Pasting a second { "mcpServers": … } block underneath the first is the most common way to break the file.

Four stdio examples

npx: a server published as a Node package

macOS
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/username/Desktop",
        "/Users/username/Downloads"
      ]
    }
  }
}

-y answers yes to npx’s install prompt, which otherwise waits for a keypress no one will ever make. The remaining arguments are the folders the reference Filesystem server may open. It runs with your own user’s permissions, so list only folders you are happy for Claude to read and change.

uvx: a server published as a Python package

The reference Git server
{
  "mcpServers": {
    "git": {
      "command": "uvx",
      "args": ["mcp-server-git", "--repository", "/Users/username/code/my-repo"]
    }
  }
}

uvx fetches the package and runs it in a throwaway environment, the Python counterpart of npx -y. The reference Git server’s README gives this form for Claude Desktop, with --repository pointing at the repository it should work in.

node: a server you built yourself

A compiled TypeScript server
{
  "mcpServers": {
    "weather": {
      "command": "node",
      "args": ["/Users/username/code/weather/build/index.js"]
    }
  }
}

Python through uv: a server you built yourself

A Python server in a uv project
{
  "mcpServers": {
    "weather": {
      "command": "uv",
      "args": ["--directory", "/Users/username/code/weather", "run", "weather.py"]
    }
  }
}

Every path is absolute. The app does not start servers from your project folder, so ./build/index.js has nothing to be relative to. The MCP guide to building a server (opens in a new tab) adds a warning worth taking at face value: you may need the full path to uv in command, which which uv on macOS or where uv on Windows prints. The same goes for node and npx if you installed them with a version manager. Building the server itself is covered in how to build an MCP server.

Environment variables and keys

A server started by Claude Desktop does not get your terminal’s environment. The protocol’s debugging guide (opens in a new tab) says stdio servers inherit only a limited, platform-dependent subset of environment variables, so anything a server needs, such as an API key, a region or a proxy, goes in its env block.

A server that needs a key
{
  "mcpServers": {
    "my-service": {
      "command": "npx",
      "args": ["-y", "@example/my-service-mcp"],
      "env": {
        "MY_SERVICE_API_KEY": "paste-the-key-here",
        "MY_SERVICE_REGION": "eu"
      }
    }
  }
}

That key now sits in plain text in your user profile. If the service offers a desktop extension, which keeps keys in the operating system’s secure storage, or a remote connector with a browser sign-in, prefer that; Claude connectors explained sets out the difference. Never commit a copy of this file anywhere.

Windows: backslashes and APPDATA

In JSON a backslash starts an escape, so C:\Users\username is not a valid path string. Double every backslash, or use forward slashes, which Windows accepts:

Windows
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "C:\\Users\\username\\Desktop",
        "C:/Users/username/Downloads"
      ]
    }
  }
}

Two more Windows notes come straight from the MCP troubleshooting guidance. If a server fails and its log mentions ${APPDATA} inside a path, add the expanded value to that server’s env, for example "APPDATA": "C:\\Users\\username\\AppData\\Roaming\\". And npx may keep failing unless npm is installed globally: if %APPDATA%\npm does not exist, npm install -g npm creates it.

Remote servers: connectors, not this file

The config file describes programs the app starts on your machine. A server that lives at a URL is added as a custom connector: in Claude, open Customize, then Connectors, choose to add a custom connector, paste the URL and sign in. The help page on custom connectors using remote MCP (opens in a new tab) says they work in Claude, Cowork and Claude Desktop on every plan, with Free limited to one, and that the connection comes from Anthropic’s cloud, so the server must be reachable over the public internet. Servers from the config file are the opposite: they use your own network, and they are not available in Cowork or on claude.ai.

If a service only offers a URL and you need it to run through your own machine, some vendors document a stdio bridge such as the community mcp-remote package, started with npx like any other entry in the file. It is third-party code running with your permissions and handling your sign-in, so apply the caution in MCP security risks before adding it.

A remote example: a task board

fenbs, a task board where AI assistants are members with roles, is a remote MCP server, so in Claude Desktop it goes in as a custom connector rather than a line in the file:

Connector URL
https://fenbs.ai/api/mcp

Claude opens fenbs in your browser; you sign in, tick what the assistant may do (read, write, comment) and approve. Nothing is pasted into JSON. Claude then holds your role on the board narrowed by those scopes, its access token lasts an hour and refreshes, every change it makes is recorded as “Claude via” you, and revoking the token under Settings ends its access without touching your own sign-in. The full walk-through is on the Claude integration page.

Restart, then check

Save the file, then quit Claude Desktop completely and reopen it. Closing the window is not enough; the app keeps running and keeps the old configuration. Once it is back, open the “+” menu in the message box, go to Connectors, then Manage connectors, and find your server by its name. Its tools are listed there.

If it is missing or shows an error, the causes are few and each leaves a trace in the logs: work through Claude Desktop MCP not working. If you also use Claude Code, the Claude Code MCP documentation (opens in a new tab) describes claude mcp add-from-claude-desktop, which copies these servers across on macOS and in WSL. Other apps use a similar mcpServers shape, with differences listed in which apps support MCP.

Related

Adding a server without editing JSON at all: MCP without coding. The three kinds of Claude connector: Claude connectors explained. What MCP is in the first place: MCP. The fenbs tools an assistant can call: MCP docs.

Questions people ask.

Where is claude_desktop_config.json?

On macOS it is in ~/Library/Application Support/Claude, and on Windows in %APPDATA%\Claude. The quickest way to open it is the Claude menu in the system menu bar, then Settings, Developer and Edit Config, which also creates the file if it does not exist.

Can I add a remote MCP server URL to claude_desktop_config.json?

The file is for local servers the app starts as processes. Remote servers are added in Claude as custom connectors, by pasting the URL under Customize and Connectors and signing in. If you must run a remote server through your own machine, a stdio bridge can do it, but it is extra code to trust.

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

Yes. Quit the app completely and open it again. Closing the window leaves it running with the old configuration.

How do I write Windows paths in the config file?

Either double every backslash, as in C:\\Users\\username\\Desktop, or use forward slashes, as in C:/Users/username/Desktop. A single backslash is an escape character in JSON and breaks the path or the whole file.

Start with one thing.

There is nothing to set up first. Write one line and you’ve started.