Home Blog Contact
Home/Blog/How to Add a Local or Remote MCP Server to Cl…
How toLLM EngineeringMCPClaude Codedeveloper tooling

How to Add a Local or Remote MCP Server to Claude Code

9 min readBy Miloš Mitrović

Claude Code talks to your external tools through the Model Context Protocol, and adding a server takes one command: claude mcp add. Run it with --transport http for a cloud service, or with a -- separator and a launch command for a local process. This guide covers both paths, the three scopes that decide who sees the server, and the errors that keep a server from connecting.

Key Takeaways

  • The short answer: claude mcp add --transport http <name> <url> for a remote server, or claude mcp add <name> -- <command> [args] for a local stdio process.
  • Scope decides reach. local (default) is private to you in one project, project ships in a committed .mcp.json for your team, and user follows you across every project.
  • The -- separator is mandatory for stdio servers. Everything after it runs the server; without it Claude Code reads the server's own flags as its own.
  • Check the result with claude mcp list, which prints a live health status such as ✔ Connected or ✘ Failed to connect next to each server.
  • Remote servers that need sign-in use OAuth. Run /mcp inside a session, or claude mcp login <name> from your shell.

What You Need Before You Start

A recent Claude Code install (the scope and status behaviour here assumes a current v2.x build) and a terminal in the project you want the server available in.

You also need one thing about the server itself: either a URL for a remote server, or a launch command such as npx -y some-mcp-server for a local one. If you built the server yourself, for example a TypeScript MCP server with the official SDK, that launch command is how Claude Code starts it.

How to Add an MCP Server to Claude Code

Pick the option that matches what you have (a URL or a command), then verify. You can finish from this section alone.

  1. Add a remote HTTP server. HTTP is the recommended transport for cloud services, per the Claude Code MCP reference. Pass the endpoint URL:
    claude mcp add --transport http notion https://mcp.notion.com/mcp
  2. Send an auth header when the server needs a static token. Use --header (short form -H):
    claude mcp add --transport http github https://api.githubcopilot.com/mcp/ \
      --header "Authorization: Bearer YOUR_GITHUB_PAT"
    Claude Code saves the config without validating the token, so a bad value is accepted here and surfaces as a failed connection later.
  3. Add a local stdio server, with the -- separator. Everything after -- is the command that starts the server. Pass any environment variables with --env (or -e) before the --:
    claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable \
      -- npx -y airtable-mcp-server
  4. Choose a scope if the default is wrong. Add --scope project to share the server with your team through a committed file, or --scope user to make it available in all your projects:
    claude mcp add --transport http shared-server --scope project https://example.com/mcp
  5. Verify the connection. List every server with its health status:
    claude mcp list
    claude mcp get notion
    A ✔ Connected line means the tools are live. Inside a session, run /mcp to see tool counts and reconnect controls.
  6. Sign in if the server requires OAuth. A server that returns 401 or 403 shows as needing authentication. Authorize it from your shell:
    claude mcp login sentry
    Or open /mcp inside a session and follow the browser flow.

Which Transport Should You Pick?

The transport is how Claude Code and the server exchange messages, and it has to match what the server actually speaks. The MCP specification defines two standard transports, stdio and Streamable HTTP, and notes that Streamable HTTP replaces the older HTTP+SSE transport from protocol version 2024-11-05.

TransportFlagUse whenNotes
stdio--transport stdioThe server runs as a local process on your machineDefault when you use -- and a command. Direct system access, no network.
HTTP (Streamable HTTP)--transport httpConnecting to a remote or cloud serverRecommended remote transport. Supports OAuth. In JSON the type accepts streamable-http as an alias for http.
SSE--transport sseA remote server exposes only a legacy SSE endpointDeprecated. Use HTTP where the server offers it.
WebSocketJSON only (type: "ws")The server pushes events over a persistent socketNo --transport ws flag and no OAuth. Header auth only, via claude mcp add-json.

If you point --transport http at an SSE-only endpoint, or the reverse, the add succeeds but the server fails to connect. Match the flag to the transport the server documents.

How Do Scopes Decide Who Sees the Server?

Scope controls which projects load the server and whether the config is shared. The three scopes match duplicates by name, and Claude Code connects once, using the highest-precedence definition (local over project over user).

