PlugWiki

mcp.json: How to Configure MCP Servers in Any Client

mcp.json is the file where an AI client lists its MCP servers: a name, then a command to launch or a URL to connect to.

Most clients read a top-level mcpServers object. Each key is the server name. A local server gives command, args and optional env; the client launches it and talks over stdio. A remote server gives a URL and optional headers.

The shape is the same everywhere, but four details change by client: the file path, the wrapper key (VS Code uses servers), the remote URL field (url, httpUrl in Gemini CLI, serverUrl in Antigravity) and whether a remote entry needs "type": "http" (Claude Code does). Get those four right and a config copied from one client works in another.

Good for

  • Anyone pasting an MCP server config from a README into Claude, Cursor, VS Code or Gemini CLI
  • Teams sharing one server setup through a committed project file
  • Developers checking why a server does not load

Write an mcp.json that loads

  1. 1

    Find your client's file

    • Claude Code: .mcp.json in the project root (shared), or ~/.claude.json (local and user scope)
    • Claude Desktop: claude_desktop_config.json in ~/Library/Application Support/Claude/ (macOS) or %APPDATA%\Claude\ (Windows)
    • Cursor: .cursor/mcp.json in the project, or ~/.cursor/mcp.json for every project
    • VS Code: .vscode/mcp.json, with servers as the wrapper key
    • Gemini CLI: ~/.gemini/settings.json or .gemini/settings.json, key mcpServers
    • Antigravity: ~/.gemini/config/mcp_config.json, or .agents/mcp_config.json in a workspace
  2. 2

    Add a local server

    Inside mcpServers, add a key with the server name and give it command (the executable, such as npx, uvx, node or python), args (an array, one item per argument) and env for API keys. See the first file in the Code section.

    Use absolute paths for scripts: the client starts the server from its own working directory, not your shell's.

  3. 3

    Add a remote server

    In Claude Code, write "type": "http" and "url". An entry with url but no type is read as stdio and skipped. streamable-http is accepted as an alias for http.

    Cursor takes url alone. Gemini CLI uses httpUrl for Streamable HTTP (its url field means SSE). Antigravity uses serverUrl (or url). Put tokens in headers, for example "Authorization": "Bearer ...".

  4. 4

    Keep secrets out of the file

    Reference environment variables instead of pasting keys, so you can commit the file:

    • Claude Code: ${API_KEY} or ${API_KEY:-default} in command, args, env, url and headers
    • Cursor: ${env:API_KEY}, plus ${workspaceFolder} for the project root
    • Gemini CLI: $API_KEY or ${API_KEY} in env
  5. 5

    Reload and check it loaded

    • Claude Code: run claude mcp list (shows Connected, Needs authentication or Failed to connect) or /mcp in a session. Approve new .mcp.json servers when asked.
    • Claude Desktop: fully quit (Cmd+Q, or Quit from the tray on Windows) and reopen; closing the window is not enough.
    • VS Code: run MCP: List Servers from the Command Palette.
    • Cursor: open its MCP settings and check the server and tool list.
  6. 6

    Or skip the file and use the CLI

    • Claude Code, local: claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable -- npx -y airtable-mcp-server (options before --, the server command after it)
    • Claude Code, remote: claude mcp add --transport http notion https://mcp.notion.com/mcp
    • Claude Code, from a JSON block: claude mcp add-json <name> '<json>' with the object inside mcpServers
    • Gemini CLI: gemini mcp add --transport http <name> <url>

    Add --scope project in Claude Code to write the entry to .mcp.json for your team.

Code

.mcp.json (local server)
{
  "mcpServers": {
    "example": {
      "command": "npx",
      "args": ["-y", "@example/mcp-server"],
      "env": {
        "API_KEY": "${API_KEY}"
      }
    }
  }
}
Same shape in Claude Code, Claude Desktop, Cursor, Gemini CLI and Antigravity. ${API_KEY} expansion is Claude Code syntax; Cursor uses ${env:API_KEY}.
.mcp.json (remote server, Claude Code)
{
  "mcpServers": {
    "api-server": {
      "type": "http",
      "url": "${API_BASE_URL:-https://api.example.com}/mcp",
      "headers": {
        "Authorization": "Bearer ${API_KEY}"
      }
    }
  }
}
From the Claude Code docs. Without "type", Claude Code treats the entry as stdio and skips it.
.vscode/mcp.json
{
  "servers": {
    "example": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@example/mcp-server"]
    }
  }
}
VS Code uses "servers", not "mcpServers", and each entry declares its type.
~/.gemini/settings.json
{
  "mcpServers": {
    "httpServerWithAuth": {
      "httpUrl": "http://localhost:3000/mcp",
      "headers": {
        "Authorization": "Bearer your-api-token"
      }
    }
  }
}
From the Gemini CLI docs. httpUrl is Streamable HTTP; url is SSE. Gemini CLI documents $VAR expansion in env only, not in headers. Antigravity uses serverUrl in mcp_config.json.
terminal
# Claude Code: remote server
claude mcp add --transport http notion https://mcp.notion.com/mcp

# Claude Code: local server (options before --, server command after)
claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable -- npx -y airtable-mcp-server

# Claude Code: paste the object inside mcpServers
claude mcp add-json example '{"command":"npx","args":["-y","@example/mcp-server"]}'

# Claude Code: share with your team via .mcp.json
claude mcp add --transport http shared-server --scope project https://example.com/mcp

# Gemini CLI
gemini mcp add --transport http http-server https://api.example.com/mcp/
Commands from the Claude Code and Gemini CLI docs.

