Original Pages

Free guide · MCP

MCP server stuck red in Cursor

Level · Intermediate

A server that will not connect tells you almost nothing from the sidebar. The actual error is sitting in a log panel most people never open, and once you read it the cause is usually obvious. This page is about getting to that error quickly, then fixing the three things it normally turns out to be.

The short version

  1. Open the Output panel — Cmd+Shift+U on Mac, Ctrl+Shift+U on Windows and Linux — and choose MCP Logs. Read the actual error before changing anything — reading the logs.
  2. Check whether the same server name exists in both .cursor/mcp.json and ~/.cursor/mcp.json. They merge, and the project one wins — the two config files.
  3. If it needs credentials, re-run auth from the surface that is actually failing, and remember OAuth is per user — auth.
  4. Still stuck? Remove the server under Customize > MCPs and re-add it, and restart Cursor if you changed a shell profile — the documented sequence.

Not sure what MCP even is? Skip the box and start below.

New to MCP? Start here

What an MCP server actually is

MCP — Model Context Protocol — is a standard way to give the agent tools it does not have built in: read from your database, open a GitHub issue, query an internal API. An “MCP server” is just a small program that exposes those tools in a format the agent understands.

The word “server” confuses people, so be concrete. There are two kinds:

  • stdio servers run as a process on your own machine. Cursor launches them with a command — typically something like npx — and talks to them over standard input and output. Nothing is listening on a public port; it is a local program.
  • remote servers are reached over HTTP at a URL. The program runs somewhere else and Cursor connects to it.

This distinction matters more than it looks, because the two kinds fail in completely different ways. A stdio server fails when the command cannot run or its environment is missing something. A remote server fails when the URL or the credentials are wrong.

One thing worth saying plainly: the colour of the indicator next to a server is not defined anywhere in Cursor’s documentation. People say “red dot” because that is what they see, and it is a perfectly good search term — but do not go hunting for an official red/amber/ green table, because there isn’t one. Read the logs instead. They contain the real answer.

The detail

The two config files, and how they merge

Cursor reads MCP configuration from two places:

  • .cursor/mcp.json in a project, for tools specific to that codebase.
  • ~/.cursor/mcp.json in your home directory, for tools you want everywhere.

Both files are merged. If the same server name appears in both, the project-level config takes priority. That single sentence explains a whole category of “I fixed it and nothing changed” — you edited the global file while a project file of the same name was quietly overriding it.

A local stdio server looks like this:

{
  "mcpServers": {
    "server-name": {
      "command": "npx",
      "args": ["-y", "mcp-server"],
      "env": { "API_KEY": "value" }
    }
  }
}

And a remote one like this:

{
  "mcpServers": {
    "server-name": {
      "url": "http://localhost:3000/mcp",
      "headers": { "API_KEY": "value" }
    }
  }
}

The top-level key is mcpServers in both cases. For stdio servers, command is required and args, env and envFile are optional — envFile is stdio-only. Servers needing static OAuth take an auth object, where CLIENT_ID is required and CLIENT_SECRET and scopes are not.

A genuine wrinkle if you are reading the docs closely: the stdio reference table lists a type field as required, with "stdio" as its example value — yet none of the documentation’s own example config blocks actually include it. If a server misbehaves and you have copied an example verbatim, this is a reasonable thing to try adding, but the docs are genuinely inconsistent here rather than you having misread them.

Reading the logs, which is the actual fix

This is the step that turns a guessing game into a two-minute job, and it is the one most people skip:

  1. Open the Output panel: Cmd+Shift+U on Mac, Ctrl+Shift+U on Windows and Linux.
  2. Select MCP Logs from the dropdown.

The logs show server initialisation, tool calls, and error messages. An stdio server whose command does not exist says so. A remote server rejecting your token says so. Compared with staring at an indicator, this is not a small improvement — it is the difference between diagnosis and superstition.

Worth knowing about failure behaviour too: when a server fails, Cursor shows an error message in chat, the tool call is marked as failed, and your other servers continue working normally. One broken server does not take the rest down, which is also why a broken one can sit unnoticed for weeks.

Authentication

For Marketplace servers, you click Add to Cursor and then follow the authentication prompts. From the CLI, it is agent mcp login with the server identifier.

The load-bearing fact: OAuth is per user — including for MCP servers shared at team level. A colleague’s working setup proves nothing about yours, and a server shared with your whole team still needs you, personally, to authenticate.

If you authenticate from both the desktop app and the web, note that Cursor uses fixed redirect URLs — https://www.cursor.com/agents/mcp/oauth/callback for web and Cursor Agents, and http://localhost:8787/callback for the desktop app. If you are building or self-hosting the server, both need registering as allowed redirect URIs.

Environment variables that never arrive

This one is quietly responsible for a lot of failures, especially with stdio servers that expect an API key from your shell. Cursor’s own troubleshooting guidance is to ensure that variables set in your shell profile are actually available to Cursor — and to restart Cursor after updating that profile.

The reason is mundane: an application inherits the environment it was launched with. If you added the export after Cursor was already running — or launched Cursor from a desktop icon that never read your shell profile at all — the variable exists in your terminal and nowhere else. Putting the value in the server’s own env block, or in an envFile, sidesteps the whole question.

The documented troubleshooting sequence

  1. View the logs. Output panel → MCP Logs. Always first.
  2. Toggle the server under Customize > MCPs. Isolating one server at a time tells you whether the problem is that server or your setup around it.
  3. Restart it properly. The documented restart is to remove the server under Customize > MCPs and add it again — not merely to reload the window.
  4. Check environment variables, and restart Cursor after any shell profile change.
  5. Check for a name collision between your project and global config, per above.

The CLI and Cloud Agents

The CLI uses the same configuration as the editor — servers you have configured work in both — and resolves config in the order project → global → nested. agent mcp list reports connection status as plain text, connected or disconnected, which is often a faster check than anything in the GUI.

Cloud Agents support MCP too, managed under Dashboard → Integrations & MCP. Configurations are encrypted at rest, and sensitive fields are redacted and cannot be read back by any user after saving — so if you are wondering why you cannot re-read a token you pasted last week, that is by design. When authentication fails there you get mcp_auth_error: the server’s tools are skipped and the run continues rather than failing outright.

The transport split matters inside Cloud Agents, and it is covered in detail in Cursor Cloud Agents: repo vs environment — briefly, HTTP server configuration is never present in the agent’s VM and calls are proxied, while stdio servers run inside the VM and depend on what your install script put there.

What people repeat that is not documented

In the interest of not wasting your afternoon on folklore, three widely-repeated claims that do not appear in Cursor’s documentation:

  • Specific dot colours and their meanings. Not documented. The indicator is real; an official colour code is not.
  • A hard cap on the number of tools or servers. A particular number circulates in forum threads. It is not in the docs, so treat it as unverified rather than as a limit to design around.
  • Windows cmd /c wrappers being required. Community posts describe this workaround. It may well help in practice, but Cursor does not document it, so try it as an experiment rather than believing it is the sanctioned setup.

What to read next

For the wider setup this fits into, read Cursor setup that survives updates. If you are running Claude alongside Cursor and wondering which tool owns your MCP configuration, see Using Claude with Cursor.