greppy is the most token-efficient coding harness.

greppy trims searching, reading, editing, testing and web work to maximum token efficiency. Your agents get their tasks done faster, cheaper and better, with a lean context and a clear focus.

greppy runs as a plugin in Claude Code, Codex, Gemini CLI, pi and OpenCode, and ships its own harness that runs as a subagent.

The same question to the same agent: left with grep, right with greppy.

Real tasks from open-source projects

ironclaw: expose the run status to the web UI

3 of 3 runs solved instead of 1 of 347% lower cost per solved task

The agent has to build a run-status query for the web UI in ironclaw, a Rust project. With greppy it finds the right facade with its first search and sees the file as a list of its definitions, 4,810 characters. The existing check parse_thread_id_field is right there, and it uses it.

Without greppy it reads the same file in full, 29,359 characters, and still writes its own parser. That parser reports an invalid thread ID with the wrong error, and one of the project’s tests fails. With greppy all three runs solve the task, without greppy one does.

Measured with pi and glm-5.3-flash.

Without greppyWith greppy
ResultTests failTests pass
Input (new)93,11671,278−23%
Cache read2,203,3923,436,544+56%
Output24,45525,388+4%
Turns4282+95%
Time13:03 min13:16 min+2%

Without greppy

  1. ls -la /ironclaw3,532 characters
  2. find /ironclaw -maxdepth 2 -type d | head -501,394 characters
  3. grep -ri "RebornServices" /ironclaw --include="*.rs" -l | head -20445 characters
  4. grep -ri "TurnCoordinator" /ironclaw --include="*.rs" -l | head -201,246 characters
  5. ls -la /ironclaw/crates/ironclaw_product_workflow/src/ /ironclaw/crates/ironclaw_product_w1,421 characters
  6. git -C /ironclaw log --oneline -15; git -C /ironclaw status68 characters
  7. reads crates/ironclaw_product_workflow/src/reborn_services.rs29,359 characters
  8. ls -la /ironclaw/crates/ironclaw_product_workflow/src/reborn_services/ 2>/dev/null; grep -220 characters
  9. reads crates/ironclaw_product_workflow/src/reborn_services/types.rs3,329 characters
  10. reads crates/ironclaw_product_workflow/tests/reborn_services_contract.rs30,611 characters
  11. reads crates/ironclaw_product_workflow/src/webui_inbound.rs14,386 characters
  12. reads crates/ironclaw_product_workflow/src/reborn_services/error.rs1,937 characters
  13. grep -rn "TurnRunState\|GetRunStateRequest\|TurnRunFailure\|pub struct EventCursor\|RunFai4,827 characters
  14. reads crates/ironclaw_product_workflow/src/lib.rs2,467 characters
  15. grep -rn "pub struct TurnRunState" /ironclaw/crates/ironclaw_turns/src/ -A 403,397 characters
  16. grep -rn "pub struct SanitizedFailure\|pub enum SanitizedFailure" /ironclaw/crates/ironcla2,386 characters
  17. grep -rn "get_run_state\|GetRunState" /ironclaw/docs /ironclaw/FEATURE_PARITY.md /ironclaw11 characters
  18. grep -rn "RebornServices\|reborn_services" /ironclaw/crates/ironclaw_reborn_composition/sr2,659 characters
  19. grep -rn "pub struct TurnCheckpointId\|impl TurnCheckpointId\|pub struct RunProfileId\|imp11 characters
  20. reads crates/ironclaw_turns/src/status.rs4,248 characters
  21. grep -rn "TurnCheckpointId\b" /ironclaw/crates/ironclaw_turns/src/lib.rs; grep -rn "pub st252 characters
  22. grep -rn "RunProfileId\|RunProfileVersion\|TurnCheckpointId" /ironclaw/crates/ironclaw_tur84 characters
  23. reads crates/ironclaw_turns/src/ids.rs7,145 characters
  24. grep -rn "SanitizedFailure" /ironclaw/crates --include="*.rs" | grep -v "ironclaw_turns/sr2,581 characters
  25. grep -rn "failure" /ironclaw/crates/ironclaw_product_adapters/src/*.rs | head -20; ls /iro2,628 characters
  26. cargo test -p ironclaw_product_workflow --test reborn_services_contract 2>&1 | tail -201,177 characters
  27. grep -rn "impl ThreadId" /ironclaw/crates/ironclaw_host_api/src/ -A 30 | head -50; grep -r39 characters
  28. grep -rn "ThreadId" /ironclaw/crates/ironclaw_host_api/src/*.rs | grep -i "struct\|fn new"235 characters
  29. grep -rn "ThreadId" /ironclaw/crates/ironclaw_host_api/src/ids.rs | head; grep -rn "macro_1,025 characters
  30. reads crates/ironclaw_host_api/src/ids.rs3,085 characters
  31. … 25 more steps69,654 characters

With greppy

  1. greppy where-am-i3,266 characters
  2. greppy search "RebornServices facade WebUI submit cancel resolve gate run state"1,277 characters
  3. greppy read crates/ironclaw_product_workflow/src/reborn_services.rs4,810 characters
  4. greppy read crates/ironclaw_product_workflow/src/reborn_services/types.rs2,154 characters
  5. greppy read-file crates/ironclaw_product_workflow/src/reborn_services.rs --lines 1:1053,551 characters
  6. greppy read-file crates/ironclaw_product_workflow/src/reborn_services/types.rs --lines 1:13,459 characters
  7. greppy read-file crates/ironclaw_product_workflow/src/reborn_services.rs --lines 105:47015,009 characters
  8. greppy read-file crates/ironclaw_product_workflow/src/reborn_services.rs --lines 470:76010,736 characters
  9. greppy search "RunState run state snapshot status event cursor gate failure checkpoint" --145 characters
  10. greppy read-file crates/ironclaw_turns/src/status.rs --lines 200:3404,974 characters
  11. greppy search-symbol GetRunStateRequest68 characters
  12. greppy read-file crates/ironclaw_turns/src/request.rs --lines 1:1201,597 characters
  13. greppy read crates/ironclaw_product_workflow/tests/reborn_services_contract.rs --head 2009,445 characters
  14. greppy read-file crates/ironclaw_product_workflow/tests/reborn_services_contract.rs --line7,144 characters
  15. greppy read crates/ironclaw_product_workflow/src/webui_inbound.rs::WebUiResolveGateRequest940 characters
  16. greppy read crates/ironclaw_product_workflow/src/webui_inbound.rs4,696 characters
  17. greppy read-file crates/ironclaw_product_workflow/src/webui_inbound.rs --lines 65:43012,382 characters
  18. greppy read crates/ironclaw_product_workflow/src/reborn_services/error.rs1,490 characters
  19. greppy search "SanitizedFailure failure category sanitized"1,015 characters
  20. greppy read-file crates/ironclaw_turns/src/status.rs --lines 1:2005,750 characters
  21. greppy read crates/ironclaw_product_workflow/src/reborn_services/error.rs::Class::RebornSe562 characters
  22. greppy read-file crates/ironclaw_product_workflow/tests/reborn_services_contract.rs --line2,706 characters
  23. greppy read-file crates/ironclaw_product_workflow/tests/reborn_services_contract.rs --line1,909 characters
  24. greppy search-pattern "pub use|pub mod" crates/ironclaw_product_workflow/src/lib.rs551 characters
  25. greppy read crates/ironclaw_turns/src/events.rs::EventCursor205 characters
  26. greppy read-file crates/ironclaw_product_workflow/src/lib.rs --lines 25:701,550 characters
  27. greppy read crates/ironclaw_turns/src/run_profile.rs::RunProfileId && greppy read crates/i221 characters
  28. greppy search-symbol RunProfileId && greppy search-symbol RunProfileVersion && greppy sear496 characters
  29. greppy search-pattern "struct RunProfileId|struct RunProfileVersion|struct AcceptedMessage600 characters
  30. greppy rg -n "pub struct RunProfileId|pub struct RunProfileVersion|pub struct AcceptedMess736 characters
  31. … 68 more steps61,767 characters

ruff: fix a contradiction between two lint rules

36% lower cost for fixing the bug

The agent has to fix a contradiction between two rules in ruff, the Python linter written in Rust. With greppy it finds the responsible rule in one call, 100 characters, and then reads exactly the functions it needs, such as comment_contains_code with 1,681 characters.

Without greppy it reads the files involved in full, detection.rs, suppression.rs and noqa.rs, 118,799 characters together. Both runs pass the project’s tests, with greppy for $0.15 instead of $0.24.

Measured with pi and glm-5.3-flash.

Without greppyWith greppy
ResultTests passTests pass
Input (new)108,99485,162−22%
Cache read6,548,5443,987,008−39%
Output50,52539,967−21%
Turns9578−18%
Time23:55 min26:02 min+9%

Without greppy

  1. ls /ruff && git -C /ruff log --oneline -3356 characters
  2. find /ruff/crates/ruff_linter/src -name "*.rs" | xargs grep -ln "commented_out_code"179 characters
  3. reads crates/ruff_linter/src/rules/eradicate/rules/commented_out_code.rs6,408 characters
  4. reads crates/ruff_linter/src/checkers/tokens.rs5,226 characters
  5. ls /ruff/crates/ruff_linter/src/rules/eradicate/36 characters
  6. reads crates/ruff_linter/src/rules/eradicate/detection.rs16,270 characters
  7. ls /ruff/crates/ruff_linter/src/rules/ruff/rules/ | head -501,378 characters
  8. reads crates/ruff_linter/src/rules/ruff/rules/unused_noqa.rs4,308 characters
  9. grep -rn "UnusedCodes\|unused_noqa\|UnusedNOQA" /ruff/crates/ruff_linter/src --include="*.2,132 characters
  10. grep -rn "CommentedOutCode" /ruff/crates/ruff_linter/src --include="*.rs" | grep -v snapsh900 characters
  11. reads crates/ruff_linter/src/suppression.rs51,254 characters
  12. reads crates/ruff_linter/src/noqa.rs51,275 characters
  13. grep -rn "find_line_with_directive_mut\|find_line_with_directive\|directive.used\|used:" /50 characters
  14. grep -rn "find_line_with_directive_mut\|RUF100\|unused_noqa\|UnusedNOQA" /ruff/crates/ruff39 characters
  15. grep -rn "NoqaDirectives" /ruff/crates/ruff_linter/src --include="*.rs" | grep -v "noqa.rs461 characters
  16. grep -rn "NoqaMapping\|NoqaDirectives\|check_noqa\|mark_used\|set_used" /ruff/crates/ruff_654 characters
  17. grep -rn "check_suppressions\|Suppressions" /ruff/crates/ruff_linter/src --include="*.rs" 1,912 characters
  18. ls /ruff/crates/ruff_linter/src/checkers/;89 characters
  19. reads crates/ruff_linter/src/checkers/noqa.rs11,125 characters
  20. ls /ruff/crates/ruff_linter/resources/test/fixtures/eradicate/ && head -100 /ruff/crates/r1,511 characters
  21. grep -rn "noqa" /ruff/crates/ruff_linter/resources/test/fixtures/eradicate/ERA001.py | hea90 characters
  22. reads crates/ruff_linter/src/rules/ruff/mod.rs5,684 characters
  23. grep -n "fn line_str\|fn line_range\|fn full_line_range\|fn full_lines_range\|fn line_star1,470 characters
  24. cat -A /ruff/crates/ruff_linter/resources/test/fixtures/ruff/RUF100_5.py472 characters
  25. ls /ruff/crates/ruff_linter/src/rules/ruff/snapshots/ | grep -i ruf100336 characters
  26. cat /ruff/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf2,149 characters
  27. ls /ruff/target/debug/ruff 2>/dev/null && /ruff/target/debug/ruff --version; ls /ruff/targ11 characters
  28. ls /ruff/target 2>/dev/null; cargo --version; rustc --version72 characters
  29. cargo build -p ruff --bin ruff 2>&1 | tail -5317 characters
  30. mkdir -p /tmp/repro && cd /tmp/repro && printf '#\t)\n#\t) # noqa: ERA001\n' > repro.py &464 characters
  31. … 79 more steps70,645 characters

With greppy

  1. greppy search-symbol commented_out_code100 characters
  2. greppy search "detect commented-out code eradication"1,160 characters
  3. greppy read commented_out_code.rs::commented_out_code606 characters
  4. greppy read crates/ruff_linter/src/rules/eradicate/detection.rs --lines 1:135228 characters
  5. greppy read crates/ruff_linter/src/rules/eradicate/rules/commented_out_code.rs::Function::1,125 characters
  6. greppy read crates/ruff_linter/src/rules/eradicate/detection.rs --head 1402,174 characters
  7. greppy read crates/ruff_linter/src/rules/eradicate/detection.rs::Function::comment_contain1,681 characters
  8. greppy read-file crates/ruff_linter/src/rules/eradicate/detection.rs --lines 1:1354,113 characters
  9. greppy read crates/ruff_linter/src/rules/eradicate/rules/commented_out_code.rs::Function::730 characters
  10. greppy who-calls comment_contains_code1,062 characters
  11. greppy read-file crates/ruff_linter/src/rules/eradicate/rules/commented_out_code.rs --line3,164 characters
  12. greppy search "parse an inline noqa directive from a comment"1,027 characters
  13. greppy search-symbol parse_inline_noqa512 characters
  14. greppy read crates/ruff_linter/src/suppression.rs::parse_suppression_comment664 characters
  15. greppy read crates/ruff_linter/src/noqa.rs::lex_inline_noqa429 characters
  16. greppy search "a suppression comment with pragma kind and codes" --kind struct625 characters
  17. greppy read crates/ruff_linter/src/suppression.rs --head 12012,169 characters
  18. greppy read crates/ruff_linter/src/suppression.rs::SuppressionParser::parse_comment crates1,317 characters
  19. greppy read-file crates/ruff_linter/src/suppression.rs --lines 1:1304,268 characters
  20. git log --oneline -3 2>/dev/null | cat && ls target/debug/ruff 2>/dev/null; ls target 2>/d49 characters
  21. printf '\t\t\t# \t)\n\t\t\t# \t) # noqa: ERA001\n' > repro.py && cat -A repro.py42 characters
  22. ls crates/ruff_linter/resources/test/fixtures/eradicate/ && greppy search-symbol commented169 characters
  23. greppy search "test ERA001 rule over a fixture" --path crates/ruff_linter/src/rules/eradic1,244 characters
  24. greppy read crates/ruff_linter/src/rules/eradicate/mod.rs::rules 2>/dev/null || greppy rea510 characters
  25. cat crates/ruff_linter/resources/test/fixtures/eradicate/ERA001.py1,746 characters
  26. ls crates/ruff_linter/resources/test/fixtures/eradicate/snapshots/ 2>/dev/null || find cra109 characters
  27. cat crates/ruff_linter/src/rules/eradicate/snapshots/ruff_linter__rules__eradicate__tests_7,527 characters
  28. greppy read crates/ruff_linter/src/suppression.rs::SuppressionParser::eat_action crates/ru3,203 characters
  29. greppy who-calls crates/ruff_linter/src/suppression.rs::SuppressionParser::parse_comment; 1,062 characters
  30. greppy read crates/ruff_linter/src/suppression.rs::SuppressionsBuilder::load_from_tokens8,329 characters
  31. … 69 more steps94,011 characters

ArcadeDB: fix lost samples under concurrent inserts

28% lower cost for fixing the bug

The agent has to fix data loss in ArcadeDB, a database written in Java: with many concurrent inserts into a time series, samples get lost. With greppy it describes the place it is looking for in one sentence, lands on the method that appends samples to a shard, and then reads single methods of the transaction logic such as commit1stPhase.

Without greppy it reads the classes involved in full, TimeSeriesShard, TimeSeriesBucket and TransactionContext, 109,095 characters together. Both runs pass the project’s tests, with greppy for $0.36 instead of $0.50.

Measured with pi and glm-5.3-flash.

Without greppyWith greppy
ResultTests passTests pass
Input (new)160,153250,396+56%
Cache read14,644,2249,934,336−32%
Output69,72546,779−33%
Turns169136−20%
Time40:00 min40:00 min+0%

Without greppy

  1. ls /arcadedb && cat /arcadedb/pom.xml | head -502,313 characters
  2. find /arcadedb -type d -name "*timeseries*" -o -type d -name "*timeSeries*" -o -type d -na124 characters
  3. find /arcadedb/engine/src/main/java/com/arcadedb/engine/timeseries -type f -name "*.java" 2,574 characters
  4. ls /arcadedb/engine/src/test/java/com/arcadedb/engine/timeseries/ && cat /arcadedb/CLAUDE.6,116 characters
  5. grep -n "Disabled" /arcadedb/engine/src/test/java/com/arcadedb/engine/timeseries/TimeSerie439 characters
  6. reads engine/src/test/java/com/arcadedb/engine/timeseries/TimeSeriesConcurrentInsertTest.j4,077 characters
  7. reads engine/src/main/java/com/arcadedb/engine/timeseries/TimeSeriesBucket.java29,867 characters
  8. reads engine/src/main/java/com/arcadedb/engine/timeseries/TimeSeriesShard.java42,347 characters
  9. find /arcadedb/engine/src/main/java -name "TransactionContext.java" -o -name "TransactionM307 characters
  10. reads engine/src/main/java/com/arcadedb/database/TransactionContext.java36,881 characters
  11. grep -rn "class TransactionManager" /arcadedb/engine/src/main/java/com/arcadedb/engine/Tra265 characters
  12. grep -rn "txContexts\|getTransaction()\|begin()" /arcadedb/engine/src/main/java/com/arcade960 characters
  13. sed -n 440,560p /arcadedb/engine/src/main/java/com/arcadedb/database/LocalDatabase.java3,265 characters
  14. find /arcadedb/engine/src/main/java -name "PageManager.java" | xargs cat | sed -n 1,200p8,019 characters
  15. find /arcadedb/engine/src/main/java -name "PageManager.java" | xargs sed -n 200,420p10,166 characters
  16. find /arcadedb/engine/src/main/java -name "CachedPage.java" | xargs cat4,352 characters
  17. find /arcadedb/engine/src/main/java -name "DatabaseContext.java" | xargs cat9,064 characters
  18. grep -rn "getWrappedDatabaseInstance" /arcadedb/ha-raft/src/main/java --include="*.java" |708 characters
  19. sed -n 470,600p /arcadedb/ha-raft/src/main/java/com/arcadedb/server/ha/raft/RaftReplicated3,812 characters
  20. grep -n "class RaftReplicatedDatabase\|extends\|implements" /arcadedb/ha-raft/src/main/jav1,036 characters
  21. sed -n 108,330p /arcadedb/ha-raft/src/main/java/com/arcadedb/server/ha/raft/RaftReplicated10,672 characters
  22. git log --oneline -10 2>/dev/null; git status 2>/dev/null | head -2068 characters
  23. grep -rn "appendSamples" engine/src/main/java/com/arcadedb/engine/timeseries/TimeSeriesEng831 characters
  24. grep -rn "TimeSeries\|timeseries" --include="*.java" engine/src/main/java/com/arcadedb/que794 characters
  25. grep -n "TimeSeries\|timeSeries\|appendSamples" engine/src/main/java/com/arcadedb/query/sq790 characters
  26. reads engine/src/main/java/com/arcadedb/engine/timeseries/TimeSeriesEngine.java27,110 characters
  27. grep -n "public TransactionContext getTransaction\|getTransaction()" engine/src/main/java/2,538 characters
  28. find engine/src/main/java -name "PageManager.java" | xargs sed -n 420,530p3,843 characters
  29. mvn -q -pl engine -am compile -DskipTests 2>&1 | tail -5247 characters
  30. ls ~/.m2 2>/dev/null; which mvn; echo $MAVEN_HOME; echo $M2_HOME; ls /opt/tools 2>/dev/nul383 characters
  31. … 143 more steps117,259 characters

With greppy

  1. ls && git log --oneline -5544 characters
  2. greppy where-am-i4,269 characters
  3. greppy search-symbol TimeSeries --all --limit 60 2>&1 | head -807,238 characters
  4. greppy search "append single sample to shard with lock and nested transaction"1,172 characters
  5. greppy brief TimeSeriesShard42,171 characters
  6. greppy brief TimeSeriesBucket 2>&1 | head -502,580 characters
  7. greppy read TimeSeriesBucket::appendSamples 2>&1 | head -1201,699 characters
  8. greppy brief TransactionContext 2>&1 | head -60238 characters
  9. greppy search "nested transaction commit defers durable publish to outer transaction" --al1,522 characters
  10. greppy read engine/src/main/java/com/arcadedb/database/TransactionContext.java --lines 1:1228 characters
  11. greppy read-file engine/src/main/java/com/arcadedb/database/TransactionContext.java --line7,313 characters
  12. greppy search "begin pushes nested transaction context onto per-thread stack" --all --limi999 characters
  13. greppy search-symbol txContexts --all --limit 20467 characters
  14. greppy read LocalDatabase::begin 2>&1 | head -40668 characters
  15. greppy read-file engine/src/main/java/com/arcadedb/database/DatabaseContext.java --lines 12,489 characters
  16. greppy read LocalDatabase::commit 2>&1 | head -60649 characters
  17. greppy read TransactionContext::commit2ndPhase 2>&1 | head -802,829 characters
  18. greppy read TransactionContext::commit1stPhase 2>&1 | head -1504,655 characters
  19. greppy read RaftReplicatedDatabase::commit 2>&1 | head -1004,947 characters
  20. greppy read RaftReplicatedDatabase::commit --handle 2>&1 | tail -5; greppy read-file ha-ra2,107 characters
  21. greppy search-symbol PageManager --all --limit 201,708 characters
  22. greppy brief PageManager 2>&1 | head -803,719 characters
  23. greppy read PageManager::updatePages 2>&1 | head -701,500 characters
  24. greppy read PageManager::checkPageVersion 2>&1 | head -602,276 characters
  25. greppy read TimeSeriesBucket::getOrCreateActiveDataPage 2>&1 | head -601,968 characters
  26. greppy search "load mutable page for transaction or overwrite current page" --limit 15923 characters
  27. greppy read TransactionContext::getPageToModify 2>&1 | head -40572 characters
  28. greppy read PageManager::getPageToModify 2>&1 | head -60303 characters
  29. greppy read TransactionContext::getPageToModify --all --limit 10 2>&1 | head -20; greppy s370 characters
  30. greppy read-file engine/src/main/java/com/arcadedb/database/TransactionContext.java --line1,008 characters
  31. … 126 more steps164,010 characters

What greppy does for your agent

Your agent sees how the code fits together

Who calls this function, what depends on a change, which calls carry a request from the route to the database? greppy answers each of these questions in one call, with file and line.

See before and after →

Find code you can only describe

“Check a user’s password” leads straight to checkPassword. greppy searches for what code does and writes one sentence under every hit saying what it is for. Your agent picks the right hit before it reads a single line.

See before and after →

Understand a function before reading it

brief sums up a function in one sentence, sketches its flow step by step and names its callers. read-smart shows the shape of a long function and folds deep blocks into one line each. The agent then reads exactly the part it needs.

See before and after →

Read exactly one symbol, change exactly one symbol

greppy read returns a function, a method or a type; for a file it returns its outline. Changes are just as precise: replace a symbol, rename it everywhere, change several files in one patch. undo reverts any change in one step.

See before and after →

One test run, one verdict

bash-smart runs a build, test or linter unchanged. The first line is the verdict, followed by exactly the errors and warnings. The agent fetches the full log with one command when it needs it.

See before and after →

The browser is built in

Your agent searches the web, reads documentation, fills in forms and checks a deployment, all from the shell. Pages enter the context as a compact structure, data as targeted extracts.

See before and after →

Every agent in its own copy, instantly

greppy gives every agent a private workspace with your current state, uncommitted changes included. Many agents work on the same repository in parallel, each in its own copy. Each one delivers a commit that you review and keep.

See before and after →

Indexed once, ready in every worktree

The first checkout builds the graph and embeddings. Every further Git worktree and every agent reuses them and indexes only its own changes.

See before and after →

Hand off tasks, get commits back

greppy -p starts a coding agent with greppy as its only tool, each in its own workspace. Your main agent hands out tasks, and every subagent reports back with a result and a commit. greppy agent opens the same agent as a terminal UI.

See before and after →

One binary, everything inside

Parser, database, embedding model and language model live in one file, and the browser ships in the same package. One command installs greppy; index, graph and embeddings are built on your machine and stay there.

See before and after →

Everything your agent knows keeps working

Every grep call runs through the real grep, with identical output and the same exit codes; ripgrep calls go to rg. Your agent keeps its familiar commands and gains greppy’s tools.

See before and after →

Over 60 languages, one set of commands

The same commands for every language in the repository. Rust, Python, Java, JavaScript, TypeScript, Go, C++, C#, Kotlin, Swift and Ruby have a fully tested graph.

See before and after →

Two ways, one package

As a plugin in your harness

One command installs greppy and adds it to Claude Code, Codex, Gemini CLI, pi and OpenCode. From then on your agent searches, reads and tests through greppy and keeps everything else as it is.

curl -fsSL https://greppy.xyz/install.sh | sh

As its own harness for subagents

greppy -p starts an agent with exactly one tool in its own copy-on-write workspace. Many run in parallel, share index and models, and report back with a one-line result and a commit.

The agent needs a model gateway.

greppy -p "Users can follow themselves. Fix that."

115 questions about the codebase, four models

up to 50
percentage points more correct answers
up to 80%
lower cost to reach the grep agent’s best quality
Read the paper (PDF)
Correct answers over cost per 1,000 tasks for four models: the agent with greppy leads with every model.

Install

$curl -fsSL https://greppy.xyz/install.sh | sh

macOS (Apple Silicon) and Linux (x86-64). One binary.

All options