the answer you actually want from your coding agent

Get the real answer from your AI —
not a confident guess.

ctx-optimize gives your coding agent a deterministic map of your codebase, so it answers where is X, who calls Y, what breaks if I change Z with cited file:line facts — in ~100ms, on any repo, in any shell, with nothing else installed. Fewer wrong turns, lower token bills, answers you can trust. One static Go binary. No LLM at query time, no database, no server.

npm install -g @muthuishere/ctx-optimize
ctx-optimize install --skills            # one-time: teach your agent (global)
cd your-repo && ctx-optimize up          # one verb: bootstrap, gather, or pull — then ask anything
watch it work · 60 seconds

The same coding session — with and without it.

One measured Claude Code session, the same questions on the same repo. Without a knowledge graph the agent greps, reads, and opens the wrong file again — more turns, more tokens, more dollars. With the store it asks and gets cited answers instead. The numbers on screen are from one real kill-test run and change with every question, repo, and model — but the savings hold up.

Narrated · one measured session · ~⅓ lower cost, ~¼ fewer turns — actual numbers vary by question & repo

get started

Three commands to a smarter agent.

npm install -g @muthuishere/ctx-optimize   # one static binary per platform, no postinstall downloads
ctx-optimize install --skills               # one-time: teach your coding agent to answer from the store
cd your-repo && ctx-optimize up             # bare repo → bootstraps config + gathers (about a second);
                                            # monorepo → scan-bootstraps one store per module + a navigator;
                                            # clone with a shared store declared → pulls it; stale → refresh

Want control instead of up's defaults — review a monorepo's module list before gathering, pick pointer targets? That's init:

ctx-optimize scan                           # lists every project it found (read-only)
ctx-optimize init --scan --yes && ctx-optimize add .   # curate config.json, then gather explicitly

Source and tests in separate folders (the .NET / Gradle case)? Declare one module across both — they share a graph, and test→source calls resolve across the split:

# .ctxoptimize/config.json
"modules": [{ "name": "Billing", "paths": ["src/Billing", "tests/Billing.Tests"] }]

A teammate cloning your repo runs the same one command — ctx-optimize up — which does whatever the state needs: pulls the team's prebuilt store when the committed config declares a pull, gathers locally otherwise, fast-refreshes a stale store, no-ops on a fresh one. Idempotent — run it whenever.

macOS / Linux / Windows · works with Claude Code, Codex, Copilot & Devin · framework routes, build-tool dependencies, k8s topology, subsystems, multi-path modules & a first-class dashboard · scripted sharing, one-verb onboarding & change-plan · source on GitHub.

agent skills — and everything else your repo knows

Docs, your database schema, any data — one graph, one question.

The installed skill makes your agent query the store before it greps. Markdown docs are gathered natively. Your Postgres schema arrives via a drop-in adapter script — tables become nodes, foreign keys become edges. Anything else goes through the validated JSON door. Then one question cites the table, the code, and the doc together:

Unedited recording · a repo with .ctxoptimize/adapters/postgres-schema.py against a live Postgres

Same corpus. Same machine. 13× faster.

Cold gather of a 12,484-file repository — and ctx-optimize's run includes building the full markdown wiki.

ctx-optimize
0.67s
graphify 0.9.12
8.88s  (its fastest path — no clustering, no LLM)
query, median
96ms
graphify query
367ms

Apple M5 Pro · 2026-07-11 · methodology and every corpus below · raw results.json

the problem

The most expensive thing your agent does is look for things.

without a graph

Grep. Open the file. Wrong one. Grep again. Open three more files just to see one signature. Every hop is tokens, latency, and context that's gone for the rest of the session.

> grep -rn "Merge" .        — 214 matches
> read store.go             — 9.4k tokens
> read store_test.go        — 11k tokens
> read app.go               — 14k tokens
… and the window is half gone
with the store

One query. Complete, citable hits — id, kind, file, line range, signature, doc, callers, callees — under a hard token budget. The agent reads a file only when it truly must.

> ctx-optimize card "Store.Merge"   — 96ms
sig: func (s *Store) Merge(b *schema.Batch) …
doc: Merge upserts a validated batch …
called by (12): cmdAdd, cmdMerge, …
calls (6): Batch.Validate, writeNDJSON, …

the demo that matters

A symbol card answers what used to take four file reads.

Signature, doc comment, location, callers, callees — in one shot, from the graph. This is the read your agent no longer makes. About to edit? change-plan X goes further: one composed answer with the signature, the callers, the blast radius, and which tests to run — measured ~90% fewer answer tokens than the query+card+affected chain it replaces.

Unedited recording · ctx-optimize card "Store.Merge" on this project's own source

remember three things

Fast. Honest. Deterministic.

