MCP Connector

Verify browser rendering with pixel-diff scoring and headless speed

hwatu is a WebKit daemon that gives coding agents one-call verified page checks with a climbable pixel-diff score, in about 35 ms.

Works with webkitplaywrightclaudecursor

75
Spark score
out of 100
Updated last month
Source checked Oct 8, 2026
Version 0.7.1
Models
universal

Add to Favorites

Why it matters

Give AI agents a fast, headless browser daemon that verifies rendered pages with pixel-perfect scoring, animation metrics, and structured output instead of forcing them to guess from screenshots-enabling verification loops that prove 97%+ visual accuracy in ~35ms per check.

Outcomes

What it gets done

01

Compare rendered pages with pixel-diff scoring, match percentages, and heatmap regions

02

Measure animations as structured data with duration, easing, and velocity metrics

03

Run headless page checks with console logs, JS errors, and screenshots in one call

04

Hand off live browser sessions to humans for CAPTCHA or manual intervention

Source

Get it from source

Spark does not host a copy of it.

Open source

Reports

Agent outcome reports

No reports yet

Capabilities

Tools your agent gets

check

Verify a page with one call: load, eval, screenshot, console output, and timing.

render

Render HTML markup to screenshot without a server, returning rendered state and output.

diff

Compare two windows by pixel-diff score, regions, and heatmap visualization.

motion

Extract animation properties as numbers: duration, easing, velocity, and keyframes.

seek

Pin all animations at a specific time t for deterministic animation frame capture.

snapshot

Capture page state as JSON tokens instead of pixels for structured analysis.

click

Perform a click action with real input events and structured error handling.

type

Type text with real input events and structured error handling.

+7 tools

Overview

hwatu is a visual verification harness for coding agents, built as a WebKit daemon. It gives an agent one-call verified page checks in about 35 ms, a climbable pixel-diff score, and animations reported as numbers, and also functions as a lightweight browser for tiling window managers. Reach for it when a coding agent needs to verify a frontend change actually rendered correctly, with a score it can climb across edits instead of a subjective screenshot check.

What it does

hwatu is a visual verification harness for coding agents, built as a WebKit daemon that replaces "looks right to me" with one-call verified page checks in about 35 ms, pixel-diff scores an agent can climb, animations reported as numbers, and headless windows that never steal focus, at any parallelism. It also doubles as a real browser optimized for tiling window managers (Hyprland, sway, niri, i3), aiming to replace a daily browser with a scrolling short-form content experience at mobile-level framerate. For human-in-the-loop tasks like CAPTCHAs, it includes a lightweight visual-verification frontend and a caller function for structured detection and hand-off.

