hwatu

hwatu

Verification browser for coding agents. Headless-by-default WebKit windows with DOM eval, screenshots, pixel-diff with a real match percentage and heatmap, and live hand-off to a human. One static binary, no Chromium.

Category
访问服务器

README

<div align="center">

hwatu

Latest Release License: AGPL-3.0 CI

Make your agent harness loop instantly faster by giving it real eyes

</div>

  • STOP your agent claiming "pixel-perfect." Make it prove 97.49%.
  • STOP paying 5 tool calls per page check. hwatu check is one call, ~35 ms (beats warm-server Playwright ~9x).
  • STOP browser windows stealing your focus. Headless by default, you keep typing.
  • STOP shipping 170 MB of Chromium. One static binary + your distro's webkitgtk.

<a href="https://github.com/hongnoul/hwatu/releases/download/readme-assets/demo-v2.mp4"><img src="https://github.com/hongnoul/hwatu/releases/download/readme-assets/demo-v2.webp" alt="hwatu real workflow: open headless, verify the rendered page, then hand the live browser to a human" width="800"></a>

Documents

  • Agent guide: protocol, primitives, verification loops
  • Human guide: the tiling-WM browser side
  • Benchmarks: every number, measured, with methodology
  • Roadmap: plan of record, priorities, non-goals

Quick Start

Install → Detect workflow → Connect agent → Verify page → Hand off to human

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

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

The installer installs binaries only. hwatu setup detects supported coding agents and prints the available connections without changing their config. Choose a client explicitly when you are ready:

hwatu doctor
hwatu setup --client claude --scope project --dry-run
hwatu setup --client claude --scope project
hwatu demo
  • Install: download two binaries and check WebKitGTK.
  • Detect: find Claude Code, Cursor, Jcode, or a generic MCP workflow.
  • Connect: use Jcode's native socket, MCP, or the CLI fallback.
  • Verify: run a headless rendered smoke test with doctor or demo.
  • Hand off: materialize the same live session only when a human is needed.

Setup is previewable, idempotent, and reversible with the same client and scope plus --undo. Project scope creates shareable configuration; user scope keeps it personal. Claude Code asks each user to approve project-scoped MCP servers when it next starts.

Manual MCP configuration remains one portable entry:

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

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

hwatu localhost:3000       # open a window like you open a terminal

Features

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

Why not Playwright or chrome-devtools-mcp?

There are three ways to give an agent a browser, and two of them are bad at it:

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 sitting in front of it. That's why it idles warm without a tab bar, and why a kept-warm Playwright server driven the same way still costs 341 ms per client to hwatu's 39 (benchmarks).

The second difference is what comes back. Playwright and chrome-devtools-mcp are, at their core, automation APIs: they let an agent drive a browser, then hand back raw screenshots and DOM for the agent to eyeball.

hwatu is different. It is a verification browser: the measurement primitives are built in, and the browser itself is a warm daemon where a window costs 13 ms and headless is a window property, not a launch mode.

That is why the loop looks like this, real commands, real output:

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

We ran this loop against a clone of stripe.com's landing page: an agent took it from 85.1% to 98.8% pixel match. Reproduce it: scripts/demo/. 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}

The same pass through Playwright's warm in-process CDP connection, its best case, is 82 ms and five API calls. Shaped like hwatu actually runs (a fresh client each check against a kept-warm engine), Playwright's pass is 341 ms vs hwatu's 39: hwatu is a warm daemon by design, Playwright is a library you have to keep warm yourself.

And when the agent hits a CAPTCHA or a judgment call, hwatu focus materializes its live session, cookies and state intact, in your tiling WM. You act for ten seconds. It takes back over. This is the adjective no other tool gets to claim: interruptible. Everywhere else, headless is decided at launch and a human can never see the session at any price. In hwatu it's a window property, switchable live, in both directions.

The speed follows from the same design decision: hwatu is a warm daemon, not a library you launch. The engine, the GPU context, the compiled adblock ruleset, and a prewarmed WebView outlive every task, so a check starts from a hot pipeline instead of a cold process. Playwright is a library and cold by nature. Keeping it warm is something you build (a server process, connection management, context pooling); hwatu ships warm as the default and the only 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.


AGPL-3.0 licensed. Linux. WebKitGTK 6.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选