Generate paste-ready MCP server configuration for Claude Code, Claude Desktop, VS Code, Cursor, and Codex CLI. Supports stdio and remote HTTP transports.
Every MCP client wants the same four or five facts about a server — what to run, with which arguments, in which environment, or which URL to call — and every one of them spells it differently. Claude nests servers under mcpServers. VS Code uses servers and insists on an explicit type. Cursor uses mcpServers but omits type entirely. Codex CLI is not JSON at all: it is TOML, with a different key name again. Getting a server working in one client teaches you almost nothing about the next.
This generator removes the translation step. You describe the server once in a single form, and it emits the correct, paste-ready configuration for all four clients simultaneously, updating as you type. Switch tabs to see each dialect. Everything is built in the browser — the JSON and TOML are assembled in local state and nothing is sent anywhere, so putting a real internal URL in the form is safe.
Take the tool's default: a server called my-server, launched locally with npx and the arguments -y and @modelcontextprotocol/server-filesystem. Here is what changes between the tabs.
| Client | File | Format | Top-level key | Transport marker (stdio) |
|---|---|---|---|---|
| Claude Code / Desktop | .mcp.json or claude_desktop_config.json | JSON | mcpServers | None — implied by command |
| VS Code | .vscode/mcp.json | JSON | servers | "type": "stdio" |
| Cursor | ~/.cursor/mcp.json | JSON | mcpServers | None |
| Codex CLI | ~/.codex/config.toml | TOML | [mcp_servers.<name>] | None |
Concretely, the Claude tab gives you a mcpServers object whose single entry holds command, args and, if you added any, env. The VS Code tab gives you the identical inner object with "type": "stdio" prepended, wrapped in servers. Cursor's is byte-for-byte the Claude version. Codex gives you a TOML table header [mcp_servers.my-server] followed by command = "npx", an args array, and an env inline table.
The transport toggle changes which fields the form shows and reshapes every output.
Local (stdio) means the client spawns a process on your machine and speaks MCP over its standard input and output. You supply a command — the executable, typically npx, uvx, node or python — and an ordered list of arguments, each in its own row so you never have to worry about shell quoting. Environment variables go in the env object as key/value pairs. Choose this when the server needs your filesystem, your local credentials, or a binary installed on your machine.
Remote (HTTP) means the client makes HTTP requests to a hosted server. You supply a url and optional headers, most commonly an Authorization header. The form pre-fills Authorization: Bearer YOUR_TOKEN as a reminder of the usual shape. Choose this when the server is a shared service, is centrally maintained, or reaches data that should not be pulled onto a laptop.
The remote outputs diverge more than the local ones. Claude and VS Code both emit "type": "http" alongside url and headers. Cursor emits only url and headers, no type. Codex uses url and — the detail that trips people up — http_headers, not headers, rendered as a TOML inline table.
| Client | Remote keys emitted |
|---|---|
| Claude Code / Desktop | type: "http", url, headers |
| VS Code | type: "http", url, headers |
| Cursor | url, headers |
| Codex CLI | url, http_headers |
env row will not appear in the output.args key at all. No environment variables means no env. No headers means no headers. Clients handle a missing key more predictably than an empty one.my-server; clear the command and you get npx; clear the URL and you get https://example.com/mcp. The output is always syntactically complete.A–Z a–z 0–9 _ - is emitted as a quoted key. A Windows path in a Codex argument will not break the file.Say you want the filesystem server limited to one project directory, with an API key from the environment. Set the transport to Local, the command to npx, and three argument rows: -y, @modelcontextprotocol/server-filesystem, and /Users/you/projects/acme. Add one environment pair with the key API_KEY.
The Claude tab produces an mcpServers object with your server name mapping to command: "npx", an args array of those three strings in order, and an env object with your one key. The VS Code tab is the same with type: "stdio" and the servers wrapper. The Codex tab is four TOML lines: the table header, command, an args array, and env = { API_KEY = "…" } as an inline table.
The argument order is preserved exactly as listed, which matters here: the directory path is positional, and moving it above the package name would break the launch.
The generator describes a single server. If your config file already has servers in it, do not paste over the file. Copy the inner entry — the "my-server": { … } block — and add it as a sibling inside the existing mcpServers or servers object, remembering the comma. For Codex, TOML tables are independent, so appending the whole [mcp_servers.<name>] block to the end of config.toml is correct as-is.
Run the generator once per server if you are configuring several. Two servers may not share a name within one file; the second silently replaces the first.
Values are emitted literally, exactly as typed. Type a live API key into an env value and it appears verbatim in the generated JSON or TOML. That is the honest behaviour for a config generator — it has no way to know your secret store — but it means the file you save is a file you must not commit.
The safer pattern is to keep the key name in the config and the value somewhere else, and to check the file before it reaches a repository. Our MCP config validator scans a pasted config for hard-coded credentials and flags them.
| Symptom | Likely cause |
|---|---|
| Client does not list the server at all | Wrong top-level key for that client — servers in a file that wants mcpServers, or the reverse. |
| VS Code rejects the entry | Missing type. VS Code wants it explicitly; the other JSON clients do not. |
| Codex ignores the server | Table written as [mcpServers.name] instead of [mcp_servers.name], or headers under headers instead of http_headers. |
| Server starts then exits immediately | Arguments split wrongly. Each token gets its own row — -y and the package name are two arguments, not one string. |
| Command not found | The client spawns the process without your interactive shell's PATH. Use an absolute path to the executable. |
| Remote server returns 401 | Header name or the Bearer prefix is wrong, or the placeholder token was never replaced. |
| Config edits do nothing | Most clients read the file at startup. Restart the client after changing it. |
Each tab shows its own path above the code block. .mcp.json sits in a project root and is shared with anyone who checks out the repository, which is why secrets in it are a live problem; claude_desktop_config.json is per-user. .vscode/mcp.json is per-workspace. ~/.cursor/mcp.json and ~/.codex/config.toml are per-user and global. Project-scoped files are the right home for a server every contributor needs; user-scoped files are the right home for anything carrying your personal credentials.
The server name is the key in the config object, and it is also what the model sees when it decides which server's tools to use. Two habits pay off. Keep it short and descriptive of the data, not the implementation — company-docs beats mcp-server-fs-2. And keep it stable, because the name appears in the tool identifiers a model learns to use, and renaming it mid-project makes previous conversations refer to something that no longer exists.
Names must be unique within a file. If you are configuring the same server twice against different data — two filesystem servers scoped to two directories, say — give them distinct names that say which is which, and generate each one separately.
The argument rows map one-to-one onto the array the client passes to the process, in order, with no shell in between. That has two consequences worth internalising.
-y @scope/server into a single row produces one argument containing a space, which is not the same thing and will normally fail.Order is preserved exactly as the rows appear, which matters whenever a server takes positional arguments after its flags. If a server starts and immediately exits, mis-split or reordered arguments are the first thing to check.