MarkLayer

io.github.thevrus由 GitHub 帳號 thevrus 發布v0.6.1更新於 Oct 31, 2026

Work visual annotations on a live webpage: watch, acknowledge, resolve, reply, or leave your own.

概覽

AI 產生的概覽

把網頁上的 MarkLayer 標註橋接給編碼代理,讓它能讀取、確認、解決、回覆標註,並自行在頁面上留下審查意見。

可以做什麼
  • 連線並檢視審查房間:以分享連結或房間 ID 加入,讀取房間中繼資料,以及被標註頁面的標題、內文、連結與控制項及其選擇器。
  • 讀取並追蹤回饋:列出、取得與監看標註,包含元素定位資訊、回覆串與附加圖片。
  • 處理標註:確認開始處理、附摘要標記為已解決、說明理由後駁回,或僅回覆而不改變狀態。
  • 主動留下回饋:建立評論標註,並以可接受或拒絕的差異形式提出精確的文字修改。
  • 推進審查流程:發布下一步清單、勾選完成步驟、發起多選項投票,並一次讀取彙整回饋。
  • 為預覽或預備環境網址建立新的審查房間,並把連結交給人工查看。
適用情境
適用於人工用 MarkLayer 審查網頁、希望代理把評論當成待辦佇列逐筆處理時;也適用於讓代理審查頁面並留下自己的問題發現與文案修改建議,供人工篩選。
執行需求
透過 npx(Node.js)以 stdio 在本機執行,或使用分享連結對應的遠端端點。需要一個 MarkLayer 房間分享連結或房間 ID,可透過 --room、MARKLAYER_ROOM 或 marklayer_connect_room 提供。選用的 MARKLAYER_AGENT 指定顯示給人工的代理名稱,MARKLAYER_API_BASE 可覆寫服務位址。需要連線至 marklayer.app 的網路。
安裝前請注意
標註、回覆、清單、投票與建議修改都會寫入共用房間,房間內的人都看得到;標記為已解決或駁回會改變審查者看到的狀態。審查者附加的圖片會從評論中提供的網址抓取。房間 ID 等同存取權杖,分享連結應視為機密。未宣告任何身分驗證。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 MarkLayer,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

marklayer-mcp

MCP (Model Context Protocol) server that bridges MarkLayer annotations to AI coding agents.

When users annotate any webpage with MarkLayer, your agent receives the comments as a structured work queue: it can acknowledge, resolve, dismiss, and reply to each one — and the human sees the status updates live. It also works the other way: point an agent at a room and ask it to review the page, and it can leave its own comments and copy-edit suggestions for the human to triage.

Install

You may not need to. Every MarkLayer share link is already a remote MCP server at the same address plus /mcp, so a client that supports remote (Streamable HTTP) servers connects with nothing installed:

bash
claude mcp add --transport http marklayer https://marklayer.app/s/abc123/mcp

Append ?agent=cursor, or any name, so the people in the room see who is working; it defaults to agent. That endpoint is bound to its room, so it has every tool below except marklayer_connect_room.

This package is the stdio version of the same tools, with no Claude-specific wiring. Use it when a client cannot reach remote servers, or when you want one install that covers every room (Claude Code, Cursor, Windsurf, VS Code, Codex CLI, etc.):

bash
# Claude Code:claude mcp add marklayer -- npx -y marklayer-mcp
# Or pre-connect to a specific room:claude mcp add marklayer -- npx -y marklayer-mcp --room https://marklayer.app/s/abc123

