{
  "markdown": "# Cornea \n\n**Deterministic visual inspection for AI agents. The eyes a coding agent never had.**\n\nCornea gives a coding agent that builds web pages a real way to *see* them. As a **token-cheap, deterministic structural model** it can reason over exactly, instead of megabytes of screenshots and raw DOM dumped into context.\n\nAn agent doesn't need a *photo* of a page. It needs to know **is my layout broken, and how.** Cornea computes an abstract *visual geometry model* of every element (box, position, z-order, computed styles) and derives inspection conclusions. **overlap, overflow, contrast, quality**. Then exposes them as native tools on **three surfaces**: CLI, MCP, and HTTP API.\n\n> One promise holds everything together: **same input → byte-identical output.** No Chromium, no sub-pixel variance, no server. A single ~1.4 MB binary.\n\n---\n\n## Quick start\n\n```bash\n# Build (Rust 1.98+, edition 2024)\ncargo build --release\n\n# Inspect a file, the simplest way to use Cornea\n./target/release/cornea tests/fixtures/sample-bugs.html 360\n```\n\n> Requires only `cargo`. No browser, no Node, no system dependencies. Builds fine on a phone-class device.\n\n**Or install the `cornea` command from npm (no Rust toolchain needed):**\n\n```bash\nnpm install -g optrex   # provides the cornea command\ncornea --help\n```\n\n---\n\n## Visual guide: what Cornea does\n\nTake this page below. It looks fine as source. But it's hiding four layout bugs. Cornea finds every one.\n\n```html\n<!-- tests/fixtures/sample-bugs.html (excerpt) -->\n<section class=\"row\">\n  <div class=\"card\">Card 1</div><div class=\"card\">Card 2</div><div class=\"card\">Card 3</div>\n</section>\n<div class=\"overlap-left\">Left overlap</div>   <!-- position:absolute; left:20; top:20 -->\n<div class=\"overlap-right\">Right overlap</div> <!-- position:absolute; left:150; top:40 -->\n<div class=\"overflow-bad\">...</div>            <!-- width:600 on a 360 viewport -->\n<p class=\"low-contrast\">Hard to read on white</p>  <!-- color:#cccccc on #ffffff -->\n```\n\nRun it and Cornea reports the damage instantly:\n\n```text\n$ ./target/release/cornea tests/fixtures/sample-bugs.html 360\n\n{\n  \"html_file\": \"tests/fixtures/sample-bugs.html\",\n  \"viewport_w\": 360.0,\n  \"element_count\": 17,\n  \"est_tokens\": 1068,                      // <-- entire page read for ~1k tokens\n  \"report\": {\n    \"total_elements\": 17,\n    \"visible_elements\": 14,\n    \"overlaps\": [ ... 7 collisions ... ],\n    \"overflows\": [ ... 1 clipped ... ],\n    \"contrast\":  [ ... 2 AA failures ... ],\n    \"quality\":   { \"score\": 0.06, \"label\": \"broken\" }\n  }\n}\n```\n\nEach finding is precise and actionable:\n\n| Finding | Detail |\n|--------|--------|\n| **Overlap** | `section.row ⇄ div.overlap-right`, area 20000 px². The absolutely-positioned boxes cover the cards |\n| **Overflow** | `div.overflow-bad`: right edge `600` exceeds viewport `360` → clipped |\n| **Contrast** | black on `blue`: ratio `2.44:1`. Fails WCAG AA (needs 4.5) |\n| **Contrast** | `#cccccc` on white: ratio `1.61:1`. Fails WCAG AA |\n\nThat is the value: **hundreds of tokens, not hundreds of kilobytes**, and a deterministic answer the agent can act on and re-verify.\n\n---\n\n## Visual guide: the three surfaces\n\nCornea is **one engine, three doors.** All three returns identical inspection JSON because they funnel through a single shared dispatch.\n\n### 1. CLI. Inspect a file\n\n```bash\ncornea <file.html | http(s)://url> [viewport_width] [viewport_height] [--js]\n```\n\n```text\n$ cornea page.html 360\n{\n  \"html_file\": \"page.html\",\n  \"viewport_w\": 360.0,\n  \"element_count\": 42,\n  \"json_bytes\": 8124,\n  \"est_tokens\": 2193,\n  \"report\": { \"total_elements\": 42, \"visible_elements\": 38, \"overlaps\": [], \"overflows\": [], \"contrast\": [], \"quality\": { \"score\": 1.0, \"label\": \"good\" } }\n}\n```\n\n### 2. MCP. Native agent tools over stdio\n\n```bash\ncornea --serve\n```\n\nAn agent calls `layout.*` tools directly; it passes the page source, or a\nlive URL (see URL capture below), per call:\n\n```json\n→ {\"method\":\"tools/call\",\"params\":{\"name\":\"layout.overlaps\",\n     \"arguments\":{\"html\":\"<div style=\\\"position:absolute;left:20;top:20;width:200;height:100\\\">A</div>...\"\n                   ,\"width\":360}}}\n← {\"id\":1,\"result\":{\"content\":[{\"text\":\"[{\\\"a_sel\\\":\\\"...div \\u21c4 ...div\\\",\\\"area\\\":20000}]\"}]}}\n```\n\n| Tool | Returns |\n|------|---------|\n| `layout.inspect` | Full visual model + report |\n| `layout.overlaps` | Elements whose boxes collide |\n| `layout.overflow` | Clipped / collapsed / off-screen |\n| `layout.contrast` | WCAG AA ratios for text elements |\n| `layout.quality` | 0..1 health score + issue list |\n| `layout.fidelity` | Which CSS features are exact vs approximated |\n\n### 3. HTTP API. Call from anything\n\n```bash\ncornea --serve-http [addr]        # default 127.0.0.1:8080\n```\n\n```bash\ncurl -s -X POST http://127.0.0.1:8080/inspect \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"html\":\"<p style=\\\"color:#cccccc\\\">bady</p>\",\"width\":360}'\n```\n\n```text\n{\"total_elements\":1,\"contrast\":[{\"selector\":\"...>p\",\"fg\":\"#cccccc\",\"bg\":\"#ffffff\",\n                                 \"ratio\":1.61,\"pass_aa\":false}]}\n```\n\n| Route | Method | Returns |\n|-------|--------|---------|\n| `/inspect` | POST | Full report |\n| `/overlaps` | POST | Collisions |\n| `/overflow` | POST | Clipped / collapsed / off-screen |\n| `/contrast` | POST | WCAG ratios |\n| `/quality` | POST | Health score |\n| `/fidelity` | GET | Engine capabilities |\n| `/health` | GET | Liveness |\n\n---\n\n## Watching a live page (URL capture)\n\nEvery surface accepts a URL where the HTML would go. Cornea fetches the\npage, inlines its external stylesheets and external scripts (relative\nURLs resolved against the page), then inspects what a browser would\nactually show. That is the live coding session loop: run your dev server,\npoint cornea at it, read the layout verdict.\n\n```bash\ncornea http://localhost:3000 390\n```\n\n```json\n{ \"url\": \"http://localhost:3000\", \"width\": 390, \"height\": 844 }  // HTTP /inspect\n```\n\n```json\n{ \"method\": \"tools/call\", \"params\": { \"name\": \"layout.quality\",\n  \"arguments\": { \"url\": \"http://localhost:3000\", \"width\": 390 } } }  // MCP\n```\n\nHonesty around capture:\n\n- Failed fetches leave the original tag in place and record a note, so the\n  report warnings still flag what did not load.\n- A positive `height` emulates a fixed viewport (screenshot frame, iframe,\n  email) and enables below the fold clipping checks. Default 0 means an\n  unbounded scrolling page.\n- Capture is a snapshot in time. Determinism holds engine side: the same\n  fetched bytes always produce the same report.\n- Plain HTTP is supported natively. HTTPS pages need a TLS stack, which the\n  binary does not carry; capture from a local http dev server or pre inline\n  the page with a fetch layer of your own.\n\n---\n\n## Architecture\n\n```\n                    ┌─────────────────────────────────────┐\n   HTML + CSS ──►   │           cornea (one binary)       │\n                    │                                     │\n                    │   dom.rs      html5ever ──► tree    │\n                    │   css.rs      <style> + inline      │\n                    │                                    │\n                    │   layout.rs   deterministic layout  │\n                    │               (block/inline/flex,   │\n                    │                box model, z-index)  │\n                    │                    │                │\n                    │   model.rs    Visual Geometry Model │\n                    │                    │                │\n                    │   inspect.rs  overlap / overflow /  │\n                    │               contrast / quality    │\n                    │                    │                │\n                    │   rest.rs     canonical dispatch    │\n                    └───────┬─────────────┬───────────────┘\n                            │             │\n                      ┌─────┴────┐   ┌────┴───────────────┐\n                      │  CLI     │   │  MCP (stdio) / HTTP│\n                      │  cornea  │   │  layout.* / REST   │\n                      └──────────┘   └────────────────────┘\n```\n\n**Read the full technical spec:** [`CORNEA-ARCHITECTURE.md`](./CORNEA-ARCHITECTURE.md)\n\n---\n\n## Fidelity. Honest about what's approximate\n\nCornea never silently fakes precision. `layout.fidelity` tells an agent exactly what it can trust, and every report carries its own `warnings` for sources the engine saw but did not apply (external stylesheets, external scripts, media queries, unresolved colors):\n\n```json\n{\n  \"exact\":        [\"box model\", \"block flow\", \"inline text estimates\", \"flex row/column (no wrap)\",\n                   \"z-index\", \"visibility\", \"absolute/fixed left/top\", \"inline styles\",\n                   \"class/id/tag selectors\", \"WCAG contrast (hex, rgb, hsl, alpha)\"],\n  \"approximate\":  [\"text glyph width (not shaping)\", \"flex-grow/flex-basis distribution\",\n                   \"percentage widths\", \"overlap semantics ignore intentional stacking\"],\n  \"deferred\":     [\"grid (parsed as block flow)\", \"media queries\", \"border-radius\",\n                   \"external stylesheet <link> when not captured\",\n                   \"complex selectors (combinators, pseudo)\"],\n  \"js\": {\n    \"engine\":      \"boa\",\n    \"phase\":       \"A\",\n    \"enabled\":     \"opt-in via --js / js:true\",\n    \"dom_shim\":    \"static HTML mirrored in first; getElementById; innerHTML parses markup\",\n    \"unsupported\": [\"async APIs\", \"event dispatch\", \"selector engine\", \"React/SPA mounting (Phase B)\"]\n  }\n}\n```\n\n## JavaScript built-in pages (Phase A)\n\nCornea can execute **inline `<script>`** that builds its DOM via a minimal shim,\nthen run the result through the same deterministic layout engine:\n\n```bash\ncornea page.html 360 --js            # inline scripts build the DOM first\n```\n\n```json\n{ \"html\": \"<p>…</p>\", \"width\": 360, \"js\": true }   // HTTP /inspect and MCP layout.*\n```\n\n- Static HTML is mirrored into the shim before scripts run, so scripts can\n  attach to existing nodes via `document.getElementById`, and `innerHTML`\n  parses real markup into elements. Static content survives script runs.\n- `style.*` assignments are serialized back to `style=\"…\"` and participate in overlap/contrast checks.\n- **Async APIs are rejected** (`setTimeout`, `fetch`, …) rather than hung. Any such use is surfaced in the report's `js_notes`, so determinism stays a guarantee.\n- External `<script src>` runs only when a capture layer (URL capture) inlined its body first.\n- Full React/SPA mounting is **Phase B** (experimental). Tracked in [`ROADMAP-JS.md`](./ROADMAP-JS.md).\n\n---\n\n## Visual guide: testing (battle-tested)\n\n54 tests run clean with `cargo test`; CI enforces **fmt, clippy `-D warnings`, release build, tests, and a CLI smoke test** on every push.\n\n```text\n$ cargo test\nRunning unittests src/lib.rs      ... 36 passed   // determinism, overlap, overflow,\nRunning unittests src/main.rs     ...  9 passed    //   contrast, inline flow, flex,\nRunning tests/endpoints.rs        ...  9 passed    //   nesting, empty input, MCP, CLI, JS, capture\n```\n\n- **Determinism**. Same page inspected twice gives byte-identical JSON (the core thesis).\n- **Bug detection**. The fixture's overlaps, overflows, and contrast failures are all asserted.\n- **End-to-end**. The compiled binary is spawned and `layout.*` is called over real stdio MCP.\n- **HTTP**. The TCP server boots on an ephemeral port and real requests are made.\n- **Live capture**. A real page is served over a local socket; linked CSS must change a contrast verdict.\n- **Edge cases**. Empty HTML, deep nesting (no crash), `display:none`, long text, flex row/col, inline wrapping.\n\n---\n\n## Layout support (v1 scope)\n\n| Feature | Status |\n|---------|--------|\n| Block flow, box model (content/border-box) | exact |\n| Inline text runs (horizontal, wrapping) | exact |\n| Flex row / column (simplified, no wrap) | approximate |\n| Absolute / fixed positioning (left/top) | exact |\n| z-index, visibility, `display:none` | exact |\n| `.class` / `#id` / `tag` selectors + inline styles | exact |\n| WCAG contrast (hex, rgb, hsl, alpha, inherited colors) | exact |\n| Live URL capture (CSS and script inlining) | supported |\n| Grid, media queries, border-radius | deferred |\n\n---\n\n## Repository layout\n\n```\ncornea/\n├── Cargo.toml             # crate: html5ever + serde/serde_json, release LTO+strip\n├── README.md              # this file\n├── CORNEA-ARCHITECTURE.md # full technical spec\n├── src/\n│   ├── lib.rs             # build_model / analyze pipeline + unit tests\n│   ├── dom.rs             # html5ever -> lightweight element tree\n│   ├── css.rs             # <style> + inline style resolution\n│   ├── fetch.rs           # live URL capture: GET + css/script inlining\n│   ├── layout.rs          # deterministic layout engine\n│   ├── model.rs           # VisualModel / ElementView / Rect\n│   ├── inspect.rs         # overlap / overflow / contrast / quality / warnings\n│   ├── rest.rs            # canonical endpoint dispatch (shared by all surfaces)\n│   ├── main.rs            # CLI + stdio MCP server\n│   └── server_http.rs     # dependency-free HTTP/1.1 API\n├── tests/\n│   ├── endpoints.rs       # end-to-end CLI + MCP binary tests\n│   └── fixtures/sample-bugs.html  # known-bug fixture for CI smoke\n└── .github/workflows/ci.yml\n```\n\n---\n\n## Status\n\n**Working MVP, hardened and battle-tested.** Deterministic inspection engine with CLI + MCP + HTTP API, live URL capture, below the fold checks, report warnings, 54 passing tests, green CI, plus Phase A inline-script rendering (`--js`). The roadmap builds toward giving Cornea (and the sibling **Crayon** text-to-image project) an even richer perception over subsequent phases.\n\n## Publishing\n\nCornea is distributed four ways: **npm** (`npm install -g optrex`, gives the `cornea` command), **crates.io** (`cargo install cornea`), **GitHub Release + Homebrew** (`brew install`), and the **MCP Registry** (`layout.*` tools discoverable by agents). All are staged in this repo. See **[`PUBLISHING.md`](./PUBLISHING.md)** for the tokens, `server.json` manifest, and the release/tag recipe.\n\nmcp-name: io.github.AbduljabbarBXR/cornea\n\n## License\n\nMIT. See [`LICENSE`](./LICENSE).\n",
  "bytes": 14097,
  "sha": "0fcce013a22a64e22d1683b5aa97bcbc0ac2de5989852366800818d7ec9c764a",
  "repo_slug": "abduljabbarbxr/cornea",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_abduljabbarbxr_cornea_246ee765/readme"
}