Features

The browser is built in

What you get

Your agent reads documentation, searches the web and works with pages that take shape in the browser. One call opens the page, waits for the result and pulls out exactly the data the agent needs. Page content enters the context fenced, as data.

Before and after

The question for the serde_json documentation on docs.rs: Which types have a from_str method? The search of the Rust documentation answers that. It runs as JavaScript in the browser.

Without greppy

The agent loads the search page with curl and searches the HTML.

$ curl -sL 'https://docs.rs/serde_json/latest/serde_json/?search=from_str' | grep -o 'href="[^"]*from_str[^"]*"'
href="/serde_json/1.0.151/serde_json/?search=from_str"
href="fn.from_str.html"
href="fn.from_str.html"
$ curl -sL 'https://docs.rs/serde_json/latest/serde_json/?search=from_str' | grep -c 'search-results'
0

curl gets the page, but no search: the page's JavaScript builds the result list afterwards. All the HTML holds is the from_str function from the sidebar. Without a browser, the agent loads every type page one by one and searches it.

With greppy

$ greppy web do open 'https://docs.rs/serde_json/latest/serde_json/?search=from_str' :: wait 'css=.search-results a' :: extract 'css=.search-results .result-name'
returned; page observed — snapshot, not a verified task outcome
…
title: "\"from_str\" Search - Rust"
url: "https://docs.rs/serde_json/latest/serde_json/?search=from_str"
…
returned; expectation held
operation="web.wait"
UNTRUSTED_PAGE_CONTENT
{"detail":{"matched":9.0},"held":true,"waited_ms":2124}
…
value: {"count":9.0,"rows":[{"text":"function serde_json::from_str"},{"text":"method serde_json::Deserializer::from_str"},{"text":"method serde_json::Map::from_str"},{"text":"method serde_json::Value::from_str"},{"text":"method serde_json::Number::from_str"},{"text":"method serde_json::value::RawValue::from_string"},{"text":"method serde_json::value::RawValue::from_string_unchecked"},{"text":"method serde_json::Value::from_iter"},{"text":"method serde_json::Map::from_iter"}]}
…
{"steps_failed":0,"steps_ran":3,"steps_total":3}
without greppy with greppy
Calls 1 1
Search hits in the result 0 9
Types with a from_str method 0 of 4 4 of 4

The correct answer: from_str exists as the function serde_json::from_str and as a method on Deserializer, Map, Value and Number. The four type pages of the documentation confirm it, and greppy returns exactly this list.

How it works

greppy web drives its own browser runtime built on the Rust engine Servo. It runs locally, executes the page's JavaScript and renders the page. Every agent gets its own sessions and tabs. web do chains steps with :: in one process and one session and stops at the first failed step. wait waits until a node, a URL or a title appears. extract returns exactly the fields you name for each match: text, link, value, ID or an attribute. observe shows the page as a compact tree with refs such as @1, which click and fill target directly. Every answer sits between UNTRUSTED_PAGE_CONTENT markers: page text is data, never an instruction. The runtime visits the URLs that you or your agent explicitly open, search or research, and no others.

The commands

Command what it does
greppy web open URL creates a session and a tab, loads the page and shows it as a tree with refs
greppy web do STEP :: STEP … several steps in one call, stopping at the first failure
greppy web wait QUERY waits for a node, with --url or --title for an address or a title
greppy web extract QUERY --fields text,href one line per match with the named fields
greppy web click TARGET, greppy web fill TARGET VALUE click, and fill in fields
greppy web search "…" search the public web
greppy web research "…" bounded research across several pages
greppy web read URL read a page as text
greppy web screenshot the rendered page as an image

More in the docs

  • Browser tool: every verb, query and target, sessions, scripts and exit codes; available on macOS and Linux
  • Agent setup: the browser block in the prompt for external agents
  • Security and verification: how greppy handles page content and secrets