MagicTools
Developer ToolsAugust 3, 202657 views5 min read

MCP Config Generator: How to Write a Correct mcp.json for Claude Code, Cursor & VS Code

MCP Config Generator: How to Write a Correct mcp.json for Claude Code, Cursor & VS Code

Most MCP setup failures are not the server's fault. They are mistakes in the config file — a trailing comma, a comment left in strict JSON, a command line crammed into the wrong field, or a root key that one client accepts and another silently ignores. This guide explains how MCP config files actually work across the major clients, shows you the exact file each one reads, and covers the errors that trip everyone up.

What Is an MCP Config File?

MCP (Model Context Protocol) servers are configured through JSON files. Each client — Claude Code, Claude Desktop, Cursor, VS Code — reads a different file, and they do not all agree on the structure. The two things that vary are:

  1. Where the file lives
  2. The root key (mcpServers vs servers)

Get either one wrong and the client silently ignores your server, or throws a confusing parse error that says nothing about the real problem.

Where Is the mcp.json File Located for Each Client?

Client Config file Root key
Claude Code .mcp.json at the project root (plus user-level config) mcpServers
Claude Desktop claude_desktop_config.json in its app-support folder mcpServers
Cursor .cursor/mcp.json mcpServers
VS Code .vscode/mcp.json servers

The filename and location matter as much as the JSON itself. Save a Claude Code config where VS Code expects it and VS Code will never see it.

How to Add an MCP Server to Claude Code

Two ways, and a good MCP config generator gives you both:

  1. Save an .mcp.json at your project root with the server under the mcpServers key. Checked into the repo, it works for everyone on the team.
  2. Run claude mcp add from the terminal to register the server without creating a file.

For team projects the checked-in file is the better choice — it version-controls the setup. For personal experiments the CLI command is faster.

stdio vs HTTP: Two Transport Shapes

stdio servers are local processes the client launches directly (command + args). They suit tools that need local access — files, databases, your machine's capabilities.

HTTP servers are remote endpoints connected by URL. The modern Streamable HTTP transport has replaced the deprecated SSE transport; if you see "transport": "sse" in an old config, that is a migration signal.

The #1 Mistake: Arguments in the Wrong Field

The most common error in stdio configs is writing the whole command line into command:

{ "command": "npx -y @modelcontextprotocol/server-filesystem" }

Clients execute command directly, without going through a shell. There is no file called npx -y @modelcontextprotocol/server-filesystem, so this fails. The executable goes in command, and every argument becomes its own string in args:

{
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-filesystem"]
}

This is the single most common stdio configuration mistake, and a proper validator checks for it specifically.

Other Common mcp.json Errors

  • Trailing commas after the last item in an object or array — legal in JavaScript, illegal in strict JSON
  • // comments — legal in JavaScript, illegal in strict JSON
  • Misspelled root keysmcpservers (wrong case) or mcpServer (wrong pluralization) instead of mcpServers
  • args that isn't an array — some tools accept a single string; the schema wants an array
  • Outdated transportsse instead of streamable-http

Client error messages rarely tell you which of these you hit. That is why a validator that names the exact mistake and the fix beats staring at a generic parse error.

Don't Commit API Keys

MCP configs routinely carry tokens, and the files are easy to commit by accident. Claude Code supports ${VAR} environment-variable expansion inside .mcp.json values, so you can commit the config and keep secrets in the environment:

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" }
    }
  }
}

For other clients, keep secret-bearing configs out of version control or inject values at deploy time.

Generate and Validate, Don't Hand-Write

Config syntax is unforgiving and the details differ per client. Use the MCP Config Generator to produce a correct mcp.json for Claude Code, Claude Desktop, Cursor, or VS Code — it picks the right file path and root key for your client, and for Claude Code it also prints ready-to-run claude mcp add commands. Paste an existing config into its validator and it reports each problem with the fix, not a generic parse error.

Everything runs locally in your browser, which matters because mcp.json files routinely carry API keys and tokens.

FAQ

Where is the mcp.json file located for each client? Claude Code reads .mcp.json at the project root, Claude Desktop reads claude_desktop_config.json in its app-support folder, Cursor reads .cursor/mcp.json, and VS Code reads .vscode/mcp.json.

Why does my mcp.json fail to parse? Almost always a trailing comma after the last item, or a // comment — both legal in JavaScript, neither legal in strict JSON. A validator points at the exact line.

What's the difference between stdio and HTTP transport? stdio servers are local processes launched by the client (command + args), for local resources. HTTP servers are remote endpoints connected by URL; Streamable HTTP has replaced the deprecated SSE transport.

Why must arguments go in args, not command? Clients execute command without a shell. "command": "npx -y server" looks for a file literally named npx -y server and fails. Executable in command, each argument as its own string in args.

How do I avoid committing API keys inside .mcp.json? Claude Code supports ${VAR} expansion, so commit the config and keep secrets in the environment. For other clients, keep secret-bearing configs out of version control or inject at deploy time.

Is my config uploaded anywhere? No. Both the generator and the validator are pure client-side JavaScript — your config, including any tokens in it, never leaves the browser.

Related Articles

DeepSeek V4 Pro vs Flash: I Ran 5 Hard Tests. Here's What 12x Gets You.

Here's the short version: **Pro is worth it for agent workloads. Flash has a hidden token-eating habit you won't notice until a long task eats your context.**

toolsAug 4, 20268 min
39

Half My openclaw Commands Ran, Half Didn't — It Looked Like a Permission Classifier, It Was launchd

Same machine, same user, same global config. Two Claude Code windows running the same CLI — one worked, one didn't. The obvious suspect was the permission classifier, which really does block commands. But the cause sat a layer down: the daemon's plist was installed and never loaded, so every gateway-bound subcommand died while purely local ones printed fine. That half-working shape is what sells the permission theory. Full trace, including the hypothesis I got wrong by misreading my own logs.

permissionstroubleshooting+4
developerAug 4, 20267 min
31

Running a 70B Model on a 4GB GPU: Hacker Dreams vs. Engineer Reality

70B on a single 4GB GPU, or small models at scale on the edge? AirLLM and Cloudflare show two roads to cheaper inference. A no-hype comparison of what each trades, and where each fits.

developerAug 4, 20264 min
41

How Much VRAM Do I Need for a Local LLM? (2026 Guide with Calculator)

How much VRAM do I need to run a local LLM? This guide breaks down the four factors that decide it — weights, quantization, KV cache, and overhead — with a rule of thumb (0.6 GB per billion params at Q4_K_M), real examples (DeepSeek R1, Kimi K3), and the exact math from our free LLM VRAM calculator.

developerAug 3, 20265 min
51

Published by MagicTools