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 分