ScopeFlagLoads inShared with teamStored in
Local--scope local (default)Current project onlyNo~/.claude.json
Project--scope projectCurrent project onlyYes, via version control.mcp.json in project root
User--scope userAll your projectsNo~/.claude.json

Use local scope for a personal or experimental server, or one whose credentials you do not want in version control. Use user scope for a utility you reach for in every repo. Use project scope to standardize tools for a team.

What Does the Committed .mcp.json Look Like?

A project-scoped add writes a standardized file at the project root. Commit it so everyone gets the same tools:

{
  "mcpServers": {
    "shared-server": {
      "type": "http",
      "url": "https://example.com/mcp"
    }
  }
}

Two details save teammates a debugging session. First, a JSON entry with a url but no type is read as a stdio server and skipped, so remote entries must set "type": "http" (or "sse" / "ws"). Second, you can keep secrets out of the file with environment variable expansion, which Claude Code supports in url, headers, command, args, and env:

{
  "mcpServers": {
    "api-server": {
      "type": "http",
      "url": "${API_BASE_URL:-https://api.example.com}/mcp",
      "headers": { "Authorization": "Bearer ${API_KEY}" }
    }
  }
}

The ${VAR:-default} form falls back to default when the variable is unset, which keeps a shared config working on a machine that has not set every value.

How Do You Reuse a Config Written for Another Client?

Setup instructions often ship an mcpServers JSON block written for Claude Desktop or Cursor rather than a claude mcp add command. Pass the object inside mcpServers (not the wrapper) to claude mcp add-json:

claude mcp add-json example '{"command":"npx","args":["-y","@example/mcp-server"]}'

Repair a url entry that lacks a type before you paste it, for the same skip-as-stdio reason described above.

Troubleshooting: Why Is the Server Not Connecting?

Most failures fall into a handful of patterns. Read the status line first, because Claude Code names the cause.

  • Claude Code parses the server's flags as its own. This is a missing --. For a stdio server, put the whole launch command after -- so flags like --port reach the server, not the CLI. Also place at least one option between --env and the server name, or the CLI reads the name as another KEY=value pair and rejects it.
  • The status shows ! Needs authentication. The server returned 401 or 403. Run claude mcp login <name> or open /mcp and re-authenticate. If you set an Authorization header that the server rejects, Claude Code reports a failed connection instead of falling back to OAuth, so drop the header to use the OAuth flow. Adding OAuth to your own remote server is its own task; see adding OAuth 2.1 authorization to a remote MCP server.
  • The status shows ⏸ Pending approval. Project-scoped servers from .mcp.json wait for your approval in an interactive session. Run claude in the project to review and approve them.
  • A remote server reports a url but no type. Claude Code prints MCP server "<name>" has a "url" but no "type"; add "type": "http" and skips it. Add the matching type to the JSON entry.
  • A pasted token carries hidden whitespace. Claude Code warns with a line such as Leading or trailing whitespace in: headers.Authorization and uses the value as written. Edit the config to strip the trailing newline.
  • Adding the same server twice fails. Running claude mcp add again with the same name at the same scope returns MCP server <name> already exists. Remove it first with claude mcp remove <name>, or edit the existing entry.

When a server fails and you are not sure whether the fault is the wiring or the server itself, test the server on its own before blaming Claude Code. Running it through the standalone tooling in the MCP Inspector tells you quickly whether the server answers tools/list at all.

What to Do Next

Connect a server that earns its place: a read-only database server so Claude can answer questions against production data without write access, or an issue tracker so it can open PRs from tickets. The Claude Code MCP quickstart walks a first connection end to end.

Treat every server as untrusted until you have read what it does. A server that fetches external content can carry prompt-injection payloads into your session, so review the source or the vendor before you grant it tools.

Sources

M
Miloš Mitrović
Email Marketing for Ecommerce

Have a question or a project?

Whether it is about this post or a system you want built, I'm happy to talk.

Get in touch

404

Post not found. It may have been moved or the link is incorrect.

← Back to the blog
Summarize with AI
ChatGPT, Perplexity, and Grok open with the prompt ready to run. Claude, Gemini, and Copilot open a chat with the prompt copied; press Ctrl+V (Cmd+V on Mac) to paste. The full text is included, so it works even without web access.