StackMCP
Blog
·8 min read

How to Set Up MCP Servers in Claude Code — Complete Guide

Step-by-step guide to configuring MCP servers in Claude Code CLI. Learn project vs global config, the mcp add command, permissions, and troubleshooting.

mcpclaude-codesetupguidehow-to

Claude Code is Anthropic's terminal-based AI coding assistant and has the most flexible MCP integration of any client. It supports two config methods (JSON file and CLI), project-scoped and global servers, a granular permission model, and both stdio and HTTP transports. This guide covers everything you need to get MCP servers running in Claude Code.

TL;DR: Create a .mcp.json file in your project root with your server definitions, or use claude mcp add from the terminal. Claude Code merges project-level and global configs automatically and asks permission before each tool invocation.

graph TD
    A[Get API tokens] --> B[Create .mcp.json or run claude mcp add]
    B --> C[Start Claude Code]
    C --> D{Servers connected?}
    D -->|Yes| E[Approve tool permissions]
    D -->|No| F[Check troubleshooting below]
    E --> G[Ready to use]

Two Ways to Configure MCP Servers

Claude Code gives you two methods for adding MCP servers: a JSON config file and a CLI command.

Method 1: The .mcp.json Config File

Create a file called .mcp.json in your project root. Claude Code reads it on startup.

{
  "mcpServers": {
    "supabase-mcp": {
      "command": "npx",
      "args": ["-y", "@supabase/mcp-server-supabase"],
      "env": {
        "SUPABASE_ACCESS_TOKEN": "sbp_your_token_here"
      }
    }
  }
}

This file is project-specific. You can commit it to version control (with placeholder values for secrets) so your team shares the same MCP setup.

Method 2: The claude mcp add Command

claude mcp add supabase-mcp \
  --command npx \
  --args "-y" "@supabase/mcp-server-supabase" \
  --env SUPABASE_ACCESS_TOKEN=sbp_your_token_here

Use .mcp.json for versioned, shareable configs. Use claude mcp add for quick experiments. Both produce identical results.

Project-Level vs User-Level Config

Project-level: .mcp.json

Place .mcp.json in your project root. Servers defined here are only available inside that project.

my-project/
  .mcp.json          <-- project-level MCP config
  package.json
  src/

User-level: ~/.claude.json

Servers configured globally (via claude mcp add --global) are available in every project. Good for universally useful servers like GitHub MCP.

claude mcp add github-mcp \
  --command npx \
  --args "-y" "@modelcontextprotocol/server-github" \
  --env GITHUB_PERSONAL_ACCESS_TOKEN=ghp_your_token_here \
  --global

When both exist, Claude Code merges them. Project-level takes priority on name conflicts.

Complete .mcp.json Example

Three servers covering a typical fullstack web workflow:

Supabase MCP | npm | Tools: 25 | ~12,875 tokens

GitHub MCP | npm | Tools: 20 | ~10,300 tokens

Playwright MCP | npm | Tools: 20 | ~10,300 tokens

{
  "mcpServers": {
    "supabase-mcp": {
      "command": "npx",
      "args": ["-y", "@supabase/mcp-server-supabase"],
      "env": {
        "SUPABASE_ACCESS_TOKEN": "sbp_your_token_here"
      }
    },
    "github-mcp": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token_here"
      }
    },
    "playwright-mcp": {
      "command": "npx",
      "args": ["-y", "@playwright/mcp"]
    }
  }
}

Field Reference

  • mcpServers: Top-level object. Each key is the server name you choose.
  • command: The executable ("npx", "uvx", "node", "docker").
  • args: Command-line arguments. For npm servers: ["-y", "@package/name"].
  • env: Environment variables passed to the server process. API keys go here.

The claude mcp CLI Commands

# Add a stdio server
claude mcp add my-server --command npx --args "-y" "@some/mcp-server" --env API_KEY=your_key

# Add an HTTP/SSE server
claude mcp add remote-docs --url https://mcp.example.com/sse

