@fordwh44/wiresnap
v0.2.0
Published
Agent-first visual verification: MCP server for wireframe layout snapshots and structural diffs, without pixel screenshots
Maintainers
Readme
wiresnap
Visual verification for coding agents — no screenshots, no vision tokens.
wiresnap is an MCP server that lets an agent check its own UI work the way it checks a test suite: as text. Instead of taking a pixel screenshot and burning vision tokens to eyeball it, the agent snapshots the page's layout before making a change and asks one question after: what changed?
Compared http://localhost:3000 against baseline "baseline":
12 changes detected (8 elements unchanged):
+ added div.alert "Action required: verify your billing ema…" at (0, 55) size 1280×42
- removed div.banner "Scheduled maintenance this Sunday at 02:…" was at (0, 55) size 1280×42
~ moved aside "Recent activity" right 60px to (476, 129)
~ resized div.card "Create report" width +60px now 420×263
~ styled button.btn.primary "Submit" background: #3b82f6 → #16a34a
~ text p "Generate a monthly summary…" "…weekly summary…" → "…monthly summary…"That report is deterministic, a few hundred tokens, and produced in about a second. A screenshot-based check of the same change costs two ~500 KB images, a vision model pass, and hope that fonts and antialiasing don't flake.
How it works
One Chrome DevTools Protocol call — DOMSnapshot.captureSnapshot — returns what the layout engine already knows: every element's box, paint order, text runs, and key computed styles. No rasterization, no GPU, no encoding. wiresnap filters that into a compact snapshot (5–50 KB of JSON), renders an SVG wireframe for humans, and diffs snapshots structurally by element identity (tag + id + classes + text) with a pixel tolerance.
Two captures of the same page are byte-identical, so "did anything change" is an exact text operation, not a similarity score.
Setup for agents (MCP)
Requires Node 18+ and a Chrome/Chromium install (auto-detected; override with WIRESNAP_CHROME).
Cursor — .cursor/mcp.json:
{
"mcpServers": {
"wiresnap": {
"command": "npx",
"args": ["-y", "@fordwh44/wiresnap", "mcp"]
}
}
}Claude Code:
claude mcp add wiresnap -- npx -y @fordwh44/wiresnap mcpSnapshots are stored in ./.wiresnap/ (change with --dir or WIRESNAP_DIR). Add .wiresnap/ to your .gitignore.
Tools
| Tool | What it does |
|---|---|
| snapshot | Capture a page's layout and store it under a name (the baseline). |
| verify | Capture the page now, diff against a stored baseline, return the change report. The main tool. |
| diff | Compare any two stored snapshots by name. |
| layout | List element boxes with positions, sizes, colors, and text — spatial grounding without an image. Supports filtering. |
The agent loop
- Before touching code:
snapshotthe affected page → baseline stored. - Make the change.
verifyagainst the baseline → plain-text report of added/removed/moved/resized/restyled/text changes.- Report matches intent? Done. Unexpected cascade (something moved that shouldn't have)? Fix and re-verify.
verify also writes a visual diff overlay SVG (overlay: true) — green for added, red for removed, amber arrows for moved/resized — for the human reviewing the agent's work.
CLI
Everything is also available standalone:
wiresnap snapshot http://localhost:3000 -o before
wiresnap snapshot http://localhost:3000 -o after
wiresnap diff before.json after.json
wiresnap diff before.json after.json --svg changes.svg --fail-on-change # CI gate
wiresnap render before.json -o wireframe.svgAnd as a library:
import { capture, createCapturer, diffSnapshots, formatReport, renderSvg } from 'wiresnap';
const before = await capture('http://localhost:3000');
const after = await capture('http://localhost:3000');
console.log(formatReport(diffSnapshots(before, after)));When to use what
| | Pixel screenshot | ARIA snapshot | wiresnap | |---|---|---|---| | Size per capture | ~500 KB | 2–5 KB | 5–50 KB | | Deterministic | no | yes | yes | | Geometry / layout | yes (implicit) | no | yes (explicit) | | Colors / styling | yes | no | key properties | | "What changed" diff | vision model | text diff | structured report | | Exact pixels (gradients, images, antialiasing) | yes | no | no |
Use ARIA snapshots to decide what to click. Use wiresnap to verify layout and styling changed the way you intended. Fall back to real screenshots only when exact pixels are the requirement.
Limitations
- Chromium-only (uses CDP).
- Main document only; iframes are not yet traversed.
- Border rendering approximates all four sides from the top border.
- Text in the wireframe SVG re-renders with system fonts, so wrapping can differ slightly from the source page (box positions come from the real layout, so geometry never lies).
- Canvas/WebGL content renders as a placeholder box.
Development
npm install
npm testTests run end-to-end — including a real MCP client driving the server over stdio — against the fixture pages in fixtures/ using the system Chrome.
License
MIT