01

Fast

Tree-sitter grammars compiled to WASM, hosted by wazero, fanned across every core. 12 languages embedded in one static binary; any other language is a one-command grammar pack. Re-gather after a change in under a second.

02

Honest

Every edge carries confidence: EXTRACTED is parsed fact, INFERRED is name-matched. Ambiguous calls are dropped, never guessed. The benchmarks on this page show where the other tool wins, too.

03

Deterministic

Same input, same graph, byte for byte — git-diffable NDJSON, a markdown wiki regenerated on every add, atomic writes. The binary never calls a model. Your agent supplies the intelligence; the store supplies precise recall.


all the numbers

Benchmarks, with the parts that don't flatter us.

Head-to-head vs graphify — the one rival we've run the full measured harness against. Measured 2026-07-11 · Apple M5 Pro (18 cores, 48 GB) · graphify 0.9.12 vs a ctx-optimize dev build · raw data. How we stack up against CodeGraph, GitNexus, potpie & Serena — on architecture, setup, and their own published numbers — is on the comparison.

cold gather — full extraction, bars scaled per corpus

graphify's own source

12,484 files13.3× faster
ctx-optimize
0.67s
graphify
8.88s

nodes 11,056 vs 10,996 — within 1% · store 8.3 MB vs 30.1 MB — 3.6× smaller

flask

265 files1.3× faster
ctx-optimize
0.79s
graphify
1.06s

nodes 1,978 vs 1,473 — we also graph docs & import modules · store 1.3 MB vs 4.2 MB

gin

159 files2.2× faster
ctx-optimize
0.41s
graphify
0.90s

nodes 1,922 vs 1,975 — graphify finds more here, shown as-is · store 1.4 MB vs 6.2 MB

ctx-optimize source

75 files1.4× faster
ctx-optimize
0.37s
graphify
0.51s

nodes 572 vs 599 — graphify finds more here too · store 0.4 MB vs 2.2 MB

query latency — 12k-file corpus, median of 5 runs, 2,000-token budget

"how does clustering work"

4.1× faster
ctx-optimize
89 ms
graphify
367 ms

"remote push pull hooks"

3.8× faster
ctx-optimize
96 ms
graphify
364 ms

"community labeling"

3.9× faster
ctx-optimize
96 ms
graphify
370 ms
▸ raw table — every number in one place
corpusfilesctx coldgraphify coldctx nodesgraphify nodesctx sizegraphify size
graphify's own source12,4840.67s8.88s11,05610,9968.3 MB30.1 MB
flask2650.79s1.06s1,9781,4731.3 MB4.2 MB
gin1590.41s0.90s1,9221,9751.4 MB6.2 MB
ctx-optimize source750.37s0.51s5725990.4 MB2.2 MB
query "how does clustering work"89 ms367 ms
query "remote push pull hooks"96 ms364 ms
query "community labeling"96 ms370 ms
Methodology — read this before quoting the numbers. graphify was timed on its fastest deterministic path (update --no-cluster: extraction only, no clustering, no LLM). ctx-optimize was timed on add, which does more work per run: extraction, graph build, stale-node pruning, and full wiki regeneration. Query latency is the median of 5 runs, same question, same 2,000-token budget, both CLIs invoked cold from the shell. Node counts are shown for scale, not equivalence — the tools disagree about what counts as a node (ctx-optimize graphs import modules and markdown documents as first-class nodes; graphify includes some file types we skip), which is why ctx-optimize shows ~34% more nodes on flask while the 12k-file totals land within 1%. On gin and on its own source graphify finds slightly more nodes and edges than we do, and we show that as-is. graphify also does things ctx-optimize deliberately does not: LLM-assisted community labeling and semantic clustering. If you want those, use graphify — the comparison here is the deterministic core both tools share.

the kill test

We tried to kill this product. Published, either way.

Before launch we pre-committed a kill bar: if the store can't beat a plain grep-and-read agent by 25% on hostile terrain, stop. Then we ran it — 12 Linux-kernel questions, answered twice by the same agent (grep-and-read vs store-first — a real agent always reads, never just greps), every answer judged against source-derived ground truth before tokens counted. Measured 2026-07-12 · full write-up · questions + keys (raw json) · raw runs ship in the repo's proof/.

graphify headlines 71.5× — against pasting your entire repo into every prompt. No agent does that. And graphify's output is a static graphify-out/ dump; ours is extensible by design — drop-in adapters, grammar packs, skills installed by default. We threw the strawman out and tested against a real grep-and-read agent. A smaller honest number beats a big fake one.
−43%
tokens to answer
−32%
cost per session
96ms
per query · ~4× graphify

