What Structural Memory Can—and Cannot—Become

deusdata/codebase-memory-mcp contributes something more specific than a faster text search: it gives an AI coding agent a persistent, typed, and bounded representation of repository structure. The final question is how far that contribution can be trusted. Taken together, the project shows a credible way to reduce repeated discovery of definitions, calls, routes, and service relationships, but it also shows why structural memory must remain tied to source scope, coverage signals, generation state, and explicit evidence limits.

The judgment is conditional rather than promotional. Codebase-memory-mcp is strongest when a question concerns relationships that can be extracted and queried—where a symbol is defined, what calls it, which route it handles, which tests or modules connect to it, or what a change may affect. It is weaker when the answer depends on an excluded file, an unresolved dynamic behavior, an ambiguous name, an unvalidated semantic match, or a runtime fact that the current static graph does not contain. The project’s architecture is valuable precisely because it gives those boundaries a place in the system.

The value is a change in the agent's first move

A file-by-file agent begins with retrieval. It searches for a name, reads a result, searches for another name, and gradually reconstructs the relationships that the question assumes. That method remains necessary for literal text and exact behavior, but it repeats structural work. Codebase-memory-mcp moves much of that work into an index: discovery establishes scope, extraction creates typed nodes and edges, query surfaces expose the relationships, and exact source remains available for verification.

The result is not a replacement for source code. It is a change in the order of reasoning. Instead of asking an agent to rediscover the shape of a large repository every time, the project lets the agent begin with a map of qualified identities and typed relationships. A question about callers can start with an inbound trace. A question about a request path can combine route and service edges. A change review can begin with affected symbols and then inspect callers, callees, and tests. A question about a literal message can still begin with text search. The contribution is the ability to choose structure when structure is the object of the question.

That contribution depends on the whole system, not one algorithm. The pipeline scopes and parses the source, builds a graph store with node and edge identities, enriches it with type-aware and derived relationships where the evidence allows, and publishes a coherent generation. The MCP layer then exposes different query surfaces for orientation, discovery, tracing, retrieval, and coverage. A shared daemon coordinates sessions, watchers, and resource-heavy jobs. Staging and atomic replacement keep an incomplete refresh from becoming the visible graph.

The relationship among those parts can be expressed as a provenance boundary:

flowchart LR A["Source repository"] --> B["Static graph generation"] B --> C["Static CALLS, search, and architecture readers"] B --> D["Exact source and coverage boundaries"] E["Runtime observations"] --> F["Runtime-observation sidecar"] F --> G["Generation-scoped resolution"] B --> G G --> H["Opt-in RUNTIME_CALL overlay"] C -. "default behavior remains unchanged" .-> I["No runtime data in default static readers"] D --> H

The central arrow runs from source to a static graph generation. The sidecar is deliberately parallel, not a hidden input that rewrites the static graph. This matters because a source-derived CALLS relation and an observed runtime interaction answer different questions. A static graph may show what the code expresses. A runtime observation may show what happened under one workload, sampling policy, deployment, or configuration. Combining them can be useful; silently substituting one for the other destroys provenance.

Consider a request handler as a concrete case. Codebase-memory-mcp can identify the handler in a scoped search, trace local callers or a route relationship, retrieve the exact definition, and check whether the relevant files were fully covered. If a client call crosses a service boundary, a route or cross-project edge can connect the local operation to a target handler without pretending that the two functions are in the same process.