Environment
- Version:
codebase-memory-mcp 0.9.0 (installed via install.sh --ui, ~/.local/bin/codebase-memory-mcp)
- Platform: macOS 24.6.0 (Darwin) arm64
- Setup: a monorepo whose root and 7 sub-repos are each indexed as a separate project (parent +
-go, -frontend, -backend, -content, -config, -ssc-content-plugin). Driven over stdio MCP from an agent host (no CLI restarts between calls).
Summary
With 7 indexed projects but only ~6 resolvable at any instant, the least-recently-used project reports "project not found or not indexed" on index_status / search_graph / detect_changes — even though it is fully indexed and, once touched, queryable. Querying one heavy project evicts another, so which 6 resolve flips over the course of a session. list_projects and index_status report different sets in the same instant, and neither reports the true indexed set.
This looks like a bounded resident/store pool (~6) with LRU-style eviction, where the discovery endpoints report the resident set rather than the indexed set. It is distinct from:
Reproduction
7 projects indexed. Within a single running server session:
list_projects → returns 6 projects including -go (30,741 nodes) but omitting -frontend.
index_status({project:"-go"}) → ❌ "project not found or not indexed", whose available_projects (count: 6) lists -frontend but omits -go. (list_projects and index_status disagree in the same instant.)
index_status({project:"-frontend"}) → ✅ status: ready, 62,546 nodes.
- Now issue a few
search_graph / get_code_snippet calls against -go. These succeed (the graph lazy-loads on demand).
- Re-run
index_status({project:"-go"}) → ✅ now ready, 30,741 nodes — it resolves now that it's resident.
- Re-run
index_status({project:"-frontend"}) → ❌ now "project not found or not indexed" — -frontend was evicted by loading -go.
The resolvable set is a sliding window of ~6; the 7th (LRU) is always reported "not indexed."
Expected
list_projects and index_status report the full set of indexed projects, regardless of which graphs are currently resident.
- A project that is indexed-but-evicted is not reported as
"project not found or not indexed" — either resolve it transparently (as the query tools already do via lazy-load), or return a distinct status (e.g. not_resident / will_load_on_query) so callers don't conflate it with genuinely-unindexed code.
Impact
The query tools themselves are excellent and lazy-load fine — but agents are told (by the standard workflow / hooks) to verify with list_projects / index_status first, and run index_repository if "not indexed." Because those endpoints intermittently report the biggest, most-used graphs (-go, -frontend) as "not indexed," agents either (a) fall back to grep, or (b) needlessly re-index (which no-ops on unchanged HEAD SHA). This is a concrete driver of #509 ("AI not using the MCP as much as it should"): the discovery layer, not the data, is what makes agents give up.
Suggested fix direction
- Make
list_projects / index_status enumerate the indexed set (open the .db registry) independent of the resident/LRU pool — the same source both endpoints should agree on.
- Raise the resident-pool cap to at least the number of indexed projects (or make it configurable), and/or evict lazily so a query always transparently loads its target.
- Distinguish
"evicted / not resident" from "not indexed" in the error, so automation doesn't trigger a spurious index_repository.
Environment
codebase-memory-mcp 0.9.0(installed viainstall.sh --ui,~/.local/bin/codebase-memory-mcp)-go,-frontend,-backend,-content,-config,-ssc-content-plugin). Driven over stdio MCP from an agent host (no CLI restarts between calls).Summary
With 7 indexed projects but only ~6 resolvable at any instant, the least-recently-used project reports
"project not found or not indexed"onindex_status/search_graph/detect_changes— even though it is fully indexed and, once touched, queryable. Querying one heavy project evicts another, so which 6 resolve flips over the course of a session.list_projectsandindex_statusreport different sets in the same instant, and neither reports the true indexed set.This looks like a bounded resident/store pool (~6) with LRU-style eviction, where the discovery endpoints report the resident set rather than the indexed set. It is distinct from:
resolve_store/cbm_validate_project_name; my project names are all[A-Za-z0-9-], so that path passes. This is dynamic, not a fixed per-name rejection.Reproduction
7 projects indexed. Within a single running server session:
list_projects→ returns 6 projects including-go(30,741 nodes) but omitting-frontend.index_status({project:"-go"})→ ❌"project not found or not indexed", whoseavailable_projects(count: 6) lists-frontendbut omits-go. (list_projects and index_status disagree in the same instant.)index_status({project:"-frontend"})→ ✅status: ready, 62,546 nodes.search_graph/get_code_snippetcalls against-go. These succeed (the graph lazy-loads on demand).index_status({project:"-go"})→ ✅ nowready, 30,741 nodes — it resolves now that it's resident.index_status({project:"-frontend"})→ ❌ now"project not found or not indexed"—-frontendwas evicted by loading-go.The resolvable set is a sliding window of ~6; the 7th (LRU) is always reported "not indexed."
Expected
list_projectsandindex_statusreport the full set of indexed projects, regardless of which graphs are currently resident."project not found or not indexed"— either resolve it transparently (as the query tools already do via lazy-load), or return a distinct status (e.g.not_resident/will_load_on_query) so callers don't conflate it with genuinely-unindexed code.Impact
The query tools themselves are excellent and lazy-load fine — but agents are told (by the standard workflow / hooks) to verify with
list_projects/index_statusfirst, and runindex_repositoryif "not indexed." Because those endpoints intermittently report the biggest, most-used graphs (-go,-frontend) as "not indexed," agents either (a) fall back to grep, or (b) needlessly re-index (which no-ops on unchanged HEAD SHA). This is a concrete driver of #509 ("AI not using the MCP as much as it should"): the discovery layer, not the data, is what makes agents give up.Suggested fix direction
list_projects/index_statusenumerate the indexed set (open the.dbregistry) independent of the resident/LRU pool — the same source both endpoints should agree on."evicted / not resident"from"not indexed"in the error, so automation doesn't trigger a spuriousindex_repository.