
kuri v0.4.14
Browser automation, web crawling, and iOS + Android device control for AI agents. Zig-native, token-efficient CDP snapshots, HAR recording, native adb wire-protocol client, and a standalone fetcher.
Kuri 🌰
Install
curl -fsSL https://kuri.trilok.ai/download | sh
macOS arm64/x86_64 and Linux x86_64/arm64. Single binary, no runtime deps.
Direct downloads: macOS arm64 · macOS x86_64 · Linux x86_64 · Linux arm64
Browser automation & web crawling for AI agents. Written in Zig. Zero Node.js.
CDP automation · A11y snapshots · HAR recording · Standalone fetcher · Interactive terminal browser · Agentic CLI · Security testing · iOS + Android device control
Quick Start · Benchmarks · kuri-agent · Security Testing · API · Skills · Changelog
Why teams switch to Kuri: current Apple Silicon
ReleaseFastbuilds stay sub-2 MB per binary, and a fresh Google Flights rerun on 2026-04-23 measured 3,392 tokens for a fullkuri-agentloop (go→snap→click→snap→eval). Cross-tool deltas should be rerun in the same environment before quoting a percentage.
Why Kuri Wins for Agents
Most browser tooling was built for QA engineers. Kuri is built for agent loops: read the page, keep token cost low, act on stable refs, and move on.
- 135 HTTP endpoints — full parity with agent-browser and browser-use, from React inspection to Core Web Vitals.
- 7-12% fewer tokens than agent-browser on real pages thanks to
@eNref format and zero-prefix rendering. - 44x lighter observations with
/page/state(48 tokens) vs full snapshot (2,124 tokens) for the same Google Flights page. - Batch execution —
POST /batchsends N commands in one HTTP call, eliminating N-1 round-trips and N-1 LLM turns. - React-compatible — trusted CDP mouse events and per-character key events fire React 18/19
onClickandonChange.
Snapshot tokens: Google Flights SIN → TPE
Fresh rerun on 2026-05-24 in this workspace, measured with wc -c and chars/4 approximation.
| Tool / Mode | Chars | ~Tokens | Note |
|---|---|---|---|
kuri snap (full) | 8,499 | 2,124 | All nodes + interactive refs |
kuri snap (interactive only) | ~3,000 | ~750 | Best for agent loops |
kuri /page/state | 190 | 48 | Lightweight observation (url, title, scroll%, counts) |
| agent-browser snap (estimated) | ~9,183 | ~2,295 | [ref=e0] format overhead |
Token efficiency: kuri vs agent-browser
| Page | kuri tokens | agent-browser tokens | Savings |
|---|---|---|---|
| example.com | 40 | 35 | -13% (trivial page, agent-browser skips root) |
| Hacker News | 386 | ~440 | 12% fewer |
| Google Flights SIN→TPE | 2,124 | ~2,295 | 7% fewer |
The savings come from kuri's compact format:
@e0refs (3 chars) vs[ref=e0](9 chars)- No
-prefix per line (saves 2 chars × line count) - Same indentation, same node filtering
Full workflow cost: go → snap → click → snap → eval
| Tool | Tokens per cycle |
|---|---|
| kuri-agent | ~3,400 |
With /page/state instead of second snap | ~1,700 |
With POST /batch (all in one call) | ~1,700 (same tokens, 1 HTTP call instead of 5) |
kuri vs libretto
libretto (Playwright + Node) is the closest competitor on per-step token cost. Measured head-to-head on 2026-07-04 — same Chrome, same tab, real tiktoken o200k_base counts (full methodology and reproduction: benchmarks/libretto_comparison.md). The honest split:
| Axis | Winner | Detail |
|---|---|---|
| Latency per call | kuri | 4–117 ms vs 1,344–1,500 ms (13–376× faster — persistent server vs Node-per-command) |
| Snapshot tokens, typical page | kuri | simple 61 vs 151 (2.5×), article 265 vs 363 (1.37×) — tighter grammar |
| Snapshot tokens, large list | split | kuri default 4,424 vs 813 — kuri emits all 259 refs, libretto truncates by default. With limit=5 kuri renders 555 tokens (1.46× under libretto), 34 refs + … +45 more markers |
| Trajectory (feed, 9 clicks) | kuri, barely | 898 vs 939 tokens (limit=5 base + diff loop vs exec loop) — parity-to-slight-edge; the morning's 5.1× loss was the untruncated base |
| Repeat runs | libretto | compiles trajectories to a Playwright script → 0-token replays; kuri re-pays the loop every run |
What kuri gained from studying libretto (all shipped this release): a diff-first loop (take_snapshot_diff, ~38 tokens/step); an adaptive diff that falls back to a full snapshot with a ! page replaced header on navigation; identity-only removal lines; screenshots written to disk (path returned, bytes never enter context); get_page_state over MCP; and — after rewriting parseA11yNodes as a real DFS tree walk — opt-in list truncation (/snapshot?limit=N, one … +K more line per capped run), scoped re-capture (scope=@ref), and hierarchy indentation, also exposed as uid/limit on MCP take_snapshot. The 9-click feed trajectory that cost 44,285 tokens with naive full re-snapshots costs 898 with a truncated base + diffs — 49× cheaper, and past libretto's 939.
The older tables above use a
chars/4token approximation; the libretto comparison uses realtiktokencounts. Rerun cross-tool numbers in your own environment before quoting a percentage.
Binary size and memory
Measured on Apple M4 Pro, macOS 26.4.1. Current binaries were built with -Doptimize=ReleaseFast.
| Binary | Current size |
|---|---|
kuri | 1,093,840 B (1.04 MiB) |
kuri-agent | 629,904 B (615 KiB) |
kuri-browse | 1,089,120 B (1.04 MiB) |
kuri-fetch | 2,063,488 B (1.97 MiB) |
RSS stayed flat across the Zig 0.16 migration
Measured against the current v0.4.3 ReleaseFast build with /usr/bin/time -l.
| Command | v0.4.3 mean max RSS |
|---|---|
kuri-fetch --version | ~2.45 MiB |
kuri-browse --version | ~2.45 MiB |
kuri-fetch --quiet --dump markdown http://example.com/ | ~9.17 MiB |
The Problem
Every browser automation tool drags in Playwright (~300 MB), a Node.js runtime, and a cascade of npm dependencies. Your AI agent just wants to read a page, click a button, and move on. Kuri is a single Zig binary. Four modes, zero runtime:
kuri → CDP server (Chrome automation, a11y snapshots, HAR)
kuri-fetch → standalone fetcher (no Chrome, QuickJS for JS, ~2 MB)
kuri-browse → interactive terminal browser (navigate, follow links, search)
kuri-agent → agentic CLI (scriptable Chrome automation + security testing)
📦 Installation
One-line install (macOS / Linux)
curl -fsSL https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/install.sh | sh