Tokens & cost: natural usage on Claude Code — plain questions, real dollars, no store vs store. Query latency: 12k-file benchmark. Honest caveat: total session wall runs +31% today (the store trades wall-time for tokens and dollars — more tool calls); we just cut query latency 40% and that gap is closing.

Don't take our word — run it yourself. Same model, same questions, answered three ways over OpenRouter — shell, ctx-optimize, graphify. Last CI run on gorilla/mux:
vs plain shell
−31% cost
−64% tool calls · −36% tokens
vs graphify
~½ the tokens
half the tool calls, lower cost
graphify vs shell
+22% tokens
its node-dump query costs more than grep

See the full table, the harness, and how to run it yourself →

the result that clears the bar — natural usage, plain questions, real dollars billed

Natural usage · Claude Code · zero steering

12 plain questions · real $ billed−31.6% cost
with store
$2.16
no store
$3.16

the fix: cards now carry the function body head (first ~30 lines) — the follow-up read they used to force is gone · turns 70→53 (−24%) · 56 unprompted store calls · before the fix the same harness measured +6% worse (published, below) · quality spot-verified: the $0.05 answers are complete and correct

▸ the full autopsy — the misses, every tier, the mechanism (skeptics, open this)
what died

"Cuts raw input+output tokens on a cached frontier agent" — dead. Claude Code and Codex grep well, and prompt caching absorbs every extra hop, so on that one narrow metric the store is parity on locate/mechanism questions. We don't claim otherwise anywhere on this page. But raw tokens aren't the bill →

what survived

The real bill is cheaper. Cache reads still bill (~10%), and fewer steps means fewer of them — so on each harness's own dollar report the store wins every Claude tier: −9% to −16%. Plus onboarding −34% to −49% tokens, correctness (grep arms of Codex and Devin named the wrong gatekeeper; the store arms didn't), and −13% to −29% steps everywhere.

fresh tokens per tier — where even a hand-tuned grep baseline shows parity (the adversarial version of the test)

Claude Code · default

linux/block · 98 filestoken parity
with store
370k
grep+read
370k

steps ~flat · wall −14% (347→298s) · quality 12/12 vs 11.5/12 — the best grep agent on earth doesn't need us for tokens

Claude Code · Sonnet

linux slice · 3,987 filesgrep wins by 5%
with store
390k
grep+read
370k

steps −13% · wall +3% (386→397s) · quality 11.5/12 vs 12/12 — the store arm was the only one to catch a comment posing as a real caller

Claude Code · Haiku

linux slice · 3,987 filestoken parity
with store
284k
grep+read
287k

steps −29% · wall +9% (641→698s) · quality 11/12 vs 11/12 — a third fewer hops, but caching makes hops free

Codex CLI · default

linux/block · 98 filestoken parity
with store
397k
grep+read
386k

steps ~flat · wall ±0% (683→680s) · quality 11.5/12 vs 11.5/12 — its grep arm named the wrong gatekeeper; the store arm didn't

Devin CLI · SWE-1.6

linux/block · 98 files · n=6−42% tokens
with store
2.30M
grep+read
4.00M

steps −24% · wall −34% (294→195s) · quality 5/6 vs 6/6 · no prompt caching — every step re-pays full context, so saved steps become saved money · daily quota cut the run at 6 pairs

▸ raw table — every number in one place
harness · modelcorpustokens, grep→storestepswall timeanswer quality (grep vs store)
Claude Code · defaultlinux/block · 98 files370,398 → 369,673 (±0%)~flat347→298s (−14%)12/12 vs 11.5/12
Claude Code · Sonnetlinux slice · 3,987 files370,308 → 389,647 (+5%)89→77 (−13%)386→397s (+3%)11.5/12 vs 12/12
Claude Code · Haikulinux slice · 3,987 files286,943 → 283,669 (−1%)174→124 (−29%)641→698s (+9%)11/12 vs 11/12
Codex CLI · defaultlinux/block · 98 files385,794 → 397,323 (+3%)~flat683→680s (±0%)11.5/12 vs 11.5/12
Devin CLI · SWE-1.6linux/block · 98 files (n=6)4,004,232 → 2,300,736 (−42%)−24%294→195s (−34%)5/6 vs 6/6
The mechanism: step-cost economics. The store cuts agent steps at every tier (Haiku −29%, Devin −24%, Sonnet −13%). Whether that becomes fewer tokens depends on what your harness pays per step. Devin re-pays the whole context every step — zero cached tokens — so −24% steps became −42% tokens. Claude Code caches, so extra hops are nearly free: token parity, −14% wall.
The correction that helps us. "Parity" prices cache reads at zero — they bill at ~10%. On each harness's own dollar report the store is cheaper at every Claude tier: −9.2% default · −5.6% Sonnet · −16.2% Haiku, from ~26% fewer cache re-reads. Fewer steps is a real bill cut wherever a step costs money.
What we don't hide. Skill-only, plain questions, before the card fix: +6% worse — agents used the store (57 calls) but re-verified in source. Total session wall is +31% today (more tool calls). The test surfaced three defects in our own ranking/card output, now fixed; the after-number re-run is pending. Scale: 3,987 files → a 274,812-node store + 3,989 wiki pages in 5.5s. Everything, unrounded, is in the write-up.