For any other MCP client, add a stdio server entry pointing at the same command (adjust the config file/key to your client — Cursor's ~/.cursor/mcp.json, Windsurf's mcp_config.json, VS Code's .vscode/mcp.json, etc.):

json
{  "mcpServers": {    "marklayer": {      "command": "npx",      "args": ["-y", "marklayer-mcp"],      "env": { "MARKLAYER_AGENT": "cursor" }    }  }}

Set MARKLAYER_AGENT (or --agent) to identify which agent this is — it's what humans see as the comment author and the "assigned to" badge, so a non-Claude client should not leave it at the default.

Usage

In your agent prompt:

Watch my MarkLayer annotations. For each one, acknowledge it, make the fix, then resolve it with a summary.

The agent will call marklayer_watch_annotations in a loop and process incoming feedback as it arrives.

Tools

ToolDescription
marklayer_connect_roomConnect to a room by share URL or bare id.
marklayer_room_infoPage URL, viewport width, timestamps.
marklayer_read_pageThe page's headings, text, links and controls, with selectors. Lets the agent review a page nobody has annotated yet.
marklayer_list_annotationsList annotations, optionally filtered by status.
marklayer_get_annotationFull detail + reply thread for one annotation.
marklayer_watch_annotationsBlock until new annotations arrive, return a batch.
marklayer_acknowledgeMark in-progress and tag with this agent.
marklayer_resolveMark resolved, optionally posting a reply with the summary.
marklayer_dismissMark dismissed with a reason the human will see.
marklayer_replyPost a reply without changing status (e.g. clarifying questions).
marklayer_create_annotationLeave a new comment yourself — proactive feedback rather than a response.
marklayer_suggest_editPropose an exact copy/grammar fix for a piece of text, as a diff the human can accept.
marklayer_share_previewOpen a new review room on a URL you built and connect to it. Same repo + branch as the room you are in (or previous) makes it the next version.
marklayer_set_next_stepsPublish an ordered checklist, each step linked to annotation ids. Replaces the previous list.
marklayer_complete_next_stepTick a step off; reviewers see it live.
marklayer_askPut a 2-6 option poll to the room. One vote per reviewer, revotable.
marklayer_get_feedbackOne read: annotation counts by status, open annotations, checklist progress, poll tallies.

Options

--room <url-or-id>   Connect at startup; otherwise call marklayer_connect_room.--api-base <url>     Override worker URL (default https://marklayer.app).--agent <name>       Identifier shown to humans (default "claude-code").

Equivalent env vars: MARKLAYER_ROOM, MARKLAYER_API_BASE, MARKLAYER_AGENT.

Troubleshooting

"Connection closed" on first start. npx -y downloads the package on the first run, and a cold download can outlast the MCP client's startup timeout. Prime the cache once (npx -y marklayer-mcp --help) and reconnect, or install it up front with npm i -g marklayer-mcp and point the client at the binary.

Tools return "room is not connected". The WebSocket dropped — rooms are held open by a Durable Object and a long-idle agent can be disconnected. Call marklayer_connect_room with the same URL to reattach.

Creating rooms programmatically

This server consumes an existing share link. To mint one (or many) from code — e.g. seed a room per page in a batch of URLs before pointing the agent at it — POST directly to the public HTTP API:

bash
curl -X POST https://marklayer.app/api/$ID \  -H 'Content-Type: application/json' \  -d '{"ops":[],"url":"https://example.com/page-1","width":1440,"expires_in":2592000}'# Share link: https://marklayer.app/s/$ID

For a review room on a preview build, POST /api/$ID/preview takes { url, title, repo?, branch?, sha?, note?, questions?, previous? } and never overwrites an existing id. Versions chain only through previous, a room you already hold: two rooms are never linked by repo and branch alone, because the version switcher shows each room's neighbours. marklayer_share_preview calls this route over stdio; over HTTP (/s/:id/mcp) it creates the room in the Worker, chains from the room in the URL, and returns an mcpUrl to reconnect to, since that endpoint stays bound to its own room.

$ID is caller-supplied (use nanoid / crypto.randomUUID() — it's the access token). No auth, no SDK. Full details: https://marklayer.app/llms-full.txt

來源:apps/mcp/README.md,提交 259986f

工具

17

marklayer_read_page

Read the page this room annotates — its headings, paragraphs, links, buttons and labels, each with the CSS selector and tag that locate it. Call this FIRST when asked to review, audit or improve a page and no annotations exist yet: without it you can only answer feedback someone else left, never find anything yourself. Every entry is already in the shape marklayer_suggest_edit and marklayer_create_annotation take, so pass `selector`, `tag` and `markdown` straight through to anchor a mark to the element you are talking about. If the answer says the page renders client-side, the copy is not in the HTML and you should say so rather than review an empty shell.

無需輸入參數。

marklayer_connect_room

Connect to a MarkLayer room (annotation session) by URL or bare room id. Disconnects any prior room.

輸入參數room必填password

marklayer_room_info

Get metadata about the connected room: page URL, viewport width, timestamps.

無需輸入參數。

marklayer_list_annotations

List every annotation in the connected room across all tools (comment, area, selection, inspect). Each entry carries a `kind` discriminator and, where the user marked an element, a `target` block with selector + markdown so you can address the change without reopening the page. Filter by status: open, in_progress, resolved, approved, dismissed, or all (default). `approved` means the person who asked for the change confirmed the fix, so those need nothing from you.

輸入參數status

marklayer_get_annotation

Get full detail for a single annotation of any kind (comment, area, selection, inspect), including its element `target` context and — for comments — the reply thread.

輸入參數id必填

marklayer_watch_annotations

Block until there is work, then return a batch of whatever arrives within a short window. CALL THIS AGAIN IMMEDIATELY EVERY TIME IT RETURNS, including when it returns nothing — an empty result means the window expired, not that the reviewer is done. Nothing pushes work to you: between your calls, a comment someone leaves reaches no one. Keep looping until the person tells you to stop or ends the session. Each event has a `kind`: "new" is an annotation someone just left; "handoff" is one given to you — assigned to you, a reply that @mentions you, or a reply on a thread you already own. A handoff also carries `request`, the reply that asked: read it, it is the instruction, and act on it rather than only acknowledging. Every event carries the full annotation with its `target` element context.

輸入參數batchMstimeoutSeconds

marklayer_acknowledge

Mark an annotation as in_progress and tag it with this agent so the human sees you are working on it.

輸入參數id必填

marklayer_resolve

Mark an annotation as resolved. Pass a summary describing what was changed — it will be posted as a reply to the thread.

輸入參數id必填summary

marklayer_dismiss

Mark an annotation as dismissed when it cannot be acted on. The reason will be visible to the human.

輸入參數id必填reason必填

marklayer_reply

Post a reply to an annotation thread without changing its status. Use to ask clarifying questions.

輸入參數id必填text必填

marklayer_create_annotation

Leave a new comment annotation yourself — proactive feedback (a bug, a UX issue, an accessibility gap, an idea) rather than only responding to a human’s. For an exact text replacement (a copy or grammar fix), use marklayer_suggest_edit instead — it renders as a diff the human can accept, rather than prose describing one. Use this after you have looked at the page with your own tools (a screenshot, a DOM read) and decided something is worth flagging; call it once per finding so each becomes its own pin the human can triage. x/y are document pixels (not viewport pixels — scroll offset already added in). Pass selector + tag + markdown (straight from marklayer_read_page) to pin to that element: the pin sits on the element and follows it when the page reflows, and x/y become optional (a fallback only). Omit all three for a fixed-point pin at x/y.

輸入參數xytagtext必填markdownpriorityselector

marklayer_suggest_edit

Propose an exact replacement for a piece of text on the page — a copy or grammar fix — as a diff the human can accept, rather than a comment describing the change in prose. `rects` are the on-page bounding boxes of `text`, in document pixels: one per line it spans, so a wrapped sentence highlights as several boxes rather than one box swallowing the whole paragraph between its first and last line. Pass selector + tag + markdown together to anchor it to the containing element so it re-resolves if the page reflows.

輸入參數tagtext必填rects必填commentmarkdownpriorityselectorsuggestion必填

marklayer_share_preview

Open a new review room on a page you built — a preview deploy, a staging URL — and get back the link to hand to a human. Call this when you have something for someone to look at, rather than asking them to open a URL and describe what they see. The page is framed live and reviewers annotate it directly; their feedback then reaches you through the other tools. Pass `repo` + `branch` (and `sha`) when the page comes from a branch: a later preview of the same repo and branch becomes the next version of this one, and reviewers can step between versions. Over stdio this also connects you to the new room. Over HTTP the endpoint stays bound to the room in its URL, so reconnect to the returned `mcpUrl` to work the new room.

輸入參數shaurl必填noterepotitle必填branchpreviousquestions

marklayer_set_next_steps

Publish your plan as a short ordered checklist the reviewers see live in the room, distilled from their feedback — one step per change you will make, each naming the annotation ids it answers. Replaces any list you set before. Tick steps off with marklayer_complete_next_step as you finish them, so the humans can watch the work land instead of asking where it is.

輸入參數steps必填

marklayer_complete_next_step

Tick a step of the checklist off (or back on with done: false). Reviewers see it change live.

輸入參數id必填done

marklayer_ask

Put a multiple-choice question to the room — "Which hero variant?", "Ship with the banner?" — when you need a decision rather than open-ended feedback. Each reviewer gets one vote and may change it. Read the tally with marklayer_get_feedback.

輸入參數prompt必填options必填

marklayer_get_feedback

Everything the room has told you, in one read: annotation counts by status with the open ones in full, the next-steps checklist and how far along it is, and every poll with its current tally. Use it to decide what to do next; use marklayer_watch_annotations to wait for more.

無需輸入參數。

版本歷史

3
  1. v0.6.1最新Oct 31, 2026
  2. v0.6.0Oct 17, 2026
  3. v0.5.0Sep 16, 2026

評分

已滿足適用檢查項的 90%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分
  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具必需15 分
  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分