$npx -y skills add unbrowse-ai/unbrowse --skill skillThe action engine of the internet. Unbrowse is the open-source action layer for AI agents: it learns a site's internal API routes from real browsing, then replays them as fast, cheap, indexed routes (cache hit under 200ms) instead of re-driving a browser. Capture once, replay eve
| 1 | # Unbrowse |
| 2 | |
| 3 | Unbrowse is the action engine of the internet: the open-source action layer that turns |
| 4 | websites into reusable, indexed API routes for agents. Teach a route once by browsing, |
| 5 | store sanitized route metadata, replay it on later calls. A replay is about |
| 6 | 30x faster and 90x cheaper than a fresh browser session (peer-reviewed: 3.6x mean speedup, |
| 7 | 5.4x median over Playwright across 94 live domains, 18 domains under 100ms; |
| 8 | [Internal APIs Are All You Need](https://unbrowse.ai/whitepaper)). |
| 9 | |
| 10 | ## CLI quick paths (read `unbrowse --help` once, then stop) |
| 11 | |
| 12 | The shipped CLI uses **flat top-level commands**. Do not prefix with `build` / `act` / `eval` / `act` — those legacy verb forms are not the primary surface. |
| 13 | |
| 14 | | You want | Command | |
| 15 | |---|---| |
| 16 | | One internet result (default) | `unbrowse "task" --url <url>` or `unbrowse get "task" --url <url>` | |
| 17 | | A URL's contents | `unbrowse fetch <url>` | |
| 18 | | Route/debug details | `unbrowse resolve --intent "..." --url "..."` | |
| 19 | | Pick a specific endpoint | `unbrowse resolve ... --no-execute` then `unbrowse execute --skill ID --endpoint ID` | |
| 20 | | Real DOM (forms, clicks) | `unbrowse go <url>` → `snap` / `click` / `fill` / `submit` → `close` | |
| 21 | | First visit / miss | `unbrowse capture --url <url> --intent "..."` | |
| 22 | | Login once | `unbrowse auth <login_url>` | |
| 23 | | Bootstrap on install | `unbrowse setup` | |
| 24 | | Health check | `unbrowse health` | |
| 25 | |
| 26 | Browser-backed commands (`fetch`, `go`, `capture`, `auth`) need Chrome/Chromium installed. If `fetch` fails with a kuri/Chrome error, use `unbrowse get "task" --url <url>` (HTTP-first resolve path) or install Chrome and re-run `unbrowse setup`. |
| 27 | |
| 28 | ## The flow (load-bearing): ONE call by default. Resolve+execute for control. One capture on a miss. |
| 29 | |
| 30 | For almost every read/search task ("find/get/list X on a site"), the FASTEST path is ONE |
| 31 | call. Let the runtime resolve the route, fill the holes, escalate if needed, and return the |
| 32 | structured result. Do NOT hand-run resolve, then fetch, then parse the page yourself. |
| 33 | |
| 34 | unbrowse "<what you want>" --url "<site>" # bare natural-language: the one-hole front door |
| 35 | unbrowse get "<what you want>" --url "<site>" # identical, explicit form |
| 36 | |
| 37 | Worked example, "homemade food on Carousell" (ONE call returns priced listings): |
| 38 | |
| 39 | unbrowse "homemade food listings with prices and links" --url "https://www.carousell.sg/homemade-food/q/" |
| 40 | |
| 41 | That single call runs resolve -> execute (or a direct fetch / one capture on a miss) and |
| 42 | returns the data. A real session that instead did `resolve` (8s, zero results on an |
| 43 | unindexed site) then hand-fetched and hand-parsed the page burned 1m41s for what one call |
| 44 | does. If you are writing a loop over URLs or piping fetch output through grep/python, stop: |
| 45 | you skipped the one-call path. |
| 46 | |
| 47 | When you must PICK a specific endpoint (several routes, a mutation, explicit params), use the |
| 48 | two-call explicit path: |
| 49 | |
| 50 | 1. `unbrowse resolve --intent "<what you want>" --url "<site>" --no-execute` -> ranked shortlist. |
| 51 | 2. `unbrowse execute --skill <id> --endpoint <id> [-p key=val ...]` -> replay it. |
| 52 | |
| 53 | On a genuine MISS (no indexed route, a first visit, an anti-bot site), do ONE escalation: |
| 54 | |
| 55 | unbrowse capture --url "<site>" --intent "<what you want>" |
| 56 | |
| 57 | That drives the browser once and INDEXES the route. First visit to an uncached site pays a |
| 58 | capture tax (seconds); every visit after is a route-cache hit (<200ms). `resolve` on an |
| 59 | uncached site WILL miss (count 0) - that is expected; escalate with one capture, never a |
| 60 | fetch loop. The manual steps (`go`, `snap`, `click`, `sync`) exist, but prefer the single `capture`. |
| 61 | |
| 62 | ### STOP rules: this is exactly where agents waste minutes |
| 63 | |
| 64 | - Do NOT `curl`, `WebFetch`, or `fetch` in a loop, or scrape pages by hand. Use the one-call |
| 65 | `unbrowse "task" --url`, or resolve + execute, or one capture. If you are writing a loop over |
| 66 | URLs or piping fetch output through grep/python, you are flailing: stop. |
| 67 | - Do NOT probe ports (`curl localhost:6969`), run `mcp serve`, or babysit a daemon. The CLI |
| 68 | runs in-process. |