Kuri
A single-binary Zig toolkit for browser automation, web crawling, and iOS/Android device control, purpose-built for token-efficient AI agent loops.
CI explicitly verifies 401 on unauthenticated requests, auto-generated tokens at ~/.kuri/api.token, and Keychain storage on macOS — access control is taken seriously. Deducted: README says KURI_SECRET auth is 'optional', which is in tension with the enforced-token path CI tests; static evidence cannot confirm the default. High-risk endpoints (/auth/extract, /cookies/set, /dialog/auto, arbitrary /evaluate) have no confirmation or tiering, so user_confirmation gets 1.
CI includes regression gates (issue #156: --help must not spawn Chrome), startup smoke, and Windows cross-compile verification, with comments candidly recording past defects (install.sh drifted four releases, silent --device no-op). Deducted: README states Zig 0.16.0 while CI installs a 0.17.0-dev pre-release toolchain — a version-claim inconsistency.
The agent-loop audience is sharply defined (token-optimized snapshots, diff loop, batch endpoint). Capability boundaries are honest and complete: Windows stubs, experimental browser runtime, WSL2 guidance. Trigger precision relies on skill-file examples with no precise trigger specification, scoring 2.
Install docs cover four paths with SHA-256 checksums and truthful signed/unsigned disclosure; known_limitations earns full marks for candor about benchmark methodology, Windows stubs, and missing signatures. Deducted: marketing framing ('Why Kuri Wins') is mixed with facts; repo metadata says NOASSERTION while the in-repo file is SSPL with an exception; maintenance rests on a single author.
Uniform JSON output, compact snapshot format, and screenshots written to disk rather than context give high output usability (3). Marginal-value claims (7-12% token savings, 13-376x latency) have methodology links but are self-measured only. Cost-benefit is honest — the readme admits a past 5.1x loss from untruncated lists — but the tradeoff is not fully resolved.
Benchmarks include methodology links and explicitly ask readers to re-measure; the tiktoken vs chars/4 distinction is clear. Deducted: all performance figures are self-measured in one author environment with no independent corroboration (cross_source_corroboration = 1). The readme is also truncated mid-sentence, leaving some content unevaluable.
- Auth strength is uncertain from static evidence: README calls KURI_SECRET optional; verify enforced token auth by default before deploying.
- High-impact endpoints (/auth/extract, /cookies, /dialog/auto, arbitrary JS evaluation) have no confirmation mechanism; mitigate agent misfire risk yourself.
- All performance and token-savings figures are self-measured; re-run cross-tool comparisons in your own environment before quoting them.
- License is SSPL v1 with an author-only exception to the service clause; hosted commercial use by anyone else needs legal review.
- Windows is compile-passing but heavily stubbed at runtime — not for production. The README's Zig 0.16.0 claim conflicts with the CI's 0.17.0-dev toolchain; check build.zig before building from source.
- The release channel is a self-managed branch (release-channel), not GitHub Releases itself; supply-chain trust depends on that branch's integrity.
What does this agent do, and when should you use it?
Kuri (justrach/kuri) is a browser automation and device-control suite written in Zig 0.16, shipping four binaries: kuri (a CDP server exposing 135 HTTP endpoints), kuri-fetch (a Chrome-free standalone fetcher with embedded QuickJS), kuri-browse (an interactive terminal browser), and kuri-agent (a scriptable CLI). It drives browsers over the Chrome DevTools Protocol and emits accessibility-tree snapshots with compact @eN refs, HAR 1.2 network recordings, and Markdown page conversions, while kuri-mobile controls Android and iOS devices through a native Zig adb wire-protocol client and usbmuxd client. Compared with Playwright/Node stacks, its Apple Silicon binaries stay under 2 MiB with zero runtime dependencies, snapshots use 7-12% fewer tokens than agent-browser, and /page/state, /diff/snapshot, and POST /batch bring a full agent loop down to roughly 3,400 tokens. It also applies stealth/anti-detection patches at startup (UA rotation, WebGL/Canvas spoofing), detects Akamai/Cloudflare/PerimeterX/DataDome blocks, and ships security-testing commands for cookie audits, security-header checks, and IDOR probing. kuri-mobile is exposed via ios/android subcommands of the main kuri binary and installs nothing on the target device.
kuri launches managed Chrome (or attaches via CDP_URL) and serves 135 JSON HTTP endpoints on 127.0.0.1:8080: /tab/new, /navigate, and /snapshot?filter=interactive&format=compact produce a11y-tree snapshots with @eN refs; /action?action=click&ref=eN fires trusted CDP mouse events and per-character key events that work with React 18/19; /har/start and /har/stop record traffic as HAR 1.2; /diff/snapshot emits compact +/-/~ deltas; POST /batch runs multiple commands in one call; /page/state returns a ~48-token lightweight page observation. kuri-fetch fetches pages standalone into markdown/html/links/text/, executes inline scripts via QuickJS, and includes SSRF defenses; kuri-browse offers numbered-link terminal browsing with history and in-page search; kuri-agent provides go/snap/click/fill/eval/cookies/headers/audit/probe commands for post-login cookie flag audits, header checks, and IDOR probes. kuri-mobile implements the adb host protocol natively (4-hex framing over host:transport:/shell:/exec on libc sockets) plus a usbmuxd ListDevices client, running android tap/swipe/screenshot/uitree and iOS simulator list-devices/openurl/screenshot/launch (real-device launch/terminate via xcrun devicectl).
- AI agent developers building browser action loops: take low-token /snapshot?filter=interactive snapshots, click via @eN refs, and use /diff/snapshot plus POST /batch to hold each cycle to roughly 1,700-3,400 tokens
- Crawler engineers scraping pages with kuri-fetch or the CDP pipeline, outputting Markdown/JSON, and using stealth patches plus KURI_PROXY to get past Akamai and PerimeterX WAFs
- Security testers who, after logging into a target, run kuri-agent cookies/headers/audit to inspect cookie flags, missing security headers, and JS-exposed tokens, and use the probe command to iterate numeric IDs for IDOR checks
- QA automation engineers using the 135 endpoints for React-compatible clicks, screenshot diffs, Core Web Vitals collection, and request interception
- Mobile testers driving Android emulators/devices via kuri-mobile's native adb client (tap, swipe, uitree, screenshot) and iOS simulators via usbmuxd/simctl
- Terminal-first developers browsing and searching the web on headless servers with kuri-browse
What are this agent's strengths and limitations?
- Single binary with zero Node/Playwright dependencies: under ReleaseFast on Apple Silicon, kuri is 1.04 MiB and kuri-agent 615 KiB, with RSS starting around 2.45 MiB
- Token efficiency tuned for agent loops: 3-char @eN refs, /page/state (48 tokens), the /diff/snapshot diff-first loop, and POST /batch batching cut a 9-click trajectory from 44,285 tokens to 898 (49x)
- Natively implemented mobile control: adb wire protocol and usbmuxd client are written in Zig with no Bun/Node/Gradle/Xcode build chain, and nothing is installed on the device
- Built-in anti-detection: stealth JS patches apply at startup (webdriver hidden, WebGL/Canvas spoofing, UA rotation), and navigation auto-detects Akamai/Cloudflare/PerimeterX/DataDome blocks returning structured fallbacks
- Ships security-testing trajectories: cookie flag audits, security-header checks, JWT decoding, and IDOR probe commands emitting single-line JSON for jq pipelines
- No native Windows feature set: cross-compile is experimental, and Chrome automation, daemonization, HAR recording, and the file-backed auth store all return error.UnsupportedOnWindows; full functionality requires WSL2 (issue #153)
- Limited real-iOS capability: XCUITest-backed tap/uitree on real devices is intentionally unavailable in the driverless design; real devices only support listing and launch/terminate via xcrun devicectl, and simulator actions depend on xcrun simctl
- CDP mode requires a local Chrome/Chromium whose lifecycle you must manage, and repeated agent-loop runs re-pay the full token cost (no libretto-style zero-token replay)
- The GitHub license field is NOASSERTION; although the LICENSE file states Apache-2.0, compliance teams should verify independently
- Cross-tool token-savings figures come from the author's own benchmarks (some using a chars/4 approximation), and the README itself advises re-running numbers in your environment before quoting percentages
How do you install or deploy this agent?
One-line install on macOS/Linux: curl -fsSL https://kuri.trilok.ai/download | sh (or curl -fsSL https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/install.sh | sh), which installs to ~/.local/bin; prebuilt binaries cover macOS arm64/x86_64 and Linux x86_64/arm64 with no runtime dependencies. Package managers also work: bun install -g kuri-agent or npm install -g kuri-agent (the correct native binary is downloaded at install time). To build from source you need Zig >= 0.16.0: git clone https://github.com/justrach/kuri.git && cd kuri && zig build -Doptimize=ReleaseFast, with outputs in zig-out/bin/. Windows is experimental cross-compile only; Chrome automation and related features return error.UnsupportedOnWindows, so use WSL2.
How do you use this agent?
CDP server mode: ./zig-out/bin/kuri (auto-launches managed Chrome if CDP_URL is unset), then curl -s http://127.0.0.1:8080/discover to find tabs. Recommended session-based agent loop: SESSION=hn-demo; BASE=http://127.0.0.1:8080; curl -s -H "X-Kuri-Session: $SESSION" "$BASE/tab/new?url=https%3A%2F%2Fnews.ycombinator.com", then /page/state (or /snapshot?filter=interactive&format=compact) and /action?action=click&ref=eN. With existing Chrome debugging: CDP_URL=ws://127.0.0.1:9222/devtools/browser/... ./zig-out/bin/kuri. Standalone fetch: kuri-fetch https://example.com (options --, -d links, --js). Terminal browsing: kuri-browse https://example.com. CLI automation: kuri-agent tabs -> kuri-agent use <ws_url> -> kuri-agent go <url> -> kuri-agent snap --interactive -> kuri-agent click e0. Device control: kuri ios list-devices / kuri android tap 540 1200. Key env vars: HOST, PORT (default 8080), KURI_SECRET (API auth), STATE_DIR (default .kuri), KURI_PROXY.
How does this agent compare with similar options?
The README benchmarks Kuri against agent-browser (Vercel) and browser-use, claiming 135-endpoint parity and 7-12% fewer snapshot tokens; against libretto (Playwright + Node), measured head-to-head with tiktoken, kuri is 13-376x faster per call (persistent server vs Node-per-command) and uses 1.37-2.5x fewer snapshot tokens on typical pages, but libretto wins on repeat runs because it compiles trajectories to a Playwright script for zero-token replays while kuri re-pays the loop each time. For large lists, kuri emits all 259 refs by default (4,424 tokens) and only beats libretto's default truncation when you pass limit=N.