feat(mcp): --wiki-root auto — resolve at MCP startup, not install time#36
Merged
Conversation
…l time
Real bug surfaced by an A/B run: keeba MCP was rooted at
/home/ali/keeba-go (cwd at install time), but the user opened Claude
Code in /home/ali/forta/codebase/risk-graph/risk-graph-indexer (which
has its own .keeba/symbols.json). Claude correctly bailed with
"Keeba index pointing at wrong repo. Fall back to grep." and used
Read+rg for half the investigation. That's $1+ of session cost burned
on a routing miss the install command made trivially fixable.
Fix: install now writes `--wiki-root auto` by default. At MCP server
startup, resolveAutoWikiRoot walks up from os.Getwd() looking for:
1. .keeba/symbols.json (canonical — what the MCP server consumes)
2. keeba.config.yaml (back-compat fallback for wiki-only repos)
3. cwd itself (last resort, server still boots, tools return the
"no symbol graph — run keeba compile first" hint)
Receipt to stderr at every startup so the user can see which root
they bound to:
keeba mcp serve: auto-resolved --wiki-root to /path/to/repo
(via .keeba/symbols.json; cwd=/launch/cwd)
Backwards compat: explicit --wiki-root-override at install time still
bakes an absolute path into the editor config, treated as opt-out of
auto-resolution. Older configs with --wiki-root="" or installs that
predate this change continue to work — empty is treated as auto.
Bonus: this also obsoletes the worktree warning we ship in
mcp_install.go. Auto-resolve picks up whichever .keeba/ the worktree
checkout has, instead of the main checkout's stale graph. The
warning still fires on explicit pin to a worktree path, since that
case (user deliberately pinned) is still ambiguous.
New helper internal/config.FindCodeGraphRoot walks up for
.keeba/symbols.json. Three new config tests + five new CLI tests
covering: symbols.json preferred over config.yaml, config.yaml
fallback, cwd fallback, empty-treated-as-auto, explicit-pin
passthrough.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
keeba mcp install --tool claude-codenow writes--wiki-root autoby default. The MCP server resolves the wiki root at startup by walking up from the editor's cwd for.keeba/symbols.json, instead of baking the install-time cwd into the editor config.--wiki-root-override <path>still works — opt-out of auto for users who want to lock the install to one repo.Why
Real-world A/B run yesterday surfaced this as the single biggest savings leak keeba ships with — bigger than any codec layer.
User installed keeba from
/home/ali/keeba-go(the keeba repo itself). Install baked--wiki-root /home/ali/keeba-gointo~/.claude.json. They later opened Claude Code in/home/ali/forta/codebase/risk-graph/risk-graph-indexerto investigate a different bug. That repo has its own.keeba/symbols.json, but the MCP server was still serving the keeba-go graph.Claude correctly bailed:
Half the investigation ran on Read +
rgagainst full files instead of keeba tools. Output tokens stayed at 17.7k, dollar cost stayed at $2.57 — savings would have been substantially better if keeba had served the right graph from the start.This is a routing bug that codec layers, output styles, and CLAUDE.md guidance can't fix. Has to be fixed at the install/serve layer.
How
--wiki-root autoresolvesAt server startup, walk up from
os.Getwd():.keeba/symbols.json(canonical signal — what the MCP server actually consumes)keeba.config.yaml(back-compat fallback for wiki-only repos without a compiled graph)Stderr receipt at every startup so the user sees which root the session bound to:
Backwards compat
--wiki-root-override <path>at install time bakes an explicit absolute path. Treated as opt-out — no auto-resolution.--wiki-root(older configs) is treated identically toauto. Existing installs keep working.mcp_install.goonly fires when the user explicitly pinned a worktree path; auto-mode makes the warning unnecessary because each worktree's own.keeba/is what gets served.Test plan
go test ./internal/config/... ./internal/cli/...— all green (3 new config tests, 5 new CLI tests)golangci-lint run— 0 issues--wiki-root autoto~/.claude.jsonkeeba mcp serve --wiki-root autofrom a subdir of an indexed repo prints the receipt and serves the correct root--wiki-root autofrom a non-indexed dir falls back to cwd, server still startskeeba mcp install, restart Claude Code, open it inrisk-graph-indexer, re-run the same investigation prompt. Expected: 16+ keeba calls (no more grep fallbacks), output drops below 17.7k, cost drops below $2.57.🤖 Generated with Claude Code