the model ladder

One store. Every model class. Judged blind.

Same prebuilt store (linux kernel, ~274k nodes), same 8 block-layer questions, one fresh agent session per model — answers graded against withheld golden keys the product already pins in CI. Measured 2026-07-17 · questions, keys & raw transcripts.

model · harnessscore /80avg s/questiontool calls (8 q)notes
Fable 5 · Claude Code8024.623every key + full mechanism chains
Sonnet 5 · Claude Code8017.525every key; fastest frontier-quality run
Opus 4.8 · Claude Code7919.022one canonical symbol described but not named
Haiku 4.5 · Claude Code7213.61890% of frontier quality at half the wall time
gpt-4o-mini · toolnexus, one-shot549.424$0.015 for all 8 — protocol pinned from the committed .ctxoptimize/instructions.md card
The store is model-portable. Sonnet matches Fable exactly at 1.4× the speed. Haiku — the cheapest Claude tier — lands 90% of frontier quality with just 18 tool calls. Agent discipline + the store beats raw model size: Haiku (72) outscored gpt-4o-mini (54) on identical questions.
Small models need the protocol pinned. A short mandatory system prompt — query first, answer only from output, cite file:line, say "not found" after two empty queries — ships in the usage card every store commits at .ctxoptimize/instructions.md. With it, a $0.15/M-token model reaches ~70% of frontier quality at ~1/100th the cost. One-shot per question beats a continuous conversation: same score, 7× cheaper, no cross-question bleed.
What frontier still buys. Canonical-symbol precision, query re-crafting when the first hit is noise, and honest abstention — on a trick question with no real answer, gpt-4o-mini fabricated a module even under protocol; every Claude tier declined to.

the design contract

What's in the binary — and what never will be.

In
  • tree-sitter → WASM, hosted by wazero — pure Go, CGO_ENABLED=0
  • one committable .ctxoptimize/ per repo: config + drop-in adapter scripts
  • central store at ~/ctxoptimize/<repo>/ — multi-module, git-diffable NDJSON
  • team sync is your scriptremote push/pull run commands you declare in the committed config (a git repo, any bucket, anything); secrets stay env-var names
  • query · card · change-plan · explain · path · affected · hubs · wiki · export · serve · up
Out — forever
  • No LLM API. The host agent answers; we serve context.
  • No database. Files, sorted, atomic writes.
  • No embeddings. Lexical + graph retrieval, deterministic.
  • No server. A static binary and your filesystem.
  • No telemetry. Nothing leaves your machine unless you push it.

different by design

Not a clone of any of them. A different bet.

The lane has graph-DB tools (CodeGraph on SQLite, GitNexus on an embedded DB, potpie on Neo4j), a Python central-store (graphify), and a live language-server (Serena). We're the one that's a single static binary you extend — here's what that changes versus the whole field.

One binary — no store to run. CGO-free Go, tree-sitter compiled to WASM. Nothing to stand up: no SQLite file, no LadybugDB, no Neo4j service, no Python venv, no language server per language. npm i -g and it runs, offline.
Deterministic — no model, ever. CodeGraph and GitNexus are structural like us; graphify reaches for an LLM to label communities and potpie keeps one in the loop. We hand all semantics to the agent you already run — zero API keys, reproducible every time.
Extensible without a fork. A new language is a drop-in grammar pack; a framework's routes, a build tool's deps, Postgres, Kafka, logs — drop-in route/manifest packs and adapter scripts through one validated door. No other tool here lets you add a recognizer as a committed JSON file.
More than code, in one graph. Routes→handlers, dependencies that federate across build tools, k8s topology, git co-change, subsystems. Serena has no persistent graph; the graph-DB tools mostly stop at code. And team sync is a script you declare — push/pull to a git repo or any bucket, no server, no built-in transport to trust.

The full board — where every rival wins and where we lose, with numbers — is on the honest comparison.


install

Convinced? It's still three commands.

npm install -g @muthuishere/ctx-optimize
ctx-optimize install --skills   # one-time: teaches your coding agent to use the store
cd your-repo && ctx-optimize up

Every command and every config key — repo config, machine-global config, monorepos, remotes, adapters, route/manifest/grammar packs — on one page: the docs. See where we stand against the field, honestly: the comparison.