mcpField
C
Cornea, deterministic visual inspection

Cornea, deterministic visual inspection

ローカル
github.com/AbduljabbarBXR開発ツール15 週間前に更新

Cornea, deterministic visual inspection について

Corneaは、コーディングエージェント向けの決定論的なWebレイアウト検査エンジンです。CLI、MCP、HTTP APIから利用でき、重なり、はみ出し、コントラスト、ページ品質を構造化モデルで分析し、同じ入力には同じ結果を返します。

主な機能

  1. 01決定論的なレイアウト分析
  2. 02重なりとはみ出しの検出
  3. 03WCAGコントラスト検査
  4. 04ページ品質の評価
  5. 05ライブURLの検査
  6. 06CLI、MCP、HTTPに対応

活用シーン

  1. 01コーディングエージェントが生成した画面の確認
  2. 02開発中のローカルページの検査
  3. 03ページ内テキストの色コントラスト確認

MCP 対応

stdio経由で`layout.*`ツールを公開し、MCPクライアントがHTMLやライブURLを検査して、レイアウトモデルと分析結果を取得できます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

インストール方法は未掲載です

このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。

リポジトリ
パッケージ
cargocornea0.2.2

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

Cornea

AI エージェント向けの決定論的なビジュアル検査。コーディングエージェントに欠けていた目を提供します。

Cornea は、Web ページを構築するコーディングエージェントに、ページを実際に 見る 手段を提供します。トークン消費が少なく、決定論的な構造モデルなので、コンテキストにメガバイト単位のスクリーンショットや生の DOM を投入せずに、正確に推論できます。

エージェントに必要なのはページの 写真 ではありません。必要なのは、レイアウトが壊れているか、壊れているならどのようにかを知ることです。Cornea はすべての要素(ボックス、位置、重なり順、計算済みスタイル)の抽象的な ビジュアルジオメトリモデル を計算し、検査結果を導き出します。重なり、はみ出し、コントラスト、品質を確認し、CLI、MCP、HTTP APIという3つの窓口からネイティブツールとして公開します。

すべてを支える約束はひとつです。同じ入力 → バイト単位で同一の出力。 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 の機能

以下のページを見てください。ソースとしては問題なさそうです。しかし、4つのレイアウトバグが隠れています。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 の基準を満たしていません

これが Cornea の価値です。数百キロバイトではなく、数百トークンで、エージェントが対処し、再検証できる決定論的な結果を得られます。


ビジュアルガイド:3つの窓口

Cornea はひとつのエンジンに、3つの窓口を備えています。すべてが単一の共有ディスパッチを通じて処理されるため、どの窓口でも同一の検査 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 経由のネイティブエージェントツール
cornea --serve

エージェントは 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.quality0..1の健全性スコアと問題の一覧
layout.fidelityCSS 機能のうち、正確に処理されるものと近似されるもの
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}]}
ルートメソッド返される内容
/inspectPOSTレポート全体
/overlapsPOST衝突
/overflowPOST切り取り・折りたたみ・画面外
/contrastPOSTWCAG 比率
/qualityPOST健全性スコア
/fidelityGETエンジンの機能
/healthGET稼働状態

ライブページの監視(URL キャプチャ)

どのインターフェースでも、HTML を指定する場所に URL を渡せます。Cornea はページを取得し、外部スタイルシートと外部スクリプトをインライン化し(相対 URL はページを基準に解決します)、その後、ブラウザーに実際に表示される内容を検査します。これがライブコーディングセッションのループです。開発サーバーを起動し、cornea にその URL を指定して、レイアウトの判定結果を確認します。

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 はエージェントが信頼できる内容を正確に示し、各レポートには、エンジンが検出したものの適用しなかったソース(外部スタイルシート、外部スクリプト、メディアクエリー、未解決の色)を示す独自の 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 など)は、処理が停止したままにならないよう拒否されます。 そのような API の使用はレポートの js_notes に示されるため、決定性が保証されます。
  • 外部の <script src> は、キャプチャレイヤー(URL キャプチャ)がその本文を先にインライン化した場合にのみ実行されます。
  • React/SPA の完全なマウントはフェーズ B(実験的機能)です。進捗は ROADMAP-JS.md で管理されています。

ビジュアルガイド:テスト(実績あり)

cargo test で 54 件のテストがすべて成功します。CI では、プッシュのたびにfmt、clippy -D warnings、リリースビルド、テスト、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
  • 決定性。同じページを 2 回検査すると、バイト単位で同一の JSON が得られます(これが中核となる考え方です)。
  • バグ検出。フィクスチャの重なり、はみ出し、コントラストの失敗をすべてアサートします。
  • エンドツーエンド。コンパイル済みバイナリを起動し、実際の標準入出力を介した 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 の成功に加え、フェーズ A のインラインスクリプトのレンダリング(--js)に対応しています。ロードマップでは、以降のフェーズを通じて、Cornea と姉妹プロジェクトであるテキストから画像を生成する Crayon の知覚能力をさらに高めていきます。

公開

Cornea は npm(npm install -g optrex で cornea コマンドを利用可能)、crates.io(cargo install cornea)、GitHub Release + Homebrew(brew install)、MCP Registry(エージェントから検出可能な layout.* ツール)の 4 つの方法で配布されます。すべてこのリポジトリ内でステージングされています。トークン、server.json マニフェスト、リリース/タグの手順については、PUBLISHING.md を参照してください。

mcp-name: io.github.AbduljabbarBXR/cornea

ライセンス

MIT。詳細は LICENSE を参照してください。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。