Its verification loop centers on hwatu diff (pixel-match percent, diff regions, heatmap), hwatu motion (an animation's easing, duration, and velocity as numbers), hwatu check (open, load, eval, screenshot, close in one call, about 35 ms median), hwatu verify (a repeatable repo-level contract covering preflight, local dev server, responsive screenshots, source-staleness check, and an evidence report - exposed to MCP clients as verify_ui), and hwatu render (the same one-call pass against raw HTML piped via stdin, no temp file or local server needed). A demo run climbed a stripe.com landing-page clone from 85.1% to 98.8% pixel match; a second real-agent scenario against a live site produced four responsive-viewport diffs followed by human hand-off. hwatu watch and MCP's subscribe_events stream load/console/download/window events without polling.

As a browser, hwatu opens a window like a terminal opens a shell (the tiling WM is the tab bar), with mainstream keybinds, native ad blocking (119k EasyList rules compiled into WebKit's content-extension engine, no JS in the request path), Chromium-curve scrolling, unmuted autoplay, a blur-shield that raised Shorts from ~34 to ~95 fps, and a unified shortform control scheme across Reels, Shorts, and TikTok. Every window shares one warm daemon (56 MB per extra window), suspends when unfocused, and crash-restores at its last URL. Known gaps: no Widevine or passkeys in WebKitGTK, so a fallback browser is needed for services like Netflix.

Compared to Playwright or chrome-devtools-mcp, hwatu is "the coldest warm daemon": engine hot, everything else absent, so headless verify passes benchmark at 35-39 ms versus Playwright's 82 ms (warm in-process) or 341 ms (a fresh client against a kept-warm server), and one tool call replaces five. Unlike those automation APIs, which hand back raw screenshots and DOM for the agent to eyeball, hwatu's measurement primitives (pixel-diff, animation numbers, structured CAPTCHA detection) are built in.

When to use - and when NOT to

Use it when a coding agent needs to verify a frontend change actually rendered correctly - not just that a click succeeded or the console was clean - with a score it can climb across edits rather than a subjective screenshot review; add a project instruction (in AGENTS.md, CLAUDE.md, or Cursor rules) telling the agent to use hwatu after frontend changes and to check console for JS/request failures even after the visible outcome verifies. hwatu setup detects supported agents (Claude Code, Cursor, Jcode, or generic MCP) and previews changes with --dry-run; setup is idempotent and reversible with --undo.

challenge (CAPTCHA handling) is detection and hand-off only, by design - no solver APIs, no token injection, no fingerprint games - so it is not a tool for automating around anti-bot systems. hwatu renders WebKit, not Chromium, so keep a Chromium-based fallback for sites needing Chromium-specific behavior, and Playwright still wins on cold start (190 vs 435 ms) and memory when that specific tradeoff matters more than warm-daemon throughput.

Inputs and outputs

Input is a URL, piped HTML (hwatu render --stdin), or a .hwatu/*.verify.json contract file; output is structured JSON - match percent and diff regions, animation numbers, page-state snapshots as tokens, console/request errors, or an evidence report - plus, on request, a live window for human hand-off.

Integrations

curl -fsSL https://raw.githubusercontent.com/hongnoul/hwatu/main/scripts/install.sh | bash

One static binary plus the distro's webkitgtk-6.0 (the installer checks); available via yay -S hwatu on Arch or cargo build --release from source. hwatu setup wires up a detected coding agent; manual MCP configuration is one entry: {"mcpServers": {"hwatu": {"command": "hwatu", "args": ["mcp"]}}} - or skip MCP entirely and call it as a CLI or over a Unix socket with newline-delimited JSON. AGPL-3.0 licensed.

Who it's for

Developers whose coding agents make frontend changes and need a real, scoreable verification pass instead of a screenshot eyeballed by the agent - and, as a side benefit, anyone on a tiling WM who wants a lightweight browser built for the same warm-daemon model.

Source README

hwatu

Latest Release License: MIT CI

Headless UI verification for coding agents

An agent verifies aiuc.com with hwatu: one command returns pixel-match scores for four responsive viewports, then the live page pops into view for human hand-off

hwatu is a headless verification harness for coding agents: a warm WebKit daemon driven over CLI, MCP, or one JSON line per Unix-socket connection. Instead of "looks right to me", the agent gets one-call verified page checks in ~35 ms, pixel-diff scores it can climb, animations as numbers, and headless windows that never steal focus, at any parallelism. Jcode drives it natively as its browser backend. When a check needs a human (a CAPTCHA, a judgment call), hwatu focus <id> materializes the same live session as a real window.

Documents

Install

curl -fsSL https://raw.githubusercontent.com/hongnoul/hwatu/main/scripts/install.sh | bash

One static binary plus your distro's webkitgtk-6.0 (the installer checks). On Arch: yay -S hwatu. From source: cargo build --release.

Then connect an agent:

hwatu setup             # detect Claude Code, Cursor, Jcode, or MCP

Verification, not vibes

  • "Pixel-perfect" is a claim. match_percent: 97.49 is a measurement.
  • One tool call per page check, ~35 ms. The same pass through warm-server Playwright is 5 calls and ~9x slower.
  • Headless by default. No window pops, no focus stolen, you keep typing.
  • One static binary + your distro's webkitgtk. No Node, no 170 MB Chromium download.

hwatu setup detects supported coding agents without changing their config. Choose a client explicitly:

hwatu doctor
hwatu setup --client claude --scope project --dry-run
hwatu setup --client claude --scope project
hwatu demo

Setup is previewable (--dry-run), idempotent, and reversible (--undo). Manual MCP configuration is one portable entry:

{ "mcpServers": { "hwatu": { "command": "hwatu", "args": ["mcp"] } } }

Or skip MCP: every command is a short CLI call or one newline-delimited JSON line over a Unix socket.

Connecting hwatu makes its tools available; a project instruction tells the agent when to use them. Add this to AGENTS.md, CLAUDE.md, or Cursor rules:

## Frontend verification

Use Hwatu after frontend changes. Exercise the affected user journey and
verify its intended visible, navigational, or persisted result with `expect`.
A successful click or clean console is not proof of success. Check `console`
for additional JavaScript and request failures after verifying the outcome.

Then make the task's proof concrete:

Implement display-name editing on /settings. Use Hwatu to enter “Test User,”
save it, verify the visible success state, reload, confirm persistence, and
report any console errors.

The verification loop:

hwatu --headless localhost:3000        # its window; you never see it
hwatu --headless staging.example.com   # the reference

hwatu diff --id 2 --other 1 --heatmap /tmp/heat.png
# {"match_percent":85.13,"regions":[{"x":0,"y":160,"w":2048,...}]}

hwatu motion --id 1                    # the reference's animations, as numbers
# easing cubic-bezier(0.25,1,0.5,1), 300ms, marquee 29.78px/s ...

# ...agent edits code...

hwatu diff --id 2 --other 1
# {"match_percent":97.49}              # climbing beats guessing

This loop took a clone of stripe.com's landing page from 85.1% to 98.8% pixel match. Reproduce it: scripts/demo/. A second real-agent scenario (four responsive viewport diffs, then live human hand-off) with evidence manifests: scripts/demo-aiuc/.

A full verification pass (open, load, eval, screenshot, close) is one command, one tool call, ~35 ms median (benchmarks):

hwatu check localhost:5173 --eval 'document.title' --shot=/tmp/after.png
# {"title":"My App","eval":"My App","shot":"/tmp/after.png",
#  "console":[...],"load_ms":13,"total_ms":35}

For a repeatable repo-level contract that also owns the preflight, local dev server, responsive screenshots, source-staleness check, and evidence report:

hwatu verify .hwatu/about.verify.json

The same executor is exposed to MCP clients as verify_ui, so agent harnesses do not rebuild the orchestration loop. See the agent guide.

Generated HTML in hand and no server? hwatu render is the same one-call pass with the markup as input: no temp file, no python3 -m http.server:

echo '<h1>generated</h1>' | hwatu render --stdin --shot=/tmp/gen.png
# {"rendered":true,"shot":"/tmp/gen.png","load_ms":5,"total_ms":28}

# React to load, console, download, and window events without polling.
hwatu watch --kinds load,console
# {"event":"load","seq":1,"window_id":7,"data":{"state":"started",...}}

MCP clients call subscribe_events for the same stream as notifications/hwatu/event. Full protocol and verification loops: agent guide.

Elsewhere, headless is decided at launch and a human can never see the session. In hwatu it is a window property, switchable live, in both directions: hwatu focus <id> promotes any headless session to a real window for the human, state intact.

challenge is detection and hand-off only, by design: no solver APIs, no token injection, no fingerprint games.

The hand-off destination

The hand-off works because hwatu is also a real browser, built for tiling WMs. hwatu <url> opens a window like your terminal opens a shell (your WM is the tab bar, there is none in the window): mainstream keybinds (ctrl+l, ctrl+f, ctrl+k palette, rebindable), native ad blocking (119k EasyList rules compiled into WebKit's content-extension engine, zero JS in the request path), Chromium-curve scrolling, and unified shortform controls. Every window shares the one warm daemon (56 MB per extra window), suspends when unfocused, and crash-restores at its last URL. Honest gaps: no Widevine or passkeys in WebKitGTK. WM configs (hyprland, sway, niri), keybinds, and setup: docs/human.md.

hwatu as the hand-off destination: quarter-width window spawns and Chromium-curve scrolling in a tiling WM

Features

  • Headless / background / focused as a per-window property, switchable live
  • Human hand-off: hwatu focus <id> drops the live session into your tiling WM
  • Pixel-diff scoring: match percent + diff regions + heatmap (diff)
  • Animations as numbers: duration, easing, velocity (motion)
  • Deterministic animation frames: pin all animations at time t (seek)
  • Page state as JSON, tokens not pixels (snapshot)
  • Real input events with structured errors (click / type / scroll / upload)
  • JS errors, console output, failed requests (console)
  • Push event subscriptions as JSON lines or MCP notifications (watch)
  • One-call page assertions with polling (expect)
  • CAPTCHA / anti-bot detection with structured wait/resume (challenge)
  • MCP server, plain CLI, and a 1-line JSON socket protocol
  • A real browser as the hand-off destination: keybinds, media, ad blocking, crash restore

Why not Playwright or chrome-devtools-mcp?

Three ways to give an agent a browser:

How it runs What it costs the agent loop
Cold library (Playwright, launched per task) engine starts when the script does fast to call, slow to run: every check pays engine startup; no state survives between tasks
Warm browser (your Chrome + devtools-mcp) a full human browser stays resident resources spent on tabs, extensions, sync, UI you never render, and its windows steal your focus while you work
hwatu "the coldest warm daemon": engine hot, everything else absent 8 ms spawns, 35 ms verified checks, invisible until you ask to see it (focus), interruptible in both directions

hwatu keeps exactly what makes checks instant (engine, GPU context, compiled adblock, a prewarmed WebView) and nothing that serves a human unless that human asked for a window. That is why it idles warm without a tab bar, and why a kept-warm Playwright server driven the same way costs 341 ms per client to hwatu's 39 (benchmarks).

The second difference is what comes back. Playwright and chrome-devtools-mcp are automation APIs: they let an agent drive a browser, then hand back raw screenshots and DOM to eyeball. hwatu is a verification browser: the measurement primitives (check, diff, motion, expect) are built in, a window costs 13 ms, and headless is a window property, not a launch mode.

How hwatu compares

Legend: ✅ Yes / built-in · 🟡 Partial / limited · ❌ No

Capability Playwright chrome-devtools-mcp hwatu
Verify pass (load + eval + screenshot), warm in-process 82 ms n/a 35 ms
Verify pass as a warm service (fresh client per check) 341 ms n/a 39 ms
Tool calls per verify pass 5 5 1
Pixel-diff score + regions + heatmap 🟡 1 ❌ ✅
Animations as numbers, pinned mid-flight ❌ 2 🟡 3 ✅
Headless ↔ headed on a live session ❌ ❌ ✅
Human hand-off mid-session, state intact ❌ ❌ ✅
No focus stealing at N parallel agents 🟡 4 🟡 4 ✅
CAPTCHA detection + structured wait/resume ❌ ❌ ✅
No Node, no per-version browser download ❌ ❌ ✅

1 toHaveScreenshot compares against stored goldens: pass/fail for test suites, not a score an agent can climb.

2 Standard practice is to disable animations or fast-forward to the end state to avoid flakes.

3 Raw CDP can query animation state, but there is no numeric summary of easing/velocity/keyframes.

4 Fine headless; every headed window pops and takes focus.

Comparison reflects each project at the time of writing; corrections are welcome. Honest caveats: Playwright still wins cold start (190 vs 435 ms, paid once per boot) and memory; hwatu renders WebKit not Chromium (keep a Playwright matrix in CI for engine-specific bugs), and it is Linux-only today. Full head-to-head data and methodology: docs/benchmarks.md.

What about Claude in Chrome? Different category. Claude in Chrome is one agent product driving your Chrome through an extension, sharing your profile, tabs, and focus, callable by nothing else. hwatu is a client-agnostic daemon any agent calls over CLI/MCP, with its own warm WebKit engine, headless by default, and verification primitives built in. Use Claude in Chrome to let Claude browse alongside you; use hwatu when agents need cheap, repeated, measurable page checks.

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.