Skip to content

fix(mcp): keep codegraph_explore loaded in Claude Code and Copilot CLI - #1697

Open
bompus wants to merge 1 commit into
colbymchenry:mainfrom
bompus:fix/claude-always-load
Open

fix(mcp): keep codegraph_explore loaded in Claude Code and Copilot CLI#1697
bompus wants to merge 1 commit into
colbymchenry:mainfrom
bompus:fix/claude-always-load

Conversation

@bompus

@bompus bompus commented Sep 4, 2026

Copy link
Copy Markdown

Fixes #1696.

Claude Code defers every MCP tool behind its ToolSearch step by default, so a fresh session sees only codegraph_explore's name until the model searches for it. On a default codegraph install setup with no project rule naming the tool, 4 of 6 headless Opus sessions never called it and did the task with Grep/Read; with the schema in context from the first turn, 6 of 6 did (numbers and the reproduction in #1696).

Change

  • codegraph_explore carries _meta: { "anthropic/alwaysLoad": true } in src/mcp/tools.ts, and ToolDefinition gains an optional _meta. Claude Code reads the key and keeps the tool's schema loaded from the first prompt. It reaches an existing install on upgrade without touching the user's config; other hosts ignore _meta.
  • The Claude Code installer target writes "alwaysLoad": true on the server entry (src/installer/targets/claude.ts), on both the project .mcp.json and the global ~/.claude.json path. Re-running codegraph install adds the key to an entry that predates it. The README's manual ~/.claude.json snippet shows the key.
  • The Copilot CLI target writes "deferTools": "never" on its entry (src/installer/targets/copilot-cli.ts). Copilot CLI's tool search defers MCP tools once ~30 tools are connected, and that key is its per-server opt-out (docs). Docs-verified only; the host is not installed here.
  • Tests: mcp-tool-annotations.test.ts asserts the _meta on every tools/list surface (the master array, getStaticTools(), ToolHandler.getTools(), and the live server); installer-targets.test.ts covers the key on the Claude project and global paths, the Copilot CLI entry, and the re-run migration for both.
  • CHANGELOG entry under Unreleased › Fixes.

Verified

  • Headless Claude Code 2.1.261, Opus, --strict-mcp-config with the plain entry: the released 1.6.0 server runs ToolSearch then codegraph_explore; this branch's build runs codegraph_explore alone.
  • vitest: 233 passed, 3 skipped. tsc clean.

Not in this PR

OpenCode 2's Code Mode, which puts MCP tools behind a code interface by default. Its per-server opt-out, "codemode": false, only survives on the native v2 entry shape, which the installer does not write yet. Separate issue to follow.

colbymchenry#1696)

Claude Code defers every MCP tool behind ToolSearch by default, so a fresh session sees only the tool name until the model searches for it. The explore tool now carries `_meta: { "anthropic/alwaysLoad": true }`, which exempts it on existing installs, and the Claude Code installer target writes `alwaysLoad: true` on the server entry (re-running install adds the key to an older entry). Copilot CLI tool search holds MCP tools back the same way once ~30 tools are connected, so its entry carries `deferTools: "never"`.
@danusha2345

Copy link
Copy Markdown
Contributor

Merged into a local integration build of current main (one trivial conflict in targets/claude.ts against #1029's CLAUDE_CONFIG_DIR helper — both functions kept). Verified over stdio: tools/list now returns codegraph_explore with _meta: {"anthropic/alwaysLoad": true}, so an existing install picks it up on upgrade without touching ~/.claude.json. installer-targets and mcp-tool-annotations green; full suite 252 files / 4349 passed.

@bompus

bompus commented Sep 6, 2026

Copy link
Copy Markdown
Author

Verified both halves of this against first-party docs and then over the wire. It's correct.

Key names check out. alwaysLoad is the documented Claude Code MCP key, including the per-tool _meta form this PR emits ("anthropic/alwaysLoad": true), and deferTools is documented for Copilot CLI with exactly the "auto" | "never" domain the PR uses. Worth stating explicitly because these are the kind of keys that get copied from the wrong guide and then silently do nothing — a typo'd key is indistinguishable from a working one at the config layer.

Measured over stdio, not read off the source: I spoke MCP to the built server (initializenotifications/initializedtools/list) against a real indexed repo and inspected the advertised tool descriptors.

arm codegraph_explore _meta
base null
this PR {"anthropic/alwaysLoad": true}

So the flag actually reaches the client in the tool listing, which is the only place it can matter. That's the whole claim, and it's confirmed at the protocol boundary rather than at the config file.

LGTM.

bompus added a commit to bompus/codegraph that referenced this pull request Sep 6, 2026
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.

Claude Code defers codegraph_explore behind ToolSearch, so most sessions never call it; the tool and the installer should opt out (alwaysLoad)

2 participants