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:
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.):
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.):
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
Options
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:
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