give grep, tree-sitter, and cat a shared brain.
tilth reads code the way an agent needs it: small files whole, large files as a structural outline, and every search resolved to where a symbol is defined — not just where the text appears. structural awareness in one call, not six.
cargo install tilth · npx tilth · Rust, zero runtime deps · MIT
an agent makes six calls to find one function.
glob → read → “too big” → grep → read again → read another file. each round-trip burns tokens and inference time — to answer a question the file’s own structure already knew.
built-in tools answer in fragments
grep finds where a string appears, not where a symbol is defined. cat returns a whole file when you needed eight lines — or overflows the context window, so the agent re-greps and re-reads. structure is rediscovered on every call.
structure, resolved in one call
the outline says what is in the file. search says where things are defined, with each hit shown in its surrounding structure. --section returns exactly the lines you asked for. one call, already structured.
−40% cost per correct answer.
code-navigation tasks across four real-world repositories — Express, FastAPI, Gin, ripgrep. baseline is Claude Code’s built-in tools; tilth is those same tools plus the tilth MCP server. scored the honest way: dollars spent per correct answer, across 160 runs.
| Model | Runs | Baseline $/correct | tilth $/correct | Change | Baseline acc | tilth acc |
|---|---|---|---|---|---|---|
| Sonnet 4.6 | 86 | $0.26 | $0.15 | −44% | 84% | 94% |
| Opus 4.6 | 25 | $0.22 | $0.14 | −39% | 91% | 92% |
| Haiku 4.5 | 49 | $0.12 | $0.08 | −38% | 54% | 73% |
| Average | 160 | $0.20 | $0.12 | −40% | 76% | 86% |
The metric is cost per correct answer — total spend divided by correct answers, the expected cost under retry. It is the same yardstick copeca applies across the garden: lower means it is cheaper to be right. Every model also finished in fewer turns — 25% fewer on average. Figures measured on v0.5.0. Full methodology →
it shows you the shape first.
tree-sitter parses the file into an abstract syntax tree, so tilth knows the difference between a definition and a mention. what it returns is decided by tokens, not lines — a 1-line minified bundle gets outlined; a 120-line focused module prints whole.
Read a file. Under ~6k tokens it comes back whole with line numbers; over, you get a structural outline with line ranges for every symbol.
--section 44-89 returns exactly those lines. --section "## Install" returns exactly that markdown heading. No re-reading the whole file.
Definitions first, then usages — structurally, not by string match. Each hit is shown inside its surrounding file structure, so you know what you found.
An expanded definition carries a ── calls ── footer of resolved callees, with file and line. Follow the call chain without a fresh search for each one.
it decides what to show
| input | behaviour |
|---|---|
| empty / binary | [empty] / [skipped] with mime |
| generated (lockfile, .min.js) | [generated] |
| < ~6k tokens | full content, line-numbered |
| > ~6k tokens | structural outline with ranges |
it remembers what the agent saw
Definitions already expanded once come back as [shown earlier] on later searches, instead of repeating the whole body — so revisiting a symbol costs almost nothing in tokens. expand defaults to 2; no flag to remember.
Install with --edit and tilth adds hash-anchored writing: each line carries a hash, and an edit is rejected if the file changed since you read it. No blind overwrite.
read, search, and navigate — structurally.
The same engine behind the CLI is exposed as MCP tools, so an agent reaches for the right one without a wall of upfront instructions.
Definition-first search. Multi-symbol in one call — "ServeHTTP, Next" — each with its own block. --expand inlines source for the top matches.
Every call site of a symbol, matched structurally with tree-sitter — not a text grep that trips on comments and strings.
Blast radius: what a file imports, and what depends on it — with the symbols each dependent uses. Read it before you rename an export.
Everything about one symbol in a single call: signature, doc, callers, callees, siblings, tests. The whole neighbourhood at once.
Function-level structural diff — which symbols changed, added, or had their signature altered. Replaces git diff for an agent.
Content and glob search on ripgrep’s own engine, with early termination — roughly constant time whether the tree is 30 files or 1,000.
fast enough to sit in the loop.
tilth is one binary with nothing to install behind it. Search runs definitions and usages in parallel; reads are memory-mapped; the codebase walk uses SIMD pre-filtering to skip files quickly.
AST-aware, via tree-sitter
Definition detection, callee extraction, callers, and outlines — all structural, across:
it does not slow down with the repo
| operation | ~30 | ~1000 |
|---|---|---|
| file read + detect | ~18ms | ~18ms |
| symbol search | ~27ms | ~27ms |
| codebase map | ~21ms | ~240ms |
Search, content, and glob use early termination. MCP mode pays the ~17ms startup once.
ripgrep’s engine, tree-sitter’s parser
Content search runs on ripgrep’s own grep-regex and grep-searcher; the directory walk on the ignore crate; reads through memmap2; the outline cache on DashMap, invalidated by mtime. No reinvented wheels.
it installs where your agent already lives.
One command wires tilth into a host’s MCP config. A host you do not use is simply one you never run.
Smaller models sometimes prefer their built-in tools — run with --disallowedTools "Bash,Grep,Glob" to make tilth the only way through. Or call the CLI straight from bash; the agent prompt lives in AGENTS.md.
is tilth for you?
tilth earns its place when something reads code often and pays for every token — which is most agents, and plenty of humans. So:
reach for tilth when — a fit
- an AI agent navigates your code and the token bill shows it
- the repo is large, unfamiliar, or spans several languages
- you want definitions and call chains, not string matches
- you measure a tool by its cost per correct answer
less to gain when — maybe not
- it’s one small script you already hold in your head
- nothing automated ever reads the code — only you, occasionally
- your language isn’t among the sixteen tree-sitter grammars
install it, point an agent at it.
install
cargo install tilth
also: npx tilth · prebuilt binaries on the releases page
read, search, navigate
where tilth is
tilth is the state of soil that’s ready for planting. Your codebase is the soil; tilth gives it structure, so you can find where to dig. Follow along on GitHub →