By Kodelyth · · 7 min read
"Who calls processPayment?" is a structural question. grep answers it
lexically — it finds the string processPayment wherever it appears, drags the
surrounding files into the model's context so it can tell a call from a
definition from a comment, and bills you for every token of all of them. On a
real repository that is hundreds of thousands of tokens to answer one question
whose answer is a short list of names.
An AST knowledge graph answers the same question directly: it already knows which
nodes have a CALLS edge into processPayment, and returns them as structured
data. ECC integrates one to do exactly this.
What it is, and whose it is
ECC wires in DeusData/codebase-memory-mcp: a single static binary that indexes a codebase into a tree-sitter AST graph across 158 languages, with Hybrid LSP semantic type resolution for the major ones (Python, TypeScript/JavaScript/JSX/TSX, Go, Rust, Java, Kotlin, C, C++, C#, PHP). Their binary, their curl script, their MIT license. ECC installs, wires, and surfaces it — no fork, no code copy, no npm dependency.
(If you've seen graphify in an ECC-adjacent repo, that's a different,
standalone graph CLI. The tool ECC integrates for in-session structural queries
is codebase-memory-mcp, exposed through MCP tools your AI calls directly.)
The token math
The project's own comparison puts a structural query like "who calls X" at roughly 3,400 tokens through the graph versus roughly 412,000 tokens via file-by-file grep — about a 99% reduction. That figure is theirs, and it's a property of the approach: the graph returns the answer, while grep returns the material from which the answer must be re-derived, every time, into a context you pay for.
The saving isn't only money. The grep approach also burns context-window space you then don't have for the actual task, and it degrades as the repo grows. The graph query is flat — a Cypher query over the index is sub-millisecond regardless of repo size.
When to use the graph, and when grep is still right
The discriminator is simple: is the question about edges between symbols, or about a string?
| Use the graph | Use grep |
|---|---|
Who calls AuthMiddleware? | Find every TODO: comment |
| What's the impact of changing this type? | Find a literal config key |
| Show the architecture / entry points | Find a log message's exact text |
| Find dead code (functions with zero callers) | Find a typo'd variable name |
Which HTTP routes touch the users table? | One-off string occurrence count |
grep is excellent at lexical questions and you should keep using it for them. The moment the question is "who / what / how do these connect," grep has to reconstruct structure the graph already holds.
The three queries that cover most of it
Your AI translates natural language into these MCP calls, but it helps to know what they are. All run locally, at zero LLM cost, and return structured JSON:
search_graph— find nodes by name or pattern. "Every handler":kodelythecc codebase query search_graph '{"name_pattern": ".*Handler.*"}'trace_path— followCALLSedges in a direction. Outbound from an entry point is "what does this reach"; inbound to a function is "who calls it" and, by extension, the blast radius of changing it:kodelythecc codebase query trace_path '{"function_name": "main", "direction": "outbound"}'query_graph— a Cypher query for everything the first two don't cover: arbitrary patterns overCALLS,IMPORTS,IMPLEMENTS,INHERITS,HTTP_CALLS, and the rest of the edge types.
So "find dead code" is a query_graph for functions with zero inbound CALLS
edges; "what breaks if I change AuthMiddleware" is trace_path inbound. You
rarely write these by hand — you ask the AI in plain words and it dispatches the
right one — but knowing the shape tells you why the answer was cheap.
Install and first index
npm i -g kodelyth-ecc
kodelythecc --target claude-code --codebase-graphThen open a project and say "Index this project" — the AI calls
index_repository and builds the graph. It's fast: a Django-scale repo indexes
in about 6 seconds; the Linux kernel (28M LOC, 75K files) in about 3 minutes, all
in memory with the working set released afterward. Verify the binary and what's
indexed:
kodelythecc codebase statuscodebase-memory-mcp: codebase-memory-mcp 0.8.1
indexed projects: 18
cache dir: /Users/you/.cache/codebase-memory-mcp
next: open a project in your AI tool and say "Index this project"Honest limits
It's an index, which means it can go stale — after a large change, run
detect_changes or re-index so the graph matches the tree, or trace_path will
answer confidently about code that moved. Hybrid LSP semantic types (parameter
binding, return-type inference, generic substitution) cover the major languages
listed above, not all 158 — the rest get the AST structure without the deep type
resolution. And it's a separate binary you install; it persists to a local cache
and your code never leaves the machine, but it is one more thing on your PATH to
keep current.
None of that changes the core trade: for structural questions, one graph query beats reading a repository into the context window, by about two orders of magnitude.
codebase-memory-mcp is MIT by
DeusData, with a
research paper behind it. ECC's wrapper —
install, auto-register, and the codebase query passthrough — is thin Node in
scripts/codebase.
Full reference in Codebase Graph.
npm i -g kodelyth-ecc && kodelythecc --target claude-code --codebase-graph