关于 Cornea, deterministic visual inspection
Cornea 是面向编码 Agent 的确定性网页布局检查引擎,可通过 CLI、MCP 和 HTTP API 使用。它以结构化几何模型分析重叠、溢出、对比度和页面质量,并对相同输入生成一致输出。
主要功能
- 01确定性布局分析
- 02检测重叠与溢出
- 03检查 WCAG 对比度
- 04评估页面质量
- 05支持实时 URL 检查
- 06提供 CLI、MCP 和 HTTP 接口
适用场景
- 01检查编码 Agent 生成的页面布局
- 02在开发期间检查本地网页
- 03验证页面文本的颜色对比度
MCP 相关
通过 stdio 暴露 `layout.*` 工具,供 MCP 客户端检查 HTML 或实时 URL,并返回布局模型与分析结果。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Cornea
为 AI Agent 提供确定性的视觉检查。让编码 Agent 拥有从未拥有过的眼睛。
Cornea 让用于构建网页的编码 Agent 真正能够看见网页。它是一个低 Token 消耗、确定性的结构模型,Agent 可以对其进行精确推理,而不必将数 MB 的截图和原始 DOM 倾倒进上下文。
Agent 不需要网页的照片,而是需要知道我的布局有没有问题,问题在哪里。 Cornea 会计算每个元素的抽象视觉几何模型(框、位置、z 顺序、计算样式),并据此得出检查结论:重叠、溢出、对比度、质量。随后将这些能力作为原生工具提供于三个入口:CLI、MCP 和 HTTP API。
一条承诺贯穿始终:相同输入 → 字节完全一致的输出。 无需 Chromium,不存在亚像素差异,也无需服务器。只需一个约 1.4 MB 的二进制文件。
快速开始
# Build (Rust 1.98+, edition 2024)
cargo build --release
# Inspect a file, the simplest way to use Cornea
./target/release/cornea tests/fixtures/sample-bugs.html 360
只需
cargo。无需浏览器、Node 或系统依赖。在手机级设备上也能顺利构建。
或者从 npm 安装 cornea 命令(无需 Rust 工具链):
npm install -g optrex # provides the cornea command
cornea --help
视觉指南:Cornea 的功能
看看下面这个页面。作为源代码看起来没问题,但它隐藏着四个布局错误。Cornea 能全部找出来。
<section class="row">
<div class="card">Card 1</div><div class="card">Card 2</div><div class="card">Card 3</div>
</section>
<div class="overlap-left">Left overlap</div>
<div class="overlap-right">Right overlap</div>
<div class="overflow-bad">...</div>
<p class="low-contrast">Hard to read on white</p>
运行后,Cornea 会立即报告这些问题:
$ ./target/release/cornea tests/fixtures/sample-bugs.html 360
{
"html_file": "tests/fixtures/sample-bugs.html",
"viewport_w": 360.0,
"element_count": 17,
"est_tokens": 1068, // <-- entire page read for ~1k tokens
"report": {
"total_elements": 17,
"visible_elements": 14,
"overlaps": [ ... 7 collisions ... ],
"overflows": [ ... 1 clipped ... ],
"contrast": [ ... 2 AA failures ... ],
"quality": { "score": 0.06, "label": "broken" }
}
}
每项发现都准确且可操作:
| 发现 | 详情 |
|---|---|
| 重叠 | section.row ⇄ div.overlap-right,面积为 20000 px²。绝对定位的框遮住了卡片 |
| 溢出 | div.overflow-bad:右边缘 600 超出视口 360 → 被裁切 |
| 对比度 | 黑色文字位于 blue 上:比例为 2.44:1。未通过 WCAG AA(需要 4.5) |
| 对比度 | 白色背景上的 #cccccc:比例为 1.61:1。未通过 WCAG AA |
这就是它的价值:只需数百个 Token,而非数百 KB,并提供 Agent 能够采取行动并重新验证的确定性答案。
视觉指南:三个入口
Cornea 是一个引擎,三个入口。 三者返回完全相同的检查 JSON,因为它们都通过同一个共享分发器处理请求。
1. CLI:检查文件
cornea <file.html | http(s)://url> [viewport_width] [viewport_height] [--js]
$ cornea page.html 360
{
"html_file": "page.html",
"viewport_w": 360.0,
"element_count": 42,
"json_bytes": 8124,
"est_tokens": 2193,
"report": { "total_elements": 42, "visible_elements": 38, "overlaps": [], "overflows": [], "contrast": [], "quality": { "score": 1.0, "label": "good" } }
}
2. MCP:通过 stdio 提供原生 Agent 工具
cornea --serve
Agent 可以直接调用 layout.* 工具;每次调用时,它会传入页面源代码,或者
实时 URL(参见下文的 URL 捕获):
→ {"method":"tools/call","params":{"name":"layout.overlaps",
"arguments":{"html":"<div style=\"position:absolute;left:20;top:20;width:200;height:100\">A</div>..."
,"width":360}}}
← {"id":1,"result":{"content":[{"text":"[{\"a_sel\":\"...div \u21c4 ...div\",\"area\":20000}]"}]}}
| 工具 | 返回内容 |
|---|---|
layout.inspect | 完整视觉模型 + 报告 |
layout.overlaps | 框发生碰撞的元素 |
layout.overflow | 被裁切 / 折叠 / 位于屏幕外的元素 |
layout.contrast | 文本元素的 WCAG AA 比例 |
layout.quality | 0..1 健康度评分 + 问题列表 |
layout.fidelity | 精确处理与近似处理的 CSS 特性 |
3. HTTP API:可从任何地方调用
cornea --serve-http [addr] # default 127.0.0.1:8080
curl -s -X POST http://127.0.0.1:8080/inspect \
-H 'Content-Type: application/json' \
-d '{"html":"<p style=\"color:#cccccc\">bady</p>","width":360}'
{"total_elements":1,"contrast":[{"selector":"...>p","fg":"#cccccc","bg":"#ffffff",
"ratio":1.61,"pass_aa":false}]}
| 路由 | 方法 | 返回内容 |
|---|---|---|
/inspect | POST | 完整报告 |
/overlaps | POST | 碰撞信息 |
/overflow | POST | 被裁切 / 折叠 / 位于屏幕外的元素 |
/contrast | POST | WCAG 比例 |
/quality | POST | 健康度评分 |
/fidelity | GET | 引擎功能 |
/health | GET | 存活状态 |
监测实时页面(URL 捕获)
每个界面都接受一个 URL,用来替代 HTML。Cornea 会抓取页面,内联其外部样式表和外部脚本(相对 URL 会根据页面解析),然后检查浏览器实际会显示的内容。这就是实时编码会话的循环:运行开发服务器,将 cornea 指向它,然后查看布局判断结果。
cornea http://localhost:3000 390
{ "url": "http://localhost:3000", "width": 390, "height": 844 } // HTTP /inspect
{ "method": "tools/call", "params": { "name": "layout.quality",
"arguments": { "url": "http://localhost:3000", "width": 390 } } } // MCP
关于捕获的说明:
- 抓取失败时会保留原始标签并记录备注,因此报告警告仍会标出未能加载的内容。
- 正数
height会模拟固定视口(截图画面、iframe、电子邮件),并启用首屏以下内容的裁剪检查。默认值 0 表示页面可无限滚动。 - 捕获是某个时间点的快照。确定性由引擎保证:相同的抓取字节始终会生成相同的报告。
- 原生支持普通 HTTP。HTTPS 页面需要 TLS 协议栈,而该二进制文件不包含此协议栈;请从本地 HTTP 开发服务器捕获,或使用你自己的抓取层预先内联页面。
架构
┌─────────────────────────────────────┐
HTML + CSS ──► │ cornea (one binary) │
│ │
│ dom.rs html5ever ──► tree │
│ css.rs <style> + inline │
│ │
│ layout.rs deterministic layout │
│ (block/inline/flex, │
│ box model, z-index) │
│ │ │
│ model.rs Visual Geometry Model │
│ │ │
│ inspect.rs overlap / overflow / │
│ contrast / quality │
│ │ │
│ rest.rs canonical dispatch │
└───────┬─────────────┬───────────────┘
│ │
┌─────┴────┐ ┌────┴───────────────┐
│ CLI │ │ MCP (stdio) / HTTP│
│ cornea │ │ layout.* / REST │
└──────────┘ └────────────────────┘
阅读完整技术规范: CORNEA-ARCHITECTURE.md
忠实度:明确说明近似之处
Cornea 绝不会暗中伪造精度。layout.fidelity 会准确告知 Agent 哪些内容可信,每份报告也都会通过自身的 warnings 标出引擎检测到但未应用的来源(外部样式表、外部脚本、媒体查询、未解析的颜色):
{
"exact": ["box model", "block flow", "inline text estimates", "flex row/column (no wrap)",
"z-index", "visibility", "absolute/fixed left/top", "inline styles",
"class/id/tag selectors", "WCAG contrast (hex, rgb, hsl, alpha)"],
"approximate": ["text glyph width (not shaping)", "flex-grow/flex-basis distribution",
"percentage widths", "overlap semantics ignore intentional stacking"],
"deferred": ["grid (parsed as block flow)", "media queries", "border-radius",
"external stylesheet <link> when not captured",
"complex selectors (combinators, pseudo)"],
"js": {
"engine": "boa",
"phase": "A",
"enabled": "opt-in via --js / js:true",
"dom_shim": "static HTML mirrored in first; getElementById; innerHTML parses markup",
"unsupported": ["async APIs", "event dispatch", "selector engine", "React/SPA mounting (Phase B)"]
}
}
JavaScript 内置页面(阶段 A)
Cornea 可以执行构建 DOM 的内联 <script>,使用的是一个最小化垫片,
然后通过同一个确定性布局引擎处理结果:
cornea page.html 360 --js # inline scripts build the DOM first
{ "html": "<p>…</p>", "width": 360, "js": true } // HTTP /inspect and MCP layout.*
- 脚本运行前,静态 HTML 会镜像到垫片中,因此脚本可以通过
document.getElementById附加到现有节点,而innerHTML会将实际标记解析为元素。静态内容在脚本运行后仍会保留。 style.*赋值会序列化回style="…",并参与重叠和对比度检查。- 不支持异步 API(
setTimeout、fetch,等等),以免挂起。任何此类用法都会显示在报告的js_notes中,从而确保确定性。 - 只有捕获层(URL 捕获)先内联外部
<script src>的内容后,才会运行该脚本。 - 完整的 React/SPA 挂载属于阶段 B(实验性)。进度记录在
ROADMAP-JS.md中。
可视化指南:测试(经实战验证)
使用 cargo test 可顺利运行 54 项测试;CI 会在每次推送时检查 fmt、clippy -D warnings、release 构建、测试和 CLI 冒烟测试。
$ cargo test
Running unittests src/lib.rs ... 36 passed // determinism, overlap, overflow,
Running unittests src/main.rs ... 9 passed // contrast, inline flow, flex,
Running tests/endpoints.rs ... 9 passed // nesting, empty input, MCP, CLI, JS, capture
- 确定性。同一页面检查两次会得到逐字节相同的 JSON(核心理念)。
- Bug 检测。会断言测试样例中的重叠、溢出和对比度失败。
- 端到端。会启动编译后的二进制文件,并通过真实的 stdio MCP 调用
layout.*。 - HTTP。TCP 服务会在临时端口启动,并接收真实请求。
- 实时捕获。通过本地套接字提供真实页面;链接的 CSS 必须改变对比度判断结果。
- 边界情况。空 HTML、深层嵌套(不会崩溃)、
display:none、长文本、flex 行/列布局、内联换行。
布局支持(v1 范围)
| 功能 | 状态 |
|---|---|
| 块级流、盒模型(content/border-box) | 精确 |
| 内联文本片段(水平排列、换行) | 精确 |
| Flex 行/列(简化,不换行) | 近似 |
| 绝对/固定定位(left/top) | 精确 |
z-index、visibility、display:none | 精确 |
.class / #id / tag 选择器 + 内联样式 | 精确 |
| WCAG 对比度(hex、rgb、hsl、alpha、继承颜色) | 精确 |
| 实时 URL 捕获(CSS 和脚本内联) | 支持 |
| Grid、媒体查询、border-radius | 暂缓 |
仓库布局
cornea/
├── Cargo.toml # crate: html5ever + serde/serde_json, release LTO+strip
├── README.md # this file
├── CORNEA-ARCHITECTURE.md # full technical spec
├── src/
│ ├── lib.rs # build_model / analyze pipeline + unit tests
│ ├── dom.rs # html5ever -> lightweight element tree
│ ├── css.rs # <style> + inline style resolution
│ ├── fetch.rs # live URL capture: GET + css/script inlining
│ ├── layout.rs # deterministic layout engine
│ ├── model.rs # VisualModel / ElementView / Rect
│ ├── inspect.rs # overlap / overflow / contrast / quality / warnings
│ ├── rest.rs # canonical endpoint dispatch (shared by all surfaces)
│ ├── main.rs # CLI + stdio MCP server
│ └── server_http.rs # dependency-free HTTP/1.1 API
├── tests/
│ ├── endpoints.rs # end-to-end CLI + MCP binary tests
│ └── fixtures/sample-bugs.html # known-bug fixture for CI smoke
└── .github/workflows/ci.yml
状态
可用的 MVP,经过强化并经受了实战检验。 确定性检查引擎,支持 CLI、MCP 和 HTTP API,具备实时 URL 捕获、折叠线以下检查、报告警告、54 项测试全部通过、CI 通过,以及 Phase A 内联脚本渲染(--js)。路线图将逐步扩展,让 Cornea(以及姊妹项目文本转图像项目 Crayon)在后续阶段具备更丰富的感知能力。
发布
Cornea 通过四种方式分发:npm(npm install -g optrex,提供 cornea 命令)、crates.io(cargo install cornea)、GitHub Release + Homebrew(brew install),以及 MCP Registry(Agent 可发现 layout.* 工具)。这些发布方式都已在此仓库中配置。令牌、server.json 清单以及发布/打标签流程详见 PUBLISHING.md。
mcp-name: io.github.AbduljabbarBXR/cornea
许可证
MIT。请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。