Your agent should read the code that is there, not the code it imagines.
yoyo is a local MCP server for codebase reading and change work. It is built for agents first, so they start from repo truth instead of model memory.
The core product is not a bag of search tricks. It is a smaller and more reliable interface to the codebase:
judge_change for ownership and invariants, inspect for cheap structured reads,
change for guarded writes, and retry_plan for bounded repair loops after failed edits.
Shoutout to xagi.in, the first sponsor of yoyo.
inspect
Why this exists
Coding agents are strong at local editing and weak at repository truth. They guess ownership layers, invent paths, over-read source files, and lose the actual invariants of the system. That is tolerable for toy projects and dangerous for real ones.
yoyo narrows that gap. It gives the agent a grounded index, a judgment surface before edits, a cheaper read surface for signatures and types, and a structured write path when a direct file mutation is the wrong tool.
boot
index
inspect
judge_change
impact
change
How it works
boot and index first. yoyo returns the tool surface and builds the repository index.
judge_change answers where a fix should live, what must remain true, and what the likely regression risks are.
inspect can return signatures, type surfaces, file structure, or exact excerpts. Rust and Go signatures are now indexed structurally.
change routes edits, renames, moves, creates, and deletes through a structured path and reindexes after the write.
What makes writes safer
The new write-side ideas are simple but important. A guarded write means yoyo does not just save the edit and hope. It writes the candidate change, runs the relevant checks, and restores the original file if the new version fails.
A runtime guard matters for interpreted languages because parsing is not enough. Python can parse and still fail with a missing name. JavaScript can parse and still fail when a module loads. Clojure can parse and still fail when a namespace resolves. yoyo treats those runtime failures as part of the same edit loop.
change
guard_failure
retry_plan
def greet():
return missing_name
That file is valid syntax. A parser alone misses the failure. A runtime guard rejects the edit, restores the previous file, and gives the next repair attempt structured context instead of vague stderr.
Current status
Headline WIP result: in one clean directed ripgrep read_only eval, Codex used yoyo for 22/22 tool calls.
That run asked three explicit engineer questions: find the 3 most likely files or symbols, decide which layer should own the fix, and state the invariants and blast radius.
yoyo localized the bug to hiargs.rs, walk.rs, and gitignore.rs, placed ownership in crates/ignore, and surfaced the key invariants and regression risks without making edits.
Write-side WIP result: yoyo is strongest when read judgment narrows the surface first, then change executes the write cleanly. The first clean directed write_only batch now shows that on ripgrep, uuid, and httprouter. semver is tracked separately: the patch in src/eval.rs is correct and passes manual cargo test, but the fixture's exact verify command, cargo test --test *, is malformed and still needs fixing before strict scoring.
This is groundedness and directed tool-use evidence, not yet a broad with-vs-without benchmark. The old 119/120 number is still a legacy regression report, and the current compare smoke runs are still 6/6 ties across v1.8.5 and v1.7.3.
Detailed artifacts live in the repository under evals/results/, including a separate semver write note.
Install
One binary. Add it as MCP. Bake the project once.
brew tap avirajkhare00/yoyo brew install yoyo codex mcp add yoyo -- /usr/local/bin/yoyo --mcp-server yoyo index --path /path/to/project
Full setup, agent config, and tool reference live in docs/README.md.