How to Connect an MCP Server

Every guide teaches you to build a server; almost none explain connecting one. The config is the same object everywhere — clients just disagree about the wrapper key, which is why your last paste silently did nothing.

Reviewed

Nearly every MCP guide teaches you to build a server. Far fewer explain the thing you will actually do a hundred times more often: connect one that already exists, in a client that has its own opinions about where config lives and what the keys are called.

The mechanics are simple. The confusion is entirely accidental, and it comes from one fact: clients disagree about the wrapper key.

The one entry, two wrappers problem

Every MCP server config is the same object underneath. A local server names a command to run:

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

A remote server names a URL to dial:

{
  "type": "http",
  "url": "https://mcp.sentry.dev/mcp"
}

That object is the part that varies per server. What varies per client is only what you wrap it in.

Claude Desktop, Claude Code and Cursor file it under mcpServers:

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

VS Code files the identical entry under servers:

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

That is the whole difference. If you have ever pasted a config from a vendor's docs and had your client silently ignore it, this was almost certainly why — the JSON was valid, the client just wasn't looking at that key.

Every server page in our MCP directory prints both wrappers for exactly this reason.

Where the file lives

  • Claude Desktop~/Library/Application Support/Claude/claude_desktop_config.json on macOS. Restart the app after editing; it reads config at launch.
  • Claude Code — prefer the CLI: claude mcp add --transport http sentry https://mcp.sentry.dev/mcp. It writes the config for you and handles OAuth on first use via /mcp.
  • Cursor~/.cursor/mcp.json globally, or .cursor/mcp.json inside a project.
  • VS Code.vscode/mcp.json for one workspace, or MCP: Add Server from the Command Palette.

The name you choose as the key — filesystem above — is what the client shows you and what it uses internally. Keep it lowercase and hyphenated. Some clients reject spaces and capitals outright, and none of them benefit from a display name here.

Local or remote is the decision that matters

A local server is a process on your machine, launched by your client, talking over stdio. Nothing crosses the network. Credentials come from the environment.

A remote server is a URL. Your client makes HTTP requests to somebody else's infrastructure, and authorization happens over OAuth.

That single choice determines your entire threat model, and it is covered properly in MCP transports. The short version for setup purposes:

Local servers execute code on your machine with your privileges. The MCP specification's own security guidance is blunt about it — a malicious startup command in a config file is arbitrary code execution, and the examples it gives are things like exfiltrating ~/.ssh/id_rsa. Read the command before you paste it. One-click install buttons from directories are exactly the vector this describes.

Remote servers do not run anything locally, but they see whatever you authorise them to see. Which brings us to the credential.

Credentials, in decreasing order of how much you should like them

OAuth. The client opens a browser, you approve, the token lives in the client and never touches your config file. This is where the ecosystem has converged: Stripe, GitHub, Linear, Notion, Sentry, Vercel, Supabase, Asana, Atlassian and Cal.com all work this way. Nothing to paste, and revocation is a dashboard away.

An environment variable. For local servers that need an API key, put the key in your environment and reference it:

{
  "command": "npx",
  "args": ["-y", "some-mcp-server"],
  "env": {
    "SOME_API_KEY": "${SOME_API_KEY}"
  }
}

A key pasted directly into the config file. Avoid. That file gets copied into bug reports, synced to cloud backups, and occasionally committed. If a vendor's quickstart tells you to paste a live key inline, treat it as a first draft rather than a recommendation.

Scope the credential too. An API key that can create and confirm orders is a different object from one that can list products, and the MCP server will happily use whichever you hand it.

When it doesn't work

Roughly in the order these actually happen:

  1. Wrong wrapper key. See above. It is this more often than anything else.
  2. Client not restarted. Claude Desktop in particular reads config at launch.
  3. Command not on PATH. Your shell finds npx; the GUI app that launched without your shell profile may not. Use an absolute path to test.
  4. Malformed JSON. A trailing comma fails silently in most clients — no error, the server simply never appears.
  5. stdout pollution. If you wrote the server yourself and it prints anything to stdout that isn't a JSON-RPC message, the transport is corrupted. Log to stderr. This is the single most common bug in hand-rolled stdio servers.

For anything past that, the MCP Inspector is the right tool — it connects to a server directly, lists its primitives, and calls them, which separates the server is broken from my client config is broken in about thirty seconds.

Once it connects

A connected server contributes tools, resources and prompts to your session. Tools are the ones the model can invoke on its own initiative, so the useful habit after connecting anything new is to look at what it actually exposes — not what the README says it does.

More servers is not better. Every tool description occupies context on every turn, and a model choosing among ninety tools chooses worse than one choosing among twelve. Connect what you are using now, disconnect the rest, and read how to optimise agent cost and latency if your bills say you already learned this the expensive way.

Before you connect anything with real access, MCP security is worth twenty minutes. The attacks are specific, named in the specification, and mostly not the ones people expect.

Prompts to try