# List configured servers
claude mcp list

# Remove a server
claude mcp remove my-server

# Global scope (add --global to any command)
claude mcp add github-mcp --command npx --args "-y" "@modelcontextprotocol/server-github" --global

Stdio vs HTTP/SSE Transport

Stdio (local): Claude Code spawns the server as a child process. Fast, secure, no network exposure.

{
  "mcpServers": {
    "playwright-mcp": {
      "command": "npx",
      "args": ["-y", "@playwright/mcp"]
    }
  }
}

HTTP/SSE (remote): For hosted MCP servers. Uses url instead of command/args.

{
  "mcpServers": {
    "remote-server": {
      "url": "https://mcp.example.com/sse"
    }
  }
}

Environment Variables and Secrets

  • Inline in config: Put the value directly in .mcp.json. Fine for personal projects, never commit real secrets.
  • Placeholder values: Commit with "YOUR_SUPABASE_ACCESS_TOKEN" and document what each dev needs.
  • CLI with shell vars: claude mcp add supabase-mcp --env SUPABASE_ACCESS_TOKEN=$SUPABASE_ACCESS_TOKEN
  • .gitignore approach: Add .mcp.json to .gitignore if it contains only secrets.

The Permission Model

Claude Code asks before each tool invocation:

Claude wants to use: supabase-mcp > list_tables
Allow this tool? (y/n/always)
  • y -- allow this invocation
  • n -- deny this invocation
  • always -- allow for the rest of the session

This is a meaningful security advantage over clients that auto-allow all MCP tool calls. If a server exposes a destructive tool, you can deny it while allowing read-only queries. For more on MCP security, see how to secure your MCP server setup.

Walkthrough: Setting Up 3 Servers From Scratch

Step 1: Gather credentials

Step 2: Create .mcp.json

Use the complete example from the section above. Replace placeholder tokens with your real values.

Step 3: Start Claude Code

claude

Claude Code detects .mcp.json automatically and starts the servers.

Step 4: Verify

claude mcp list

All three servers should show as connected.

Step 5: Test

  • "List all tables in my Supabase project"
  • "Show the open pull requests in this repository"
  • "Take a screenshot of http://localhost:3000"

Approve tool permissions when prompted. For deep dives on each server, see the individual guides: Supabase MCP, GitHub MCP, Playwright MCP.

Troubleshooting

"Server failed to start"

npx not found: Your PATH might not include Node.js, especially with nvm. Use the absolute path:

{
  "command": "/Users/you/.nvm/versions/node/v20.11.0/bin/npx",
  "args": ["-y", "@supabase/mcp-server-supabase"]
}

Wrong package name: Test manually: npx -y @supabase/mcp-server-supabase

"Tool not available"

  • Server crashed after starting -- check terminal output
  • Server needs additional env vars before exposing tools
  • Restart Claude Code to pick up reconfigured servers

Environment variable issues

  • Variable names are case-sensitive (SUPABASE_ACCESS_TOKEN != supabase_access_token)
  • Copy tokens fresh -- trailing spaces cause silent auth failures
  • Verify the token is still valid in the service dashboard

JSON syntax errors in .mcp.json

Validate with:

python3 -c "import json; json.load(open('.mcp.json'))"

Common mistakes: trailing commas, single quotes, unquoted keys. For a comprehensive list of fixes, see how to fix MCP server connection errors.

Managing MCP Across Multiple Projects

  • Global servers for universal tools: GitHub MCP is useful regardless of project. Add it with --global.
  • Project-level for specific tools: Database and project-specific servers go in each project's .mcp.json.
  • Watch your token budget: Each server's tool definitions consume context tokens. Five servers could use 40,000+ tokens. Only enable what you actively need. See how to cut MCP token costs for strategies.

The same servers work across Cursor, Continue.dev, and Windsurf -- only the config format changes. Browse pre-built stacks to find the right server combination for your workflow.

Related Stacks

Related Servers