Overview

Claude Code connects to MCP servers declared in settings.json. Once connected, the server’s tools appear alongside built-in tools and Claude can call them in any turn. The pattern rule is: prefer MCP tools over Bash when the integration will be used across sessions. A one-off gh invocation is fine; recurring GitHub operations belong in the GitHub MCP server. See mcp-servers for designing servers; this page covers the Claude Code client configuration.

Declare MCP servers in settings.json

Each server gets an entry under mcpServers. The key is the server’s logical name; the value describes how to launch or connect to it.

{
  "mcpServers": {
    "github": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}"
      }
    },
    "postgres": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres", "${DATABASE_URL}"]
    }
  }
}

Place project-specific servers in .claude/settings.json. Place personal or cross-project servers in ~/.claude/settings.json. Both files are read; project settings merge on top.

Pass secrets through environment variables, never inline

The env block in the server config accepts ${VAR} substitutions resolved from the shell environment. Never write a token or connection string as a literal value in settings.json.

Reasons: settings.json is often committed to version control. Literals leak in diffs, logs, and PR reviews. Environment variables stay in .env (gitignored) or in the CI secrets store.

"env": {
  "GITHUB_TOKEN": "${GITHUB_TOKEN}",
  "DATABASE_URL": "${DATABASE_URL}"
}

Claude Code reads the current shell environment when launching servers. Set the variables in your shell profile or a gitignored .env.local file sourced at session start.

Restrict tool exposure with allowedTools

By default, Claude Code exposes every tool a server advertises. Use allowedTools to restrict access to the tools the project actually needs.

{
  "mcpServers": {
    "github": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" },
      "allowedTools": [
        "mcp__github__list_issues",
        "mcp__github__create_pull_request",
        "mcp__github__pull_request_read",
        "mcp__github__merge_pull_request"
      ]
    }
  }
}

Restricting to read-only tools for a project that should not create issues prevents accidents during exploratory sessions. Allowlists also document the project’s intended integration surface.

Scope servers to specific repositories

Use project-level .claude/settings.json rather than user-level ~/.claude/settings.json when the server is specific to one repo. A Postgres server pointed at the dev database for project A should not appear in project B’s sessions.

For shared servers (GitHub, Notion), declare them at the user level but restrict allowedTools per project. The user-level declaration provides the auth; the project-level restriction limits the blast radius.

Prefer MCP tools over Bash for durable integrations

The tradeoff is:

  • Bash with gh pr create: works, no setup, breaks on quoting edge cases, not logged by MCP, not consistent across sessions.
  • mcp__github__create_pull_request: typed inputs, no quoting issues, MCP-level logging, consistent schema across sessions.

Use Bash for one-off commands the agent will not repeat. Use MCP tools for operations that recur: reading PRs, posting comments, querying a database, writing to a project management tool.

The practical test: if you have written the same Bash command in three different briefs, write an MCP server for it or enable the official one.

Confirm server connectivity before relying on it in a brief

MCP servers can fail to start (missing binary, bad token, network error). A brief that assumes GitHub MCP is live will silently fall back to Bash or fail mid-session.

Add a preflight step to briefs that depend on MCP:

Phase 0: Verify MCP connectivity.
Run: list available tools and confirm mcp__github__list_issues is present.
If not present, stop and report the error.

This catches misconfiguration before the expensive phases run.