earmark
earmark
実行中のアプリで要素をクリックし、変更したい内容を伝えると、コーディングエージェントはCSSセレクタ、ソースファイルと行、コンポーネントパス、計算済みスタイル、ボックスジオメトリを取得します — 「右側のボタンがおかしい」ではなく。
どのフレームワークでも動作します。オーバーレイにビルドステップは不要です。
┌─ browser ──────────────┐ ┌─ broker ────────┐ ┌─ agent ─────────┐
│ click → annotate │ POST │ store + SSE │ MCP │ list / watch │
│ pins, panel, markdown │───────▶│ long-poll │◀──────▶│ ask / resolve │
│ │◀───────│ .earmark/*.json │ │ dismiss │
└────────────────────────┘ SSE └─────────────────┘ └─────────────────┘30秒で試す
npm install && npm run examplehttp://127.0.0.1:5173/examples/vanilla/ を開き、ツールバー(右下)の矢印をクリックするか alt+a を押して、ページ上の任意のものをクリックします。
ランディングページと完全なガイドは、http://127.0.0.1:5173/site/ で一緒に提供されます。ソースは site/index.html にあり、依存関係のない単一の自己完結型ファイルです。
ライブエージェント同期を行うには、2つ目のターミナルでブローカーを実行します:
npm run serverRelated MCP server: vibe-annotations
インストール
npm install -D earmarkimport { createEarmark } from 'earmark';
if (import.meta.env.DEV) {
createEarmark();
}バンドラー不要:
<script type="module" src="/node_modules/earmark/src/index.js" data-earmark-auto></script>オプション
createEarmark({
endpoint: 'http://127.0.0.1:7331', // or false for copy-paste only
hotkey: 'alt+a',
theme: 'auto', // 'auto' | 'light' | 'dark'
persist: true, // keep annotations across reloads
onAnnotate: (annotation) => {},
});エンドポイントはデフォルトでローカルブローカーを指し、何もリッスンしていない場合は静かに機能低下します。オーバーレイは動作を続け、同期ドットがグレーになるだけです。
使い方
ツール | 機能 |
➤ | 要素をクリックします。Shift+クリックで追加し、クリックで確定します。 |
T | テキストを選択 — 正確な文字列は、エージェントに渡せる最もgrepしやすいものです。 |
⛶ | 領域をドラッグします。内部のすべての要素を報告するか、空の領域にフラグを立てます。 |
❊ | 動いているすべてを停止 — CSSアニメーション、 |
☰ | パネル: 確認、削除、エージェントへの回答、マークダウンのコピー。 |
⌘↵ で注釈を保存、esc でキャンセル、alt+a でピッキングを切り替えます。各注釈は高、通常、低の優先度に設定でき、high はエージェント用に最初に並べられます。
コピー&ペーストモード
パネルの マークダウンをコピー をクリックして、エージェントに貼り付けます:
## UI feedback — 1 annotation
- **Page:** http://localhost:5173/dashboard
- **Viewport:** 1440×900 @2x, dark mode
- **Framework:** react
### 1. Export button padding is too tight — needs 10px 16px
- **Element:** `<button>` <ExportButton>
- **Selector:** `[data-testid="export-btn"]`
- **Source:** `src/components/Card.tsx:42:7`
- **Component path:** App › Dashboard › Card › ExportButton
- **Text:** "Export"
- **Box:** 66×37 at (194, 376)
- **Computed:** padding: 7px 13px; border-radius: 8px; font-size: 13px
- **Ancestors:** div.row ← section.card ← mainエージェント同期モード(MCP)
claude mcp add earmark -- npx -y earmark-mcpまたは、プロジェクトの .mcp.json に書き込む場合:
npx earmark-mcp initその1つのプロセスが、MCPサーバーとブラウザが通信するブローカーを実行します。何かが機能していないときは、その理由を尋ねてください:
npx earmark-mcp doctor✓ Node version: v24.12.0
✓ sqlite backend: available
✓ MCP registration: earmark is registered in .mcp.json
✓ Broker: responding on http://127.0.0.1:7331 — 1 annotations, 2 sessions
✓ Browser overlay: http://localhost:5173/ (1 annotations)失敗した各チェックは修正コマンドを出力し、doctor は非ゼロで終了するため、CIで利用できます。
ツール
ツール | 目的 |
| 未処理の作業をマークダウンで返します( |
| 人間が何かを注釈するまでブロックします |
| 完全な返信スレッドを含む1つの注釈 |
| 開いているブラウザタブと、注釈が付けられたルート |
| 生成されたすべての注釈を含む1つのタブ |
| 「確認しました、対応中です」 — ピンが青に変わります |
| 明確化の質問をする — ピンが琥珀色に変わります |
| 要約付きで完了とマーク — ピンが緑に変わります |
| 人間が見る理由を添えて拒否 |
| すべて削除 |
| オーバーレイは接続されていますか? どのエンドポイントを使うべきですか? |
これによって可能になる修正ループ:
watch → acknowledge → read the source path → edit the file → resolve → watchacknowledge は時間のかかる処理で重要です。これがないと、リファクタリングの途中のエージェントは、あなたを無視したエージェントとまったく同じに見えます。青いピンは対応中を意味し、緑は実際に完了を意味します。
フィードバックがあいまいな場合は、推測する代わりに ask を使います。質問はピンに表示され、人間の回答が次の watch を起動します。
ステータス
open → acknowledged → resolved の流れで、エージェントが人間を待っている場合は needs-input、拒否した場合は dismissed になります。ピンは色分けされます: オレンジ、青、緑、琥珀、グレー。
セッション
セッションは1つのブラウザタブであり、1回のページロードではありません。IDは sessionStorage に保持されるため、リロード後も存続します。注釈はそれぞれ独自の page.url を持つため、3つのルートをまたいだセッションは、エージェントに3つの異なるルートを持つ1つのグループを提供します。
SPAナビゲーションも追跡されます: pushState、replaceState、popstate、hashchange はすべてセッションのルートリストを更新します。タブは、SSEストリームが開いている間だけ接続済みと見なされます。
curl http://127.0.0.1:7331/sessionsソースファイルパス
セレクタはエージェントに何をgrepすべきかを伝えます。ソースパスは正確にどこを見るべきかを伝えます。これが1回の編集と3回のgrepの違いです。
React 19はランタイムの _debugSource ファイバーフィールドを削除したため、これはビルド時に行われます:
// vite.config.js
import earmark from 'vite-plugin-earmark';
export default {
plugins: [react(), earmark()],
};vite dev 中、すべての組み込みJSX要素は data-earmark-src="src/Card.tsx:42:7" を取得します。プラグインはオーバーレイも注入するため、アプリコード内の createEarmark() はオプションになります。
earmark({
inject: false, // do not auto-mount the overlay
endpoint: '…', // passed through to createEarmark
applyInBuild: true, // also stamp production builds (off by default)
})プラグインがなくてもすべて動作します。セレクタ、コンポーネント名、テキストは取得できますが、file:line だけは取得できません。data-earmark-src を手動で追加することもできます。
プレーンなHTMLとCSS — ビルドステップ不要
静的サイトにはスタンプするビルドがないため、earmarkは代わりに注釈時にソースを解決します:
HTML — ドキュメントを再取得して位置追跡付きで解析し、ソース内で要素の子インデックスパスをたどります。各ステップはライブのタグ名と照合されるため、フレームワークでレンダリングされたページ(提供されたHTMLが単なるシェルである場合)は、行をでっち上げるのではなく何も報告しません。
CSS — 要素に一致するすべてのルールを、それを宣言しているファイルと行にマッピングします。これはフレームワークの有無にかかわらずどこでも機能します。
- **Source:** `index.html:101:11` _(resolved from the served HTML)_
- **CSS rules that style it:**
- `button` → `index.html (inline <style>):49`
- padding: 7px 13px; border-radius: 8px; border: 1px solid var(--line);
- `button.primary` → `index.html (inline <style>):59`
- background: var(--accent); color: rgb(255, 255, 255);エージェントは、変更する必要があるパディングが汎用の button ルールの49行目にあり、.primary にはないことを知ります。インライン <style> ブロックはホストドキュメント内のオフセットとして扱われます。外部スタイルシートは自身のパスを報告します。クロスオリジンのスタイルシートは、その内容を読み取れないためスキップされます。
スタンドアロンブローカー
npx earmark-server --port 7331
curl http://127.0.0.1:7331/markdownルート | |
| 死活監視 + 件数 |
| 一覧 |
| 作成(バッチ) |
| ロングポーリング |
| ステータス更新 |
| スレッドに追記 |
| 削除 · クリア |
| タブを登録 / ルート変更を記録 |
| タブと、件数と注釈 |
| SSEストリーム。タブの生存シグナルも兼ねる |
| エージェント向けドキュメント |
フラグ: --host --store --file --no-persist --webhook --token --quiet。
ストレージ
--store json(デフォルト)は、250msのデバウンスで読み取り可能な .earmark/annotations.json を書き込みます。--store sqlite は、node:sqlite を介して各変更を即座に .earmark/annotations.db に書き込むため、クラッシュしても実行中のステートメントだけが失われます。依存関係なし、Node 22.5+ で、利用できない場合はJSONにフォールバックします。--store memory は何も保持しません。
ウェブフック
npx earmark-server --webhook https://hooks.example/earmarkさらに EARMARK_WEBHOOK_URL と EARMARK_WEBHOOKS(カンマ区切り)があります。すべての注釈イベントは x-earmark-event ヘッダー付きでPOSTされます。配信は5秒のタイムアウトと1回のリトライでfire-and-forget方式のため、停止したエンドポイントによって注釈ループが止まることはありません。
セキュリティ
これは開発ツールです。
ブローカーは
127.0.0.1のみにバインドします。0.0.0.0にバインドしないでください。CORSは設計上オープンです。開発サーバーは任意のオリジン上にあります。
ブラウザで開いている任意のページがループバックポートに到達できます。お使いのマシンでそれが問題になる場合は
--token SECRETを渡してください。ウェブフックは注釈の内容をマシンの外部に送信します — ページURL、要素テキスト、入力した内容など。自分が管理するエンドポイントだけを設定してください。
ソース解決は、同じオリジンから自分のページとスタイルシートを再取得します。どこにも送信されません。
共有ホストや公開ホストで実行しないでください。
テスト
npm test7つのスイート、88のテスト: ストアとHTTPの動作、実際のstdioクライアントで駆動するMCPサーフェス、オーバーレイの同期クライアント、両方の永続化バックエンド、ウェブフック配信、init/doctor CLI、そしてソースリゾルバ。
非対応
デスクトップブラウザのみ対応。iframe、canvas/WebGLの内部、スクリーンショットには対応していません。未対応の全一覧と各設計判断の理由については plan.md を参照してください。
ライセンス
MIT。クリーンルーム実装 — 他のツールのソースから派生したものではありません。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityDmaintenanceMCP server for visual feedback, video direction, and QA assertions on web pages, enabling AI agents to read, reply, and resolve annotations in real time.4MIT
- Flicense-qualityAmaintenanceMCP server that exposes web page annotations to AI coding agents, enabling automated implementation of visual feedback and design tweaks.1132
- Alicense-qualityCmaintenanceA MCP server that enables AI coding agents to consume structured UI feedback via click-to-annotate, supporting issue types and severity levels.11MIT
- AlicenseAqualityBmaintenanceMCP server that opens a browser and adds a comment/pencil overlay to every page, letting you annotate live sites and send the marks to your coding agent.8MIT
Related MCP Connectors
MCP server for AgentDocs (agentdocs.eu): read, search, write, comment on & share Markdown docs.
A paid remote MCP for AI agent browser approval MCP, built to return verdicts, receipts, usage logs,
A paid remote MCP for AI agent browser DevTools MCP, built to return verdicts, receipts, usage logs,
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/nahar-strativ/Agentic'
If you have feedback or need assistance with the MCP directory API, please join our Discord server