Common errors and fixes

  • MCP server "<name>" has a "url" but no "type"; add "type": "http" (or "sse" / "ws") to this entry

    Cause: Claude Code reads an entry with no type as a stdio server.

    Fix: Add "type": "http" (or "sse" or "ws" to match the endpoint).

    claude-code Source

  • Server shows ⏸ Pending approval (run `claude` to approve)

    Cause: A project-scoped server from .mcp.json that you have not approved yet.

    Fix: Run `claude` interactively and approve it. `claude mcp reset-project-choices` resets earlier choices.

    claude-code Source

  • 'url' is not a valid URL

    Cause: A ${VAR:-default} reference whose variable is set to an empty string. An empty value counts as set, so the default is not used.

    Fix: Unset the variable instead of setting it to an empty string, or set the real value.

    claude-code Source

  • Remote server fails with 401 although the token is in an environment variable

    Cause: In a remote url or headers, Claude Code reads credential variables such as ANTHROPIC_API_KEY or NPM_TOKEN as empty.

    Fix: Copy the value into a variable with your own name (for example MY_SERVICE_TOKEN) and reference that.

    claude-code Source

  • Config copied from Claude Desktop loads no servers in VS Code

    Cause: VS Code uses a "servers" wrapper key and a "type" on each entry, not "mcpServers".

    Fix: Rename the wrapper to "servers" and add "type": "stdio" (or "http") to each entry.

    vs-code Source

  • Edits to claude_desktop_config.json have no effect

    Cause: Claude Desktop reads its config at launch, and closing the window does not quit it.

    Fix: Quit with Cmd+Q (macOS) or Quit from the tray icon (Windows), then reopen. Check the JSON syntax and use absolute paths.

    claude-desktop Source

Verdict

Copy the server's own JSON, then fix the four things that differ by client: file path, wrapper key, URL field and type. In Claude Code, prefer claude mcp add over editing files by hand.

The catch is that no two clients agree on every field. A config that loads in Claude Desktop can fail silently in VS Code or skip a remote server in Claude Code, so check the server list after every edit.

Best for

  • Sharing a team setup through a committed .mcp.json
  • Moving a server between Claude Desktop, Cursor and Claude Code

Skip it if

  • You would have to paste a real API key into a file you commit

Questions

What is mcp.json?

It is the configuration file an AI client reads to know which MCP servers to start or connect to. The common shape is {"mcpServers": {"<name>": {...}}}, where each entry is either a local command (command, args, env) or a remote endpoint (url, headers). Cursor names the file mcp.json, Claude Code uses .mcp.json for project servers and Claude Desktop uses claude_desktop_config.json.

Is there one mcp.json schema for every client?

No single file format is shared by all clients; each client documents its own fields. The core is common: mcpServers, then command/args/env for local servers and a URL plus headers for remote ones. Differences: VS Code wraps entries in servers and adds type; Claude Code needs type (stdio, http, sse or ws) on remote entries; Gemini CLI uses httpUrl; Antigravity uses serverUrl.

Where is the mcp.json file?

Claude Code: .mcp.json in your project root, or ~/.claude.json for local and user scope. Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows. Cursor: .cursor/mcp.json or ~/.cursor/mcp.json. VS Code: .vscode/mcp.json. Gemini CLI: ~/.gemini/settings.json. Antigravity: ~/.gemini/config/mcp_config.json.

What is the difference between .mcp.json and ~/.claude.json in Claude Code?

.mcp.json sits in the project root and holds project-scoped servers you commit for your team; Claude Code asks you to approve them before first use. ~/.claude.json in your home folder holds local-scoped servers (one project, private to you) and user-scoped servers (all your projects). If the same name is in more than one, local wins over project, and project over user.

How do I add an MCP server in Gemini CLI?

Run gemini mcp add <name> <command> [args...] for a local server, or gemini mcp add --transport http <name> <url> for a remote one. It writes to .gemini/settings.json by default; add -s user for ~/.gemini/settings.json. In the file, Streamable HTTP servers use httpUrl.

Where is the Antigravity MCP config?

Antigravity reads ~/.gemini/config/mcp_config.json for all projects and <workspace>/.agents/mcp_config.json for one workspace. In Antigravity IDE you reach it from the agent panel: ... > MCP Servers > Manage MCP Servers > View raw config. Remote entries use serverUrl.

How do I use environment variables in mcp.json?

Claude Code expands ${VAR} and ${VAR:-default} in command, args, env, url and headers of .mcp.json. Cursor uses ${env:VAR}. Gemini CLI expands $VAR or ${VAR} in env. In Claude Code, credential variables such as ANTHROPIC_API_KEY read as empty in a remote server's url and headers, so copy the value into a variable with your own name.

Why does my server not show up after I edit the file?

Most often: a JSON syntax error, a relative path, a remote entry missing type in Claude Code, mcpServers used in VS Code instead of servers, or a client that was not restarted. Claude Desktop must be fully quit, not just closed. In Claude Code, claude mcp list prints the reason next to each server.

Can I share mcp.json with my team?

Yes. In Claude Code, commit .mcp.json (or run claude mcp add --scope project ...). In Cursor, commit .cursor/mcp.json. Keep keys out by referencing environment variables, and have each person set them locally.

Sources

Docs, issue trackers and discussions this page is built from.

Show all 7
  1. Connect Claude Code to tools via MCP · code.claude.com
  2. Model Context Protocol (MCP) · cursor.com
  3. Add and manage MCP servers in VS Code · code.visualstudio.com
  4. Connect to a real host · py.sdk.modelcontextprotocol.io
  5. MCP servers with the Gemini CLI · github.com
  6. MCP in Antigravity · antigravity.google
  7. Build an MCP server · modelcontextprotocol.io

Updated Nov 1, 2026.