How to Control MCP Servers on a Per-Project Basis in Claude Code

You control MCP servers per project through two keys in your project's .claude.json file: mcpServers to override or extend definitions, and disabledMcpServers to blacklist specific servers from the global catalog.

The everything-claude-code repository implements a two-tier configuration system that separates the global catalog of available Model Context Protocol (MCP) servers from project-specific selections. This design lets teams maintain a centralized library of tools while keeping each project's active MCP set lean and purposeful.

Understanding the Configuration Architecture

The repository stores a global catalog of MCP servers in mcp-configs/mcp-servers.json. This file contains the master list with launch commands, arguments, environment variables, and descriptions for every available server. However, projects do not automatically inherit all servers from this catalog. Instead, each project must explicitly opt in to the tools it needs.

This separation prevents context window overflow—the README explicitly warns against enabling more than 10 MCP servers per project to preserve the model's effective context.

Where Project Configuration Lives

Claude reads project-level MCP configuration from either:

  • ~/.claude.json — global user defaults
  • .claude.json in the project root — project-specific overrides (takes precedence)

The local .claude.json is the recommended location for per-project control.

The Two Control Mechanisms

mcpServers: Override or Extend the Global Catalog

The mcpServers key allows complete or partial redefinition of server definitions. When present, it merges with the global catalog—project entries take precedence, and new entries extend the set.

Complete replacement example — define only the servers this project needs:

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT_HERE"
      },
      "description": "GitHub PR & repo ops"
    },
    "memory": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-memory"],
      "description": "Persistent session memory"
    }
  }
}

Partial override example — add a custom server while inheriting the rest:

{
  "mcpServers": {
    "my-custom-mcp": {
      "command": "node",
      "args": ["custom-mcp.js"],
      "description": "Internal analytics MCP"
    }
  }
}

disabledMcpServers: Blacklist Unwanted Servers

The disabledMcpServers key accepts an array of server names to exclude from the active set. This is the safest way to trim the global catalog without redefining every entry you want to keep.

Aggressive filtering example:

{
  "disabledMcpServers": [
    "firecrawl",
    "supabase",
    "vercel",
    "railway",
    "cloudflare-docs",
    "cloudflare-workers-builds",
    "cloudflare-workers-bindings",
    "cloudflare-observability",
    "clickhouse",
    "context7",
    "magic",
    "filesystem"
  ]
}

Combine both keys for precise surgical control:

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT_HERE"
      },
      "description": "GitHub PR & repo ops"
    },
    "memory": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-memory"],
      "description": "Persistent session memory"
    }
  },
  "disabledMcpServers": [
    "firecrawl",
    "supabase",
    "vercel",
    "railway",
    "cloudflare-docs",
    "cloudflare-workers-builds",
    "cloudflare-workers-bindings",
    "cloudflare-observability",
    "clickhouse",
    "context7",
    "magic",
    "filesystem"
  ]
}

How the Merge Logic Works

When Claude initializes a session, it applies this three-step resolution:

  1. Load global catalog from mcp-configs/mcp-servers.json (lines 3-88)
  2. Merge project overrides — spread projectConfig.mcpServers over globalCatalog.mcpServers
  3. Filter blacklist — remove any server whose name appears in disabledMcpServers

The resulting set is what Claude instantiates via npx, HTTP endpoints, or custom commands.

Merge pseudocode:

const globalCatalog = loadJSON('mcp-configs/mcp-servers.json').mcpServers;
const projectConfig = loadJSON('.claude.json');

const merged = {
  ...globalCatalog,
  ...(projectConfig.mcpServers || {})
};

const active = Object.keys(merged).filter(
  name => !(projectConfig.disabledMcpServers || []).includes(name)
);

Configuring MCP Servers in Practice

Step 1: Inspect the Global Catalog

Review mcp-configs/mcp-servers.json in the everything-claude-code repository to see available servers and their default configurations. Each entry includes:

  • command — executable to launch (typically npx or node)
  • args — command arguments, often including the package name
  • env — optional environment variables for authentication
  • description — human-readable purpose statement

Step 2: Create Your Project's .claude.json

Place this file in your project root. Start minimal:

{
  "disabledMcpServers": []
}

Then iteratively refine based on which tools your codebase actually needs.

Step 3: Verify Active Servers

After starting Claude Code, observe which MCP servers initialize. If you exceed 10 active servers, the README warns that you risk degrading the model's context efficiency (lines 358-360).

Step 4: Handle Hook Dependencies

The hooks/hooks.json file defines automation that may depend on specific MCP servers. Disabling a server referenced by active hooks will disable those hooks automatically—verify your hooks still function after trimming the MCP list.

Key Files for MCP Configuration

File Purpose
mcp-configs/mcp-servers.json Master catalog of all available MCP servers with launch configurations
README.md Context window guidance and disabledMcpServers documentation (lines 358-360)
.claude.json (project-level) Your per-project overrides and blacklist (you create this)
hooks/hooks.json Hook definitions with potential MCP dependencies

Summary

  • Global catalog lives in mcp-configs/mcp-servers.json — maintain this centrally, enable nothing by default.
  • mcpServers in .claude.json overrides or extends catalog entries for your project.
  • disabledMcpServers in .claude.json blacklists specific servers by name.
  • Merge order: global catalog → project mcpServers overlay → disabledMcpServers filter.
  • Stay under 10 active MCPs per project to protect context window efficiency.

Frequently Asked Questions

Can I disable all global MCP servers and define only project-specific ones?

Yes. Set "disabledMcpServers" to a list of all global server names, or provide a complete replacement in "mcpServers" that omits any you do not need. The override completely replaces global definitions for matching keys.

Does the .claude.json file support environment variable substitution?

No. The configuration expects literal values in env fields. For secrets, reference environment variables in your shell profile and ensure they are available when Claude launches, or use project-specific .env files loaded by your MCP wrapper.

What happens if I disable an MCP server that a hook requires?

Hooks defined in hooks/hooks.json that depend on the disabled server will fail gracefully or skip execution. Review your active hooks after modifying disabledMcpServers to ensure automation continues working.

Can different team members use different MCP selections for the same project?

Yes. Each developer can maintain personal overrides in ~/.claude.json for global defaults, or use untracked local .claude.json files (add to .gitignore) for project-specific preferences. The repository's global catalog remains the shared baseline.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →