Atlas / MCP servers / hongnoul / Hwatu

HwatuBLOCK

mcp/hongnoul/hwatu

Headless verification browser for AI coding agents: 35 ms one-call checks, pixel diffs, live human hand-off

Verdict
BLOCK
Grade
F
Trust score
46 /100
Exposed tools
—
Transport
stdio
License
MIT
Stars
115
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

[](https://github.com/hongnoul/hwatu/releases) [](LICENSE) [](https://github.com/hongnoul/hwatu/actions/workflows/ci.yml)

Headless UI verification for coding agents

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 materializes the same live session as a real window.

Documents

  • Agent guide: protocol, primitives, verification loops
  • Benchmarks: every number, measured, with methodology
  • Vision: durable product principles, native platform strategy
  • Human guide: hwatu as a tiling-WM browser, keybinds, hand-off
  • Roadmap: portfolio priorities and product boundaries
  • AI verification
  • Tiling-WM browser
  • Shared platform
  • macOS research: measured WKWebView probes, competi
Read from source at commit 0ee44ab04a68OBSERVED · 2026-10-07
02

Trust audit

BLOCKgrade F · trust 46/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)FAIL
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (9 observation(s))
Network
declared (15 observation(s))
Shell
declared (5 observation(s))
Dependencies
pinned
Secrets in source
found

Findings (25)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
crates/hwatu/src/clone.rs:164
fn eval(id: u64, js: &str, timeout_ms: u64) -> Result<serde_json::Value, String> {
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
crates/hwatu/src/clone.rs:241
match eval(id, &js, wait.eval_timeout_ms()) {
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
crates/hwatu/src/clone.rs:304
let cap = eval(live, EXTRACT_JS, opts.timeout_ms)?;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
crates/hwatu/src/clone.rs:517
eval(live, &format!("scrollTo(0,{scroll_y}); return 0"), 10_000)?;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
crates/hwatu/src/clone.rs:534
eval(live, &iso, 10_000)?;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHNetwork egress · net.tls_off · CWE-200, CWE-319
crates/hwatu/src/clone.rs:110
"--no-verify" => verify = false,
Why it matters. certificate verification is disabled
Fix. leave verification on
HIGHPrompt injection · prompt.zero_width · CWE-94, CWE-1427
scripts/demo/clone/index.html:191
<div class="below-title"><h2>Flexible solutions for every business model.</h2> <p>Grow your business with a comprehensive set of payments and financial tools—designed to work individually or together.
Why it matters. invisible characters in instruction text
Fix. strip non-printing characters
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
scripts/bench-tokens.mjs:238
console.log(`# token/context budget benchmark\n`);
MEDIUMNetwork egress · net.beacon_words · CWE-200, CWE-319
crates/hwatud/src/abp.rs:344
"websocket" | "ping" | "beacon" | "other" | "object" | "object-subrequest" => {
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
crates/hwatu/src/verify_job.rs:1232
"url": "http://127.0.0.1:4321/about",
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
crates/hwatu/src/verify_job.rs:1286
url_authority("http://127.0.0.1:4321/x"),
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
crates/hwatud/src/ipc_server.rs:1659
"http://127.0.0.1:8080"
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
crates/hwatud/src/prompts.rs:240
assert_eq!(host_of("http://127.0.0.1:8080/"), "127.0.0.1");
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
crates/hwatu/src/main.rs:1954
let token = "0123456789abcdef0123456789abcdef".to_string();
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
crates/ipc/src/lib.rs:1850
let token = "0123456789abcdef0123456789abcdef";
LOWInventory / provenance · inv.hidden_file · CWE-1104
packaging/aur/.SRCINFO
.SRCINFO
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
examples/clone/materialize.py:32
h = hashlib.sha1(url.encode()).hexdigest()[:16]
LOWFilesystem / path · fs.credential_store · CWE-22, CWE-59
.github/workflows/aur-publish-manual.yml:42
mkdir -p ~/.ssh
Why it matters. touches a credential store
LOWFilesystem / path · fs.credential_store · CWE-22, CWE-59
.github/workflows/aur-publish-manual.yml:43
chmod 700 ~/.ssh
Why it matters. touches a credential store
LOWFilesystem / path · fs.credential_store · CWE-22, CWE-59
.github/workflows/aur-publish-manual.yml:44
printf '%s\n' "$AUR_SSH_KEY" > ~/.ssh/aur
Why it matters. touches a credential store
LOWFilesystem / path · fs.credential_store · CWE-22, CWE-59
.github/workflows/aur-publish-manual.yml:45
chmod 600 ~/.ssh/aur
Why it matters. touches a credential store
LOWFilesystem / path · fs.credential_store · CWE-22, CWE-59
.github/workflows/aur-publish-manual.yml:46
ssh-keyscan -t ed25519 aur.archlinux.org >> ~/.ssh/known_hosts 2>/dev/null
Why it matters. touches a credential store
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
crates/hwatu/build.rs:17
println!("cargo:rerun-if-changed=../../.git/HEAD");
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
crates/hwatu/build.rs:18
println!("cargo:rerun-if-changed=../../.git/refs");
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
crates/hwatud/build.rs:17
println!("cargo:rerun-if-changed=../../.git/HEAD");

Gates applied: no_behavioural_pass.

Audited 2026-10-07 · audit v0.4.1 · source sha 0ee44ab04a68full audit observations/trust-audit/mcp-server/hongnoul__hwatu.json · Report an issue / request a re-scan
03

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-070ee44ab04a68BLOCKF46first audit
04

Questions

What is the Hwatu MCP server?

Headless verification browser for AI coding agents: 35 ms one-call checks, pixel diffs, live human hand-off

Is Hwatu safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (46/100) and found 7 critical or high issues in the source. Each one is listed on this page with the file and line it is on.

What credentials does Hwatu need?

No credential environment variables were found in its source, so it appears to need none.

How does Hwatu run?

It speaks stdio, so it runs as a local process your client starts.

How current is this page?

The grade is for one exact copy of the source (0ee44ab04a68), read on 2026-10-07. The repository is watched and re-audited when it changes.

Advertisement