crux
by notshekhar
README.md
# crux
A local-first context engine for coding agents.
`crux` watches folders, keeps a live index of your code (plus docs, tickets, and web pages),
and serves it over **MCP** so any agent — loop, Claude Code, Cursor, Windsurf, Zed — can
ask precise questions about your codebase instead of grepping blindly.
**Status:** Phase 1. The live index works end-to-end and serves MCP.
## Install
```bash
curl -fsSL https://raw.githubusercontent.com/notshekhar/crux/main/install.sh | bash
```
Windows (PowerShell):
```powershell
irm https://raw.githubusercontent.com/notshekhar/crux/main/install.ps1 | iex
```
No runtime needed — it's a single static binary. Language grammars are fetched on
first `crux init` rather than bundled, so the download stays small.
```
crux init . # index a repo, print agent config
crux search "retry webhooks"
crux symbol RetryPolicy
crux status # what's indexed, how fresh
crux list # every workspace you've indexed
crux serve . # browse the index in a browser
crux mcp . # what your agent runs
crux upgrade # update in place
```
## Inspecting the index
`crux serve` opens a local inspector — loopback only, since the index holds
your source:
- **Graph** — the import graph, as modules or individual files, force-directed.
Hubs are highlighted; isolated files are counted rather than drawn.
- **Search** — the same three-arm search the agent gets, showing which arms matched.
- **Files** — per file: every symbol, and the chunk boundaries search actually uses.
- **Symbols** — definitions, callers, callees. Labelled heuristic until SCIP lands.
- **Inspect** — what is in the index, per-tier coverage, and storage by table.
Uninstall with `CRUX_UNINSTALL=1 bash install.sh`.
## Where it keeps things
Everything lives under `~/.crux` — **nothing is written into the repos you index**:
```
~/.crux/
├── config.json settings
├── grammars/ tree-sitter parsers, fetched on first init
└── index/
├── registry.json
└── <project>-<hash>.db
```
`crux list` shows every index and its size; `crux forget <path>` deletes one.
## Indexing many repos at once
Point it at a folder of projects and it indexes all of them into one searchable
index, applying each repo's own `.gitignore`:
```
crux init ~/code # 20 repos, 21,415 files, 106s, 588 MB
crux search "leader election heartbeat" ~/code
```
Measured on the `loop` repo (469 files, 3.9 MB of TypeScript): cold index 3.4 s at
138 files/s, 13,455 symbols, query p50 2.1 ms / p95 3.2 ms.
Built: the durable queue, leader election, tree-sitter extraction for
TS/TSX/JS/Python/Go/Rust, content-addressed storage, FTS5 + trigram, three-arm
fused search, the filesystem watcher, five MCP tools, and the CLI.
Not yet: the code graph (`refs`, `pack`), embeddings, and connectors.
---
## Why
Every "context for AI" tool today does the same thing: chunk the repo, embed it, run cosine
similarity, dump twenty chunks into the prompt. That approach cannot answer the questions
agents actually ask — "who calls this?", "what breaks if I change this signature?" — because
those are *graph* queries with no similarity signal at all.
`crux` runs five retrievers (BM25, trigram, vector, symbol table, path fuzzy), fuses them,
and then expands along the code graph. Embeddings are roughly 20% of the answer quality.
The graph is the moat.
The second half of the thesis is **freshness**. A stale index is worse than no index,
because the agent can't tell the difference. `crux` watches the filesystem, queues work
durably in SQLite, and verifies every returned span against the file on disk before
handing it to an agent.
## Read the plan
| Doc | What's in it |
|---|---|
| [00-overview](plan/00-overview.md) | Thesis, goals, non-goals, decisions already made |
| [01-architecture](plan/01-architecture.md) | Process model, leader election, why no daemon |
| [02-queue](plan/02-queue.md) | The durable job queue — schema, claiming, the hash skip rule |
| [03-watcher](plan/03-watcher.md) | Filesystem watching, event storms, git-aware shortcuts |
| [04-storage](plan/04-storage.md) | Content-addressed schema, why branch switches are free |
| [05-index-tiers](plan/05-index-tiers.md) | Lexical → tree-sitter → SCIP → vectors → git |
| [06-retrieval](plan/06-retrieval.md) | Query pipeline, fusion, graph expansion, context packing |
| [07-mcp](plan/07-mcp.md) | The eight tools and why the cap matters |
| [08-sources](plan/08-sources.md) | Connectors for docs, tickets, web |
| [09-operations](plan/09-operations.md) | Resource discipline, privacy, prompt-injection safety |
| [10-roadmap](plan/10-roadmap.md) | Phases, evaluation, risk register |
## Shape of it
```
Claude Code Cursor loop ← MCP hosts (stdio)
└──────────────┼─────────────┘
crux mcp × N ← thin readers
│
.crux/index.db ← SQLite (WAL) + durable job queue
│
one elected leader ← watcher + parse worker + embed worker
```
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues