Skip to content

fix(mcp): add --tools CLI flag for CODEGRAPH_MCP_TOOLS fallback (#1192)#1232

Open
umi008 wants to merge 1 commit into
colbymchenry:mainfrom
umi008:fix/1192-mcp-tools-env
Open

fix(mcp): add --tools CLI flag for CODEGRAPH_MCP_TOOLS fallback (#1192)#1232
umi008 wants to merge 1 commit into
colbymchenry:mainfrom
umi008:fix/1192-mcp-tools-env

Conversation

@umi008

@umi008 umi008 commented Jul 9, 2026

Copy link
Copy Markdown

Summary

Adds codegraph serve --mcp --tools=<list> as a CLI fallback for the
CODEGRAPH_MCP_TOOLS env var. Some MCP clients (OpenCode, Antigravity
IDE) don't forward the env block from the MCP server config to the
spawned process, so users pinning the tool surface via
env.CODEGRAPH_MCP_TOOLS see only the default codegraph_explore
regardless of what they set.

Root cause

The filtering logic in getStaticTools() (proxy) and
ToolHandler.getTools() (direct / daemon) is correct — both read
process.env.CODEGRAPH_MCP_TOOLS at call time. The bug is that some
MCP clients don't inject the env block from the MCP config into the
spawned process, so process.env.CODEGRAPH_MCP_TOOLS is empty when
the server reads it.

Fix

Add a --tools flag to the serve --mcp command. The flag is parsed
by commander and sets process.env.CODEGRAPH_MCP_TOOLS before
MCPServer construction, so it propagates through every runtime path:

  1. ProxyrunLocalHandshakeProxygetStaticTools() reads the
    env var at call time.
  2. Daemon — the spawn uses env: { ...process.env } (line 156 in
    src/mcp/index.ts), so the daemon inherits the env var from the
    launcher.
  3. Direct modeToolHandler.getTools()toolAllowlist()
    reads the env var.

The CLI flag wins over a pre-set env var so the operator's explicit
intent in the MCP config is always honored. An empty value is treated as
unset to match the existing whitespace-only env-var behavior in
toolAllowlist().

Validation

  • New test suite __tests__/cli-mcp-tools-flag.test.ts exercises
    end-to-end against the built binary:
    • default surface (only codegraph_explore) when --tools is omitted
    • requested surface when --tools=explore,search,node
    • single-tool allowlist (--tools=callers)
    • empty value falls back to the default
    • --tools wins when both flag and env var are set
    • the proxy path also honors --tools (env var set in the
      launcher process before the proxy intercepts tools/list)
  • All 6 new tests pass on Linux + macOS.
  • Existing mcp-tool-allowlist.test.ts (7 tests) and
    mcp-initialize.test.ts (3 tests) still pass — no regression.

Reproduction

// .mcp.json (works on Claude Code, Cursor, Codex CLI, Kiro)
{
  "mcpServers": {
    "codegraph": {
      "command": "codegraph",
      "env": { "CODEGRAPH_MCP_TOOLS": "explore,search,node" }
    }
  }
}
// .mcp.json (works on opencode, Antigravity IDE — the env block is ignored)
{
  "mcpServers": {
    "codegraph": {
      "command": "codegraph",
      "args": ["serve", "--mcp", "--tools=explore,search,node"]
    }
  }
}

Closes #1192

…ymchenry#1192)

Some MCP clients (OpenCode, Antigravity IDE) don't forward the `env`
block from the MCP server config to the spawned process, so users pinning
the tool surface via `env.CODEGRAPH_MCP_TOOLS` see only the default
`codegraph_explore` regardless of what they set.

The new `codegraph serve --mcp --tools=<list>` flag mirrors the env
var and is set BEFORE MCPServer construction, so it propagates through
every runtime path: the proxy's static ListTools (runLocalHandshakeProxy
-> getStaticTools), the detached daemon via the spawn's
`env: { ...process.env }`, and the direct-mode ToolHandler.

The CLI flag wins over a pre-set env var so the operator's intent in the
MCP config is always honored, and an empty value is treated as unset to
match the existing whitespace-only env-var behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Setting "CODEGRAPH_MCP_TOOLS": "explore,search" has no effect; only a single explorer tool is displayed

1 participant