Run one command (`claude mcp add`, `codex mcp add`, or a few lines of config for Cursor and Windsurf), point it at a MarkLayer room, and tell the agent to watch it. The server exposes nine tools; the two that matter for a first run are marklayer_watch_annotations (to pull feedback as it arrives) and marklayer_resolve (to close it out with a summary the human sees as a reply). No API key, no dashboard, no account on either side.
https://marklayer.app/s/<id>) is the room.claude mcp add marklayer -- npx -y marklayer-mcp for Claude Code, or the Codex, Cursor, or Windsurf equivalent further down this page. This adds the server with no room attached.--room <share-url> on that same command to connect at startup, or leave it off and tell the agent the URL in your prompt; it calls marklayer_connect_room itself.marklayer_watch_annotations, which blocks until something new arrives.marklayer_acknowledge, marklayer_resolve, marklayer_dismiss, or marklayer_reply call updates the pin's status live for anyone else who has the room open, no refresh needed.| Tool | What it does |
|---|---|
marklayer_connect_room | Connect by share URL or bare room id. Replaces any prior room. |
marklayer_room_info | Page URL, viewport width, timestamps for the connected room. |
marklayer_list_annotations | List annotations, filterable by status. |
marklayer_get_annotation | Full detail and reply thread for one annotation. |
marklayer_watch_annotations | Block until new annotations arrive, then return a batch. The one to loop on. |
marklayer_acknowledge | Mark in_progress, tagged with the agent's name. |
marklayer_resolve | Mark resolved; the optional summary posts as a reply. |
marklayer_dismiss | Mark dismissed with a reason, shown to the human. |
marklayer_reply | Post a reply with no status change, for a clarifying question. |
Four annotation kinds can arrive through any of these: comment (a threaded note, optionally pinned to an element), area and selection (a region or element marked without necessarily attaching text), and inspect (element context alone, no instruction, for handing over a specific node with nothing else attached). Anything pinned to an element carries a target block: CSS selector, a text fingerprint that survives DOM changes, and the detected framework component where one exists, which is what actually lets the agent find the file to edit rather than guess from a description.
Most write-ups of this flow mention four states: open, in progress, resolved, dismissed. There's a fifth, approved, and it's not one the agent can set. It's reserved for the person who filed the annotation confirming the fix actually works after resolved was posted. Filtering marklayer_list_annotations by status and skipping approved results is the practical use: those are closed by a human who already checked, and re-touching them wastes a turn.
The room lives on marklayer.app regardless of what it's pointed at. That means the identical setup connects the agent to a live production page, a staging URL behind basic auth, or a local dev server — the difference is only in how the page itself was annotated (the extension for localhost and authed pages, no install at all for a public URL). If your workflow is specifically "point at an element in my own dev server, nothing else," the localhost + AI agent walkthrough covers that narrower case start to finish; this page is the setup reference for any of them.
Every client below runs the same server, the same nine tools, and the same rooms and statuses. Only the config file's location and format change, and dropping --room <url> from any of them registers the server with no room attached, so the agent calls marklayer_connect_room itself once you give it a share link in the prompt.
Codex stores MCP servers as TOML, not JSON, either globally at ~/.codex/config.toml or scoped to one trusted project at .codex/config.toml:
[mcp_servers.marklayer]
command = "npx"
args = ["-y", "marklayer-mcp", "--room", "https://marklayer.app/s/abc123"]
Or skip hand-editing the file entirely with codex mcp add marklayer -- npx -y marklayer-mcp --room https://marklayer.app/s/abc123.
Cursor reads a mcpServers block from a JSON file: ~/.cursor/mcp.json globally, or .cursor/mcp.json in the repo root to scope it to one project.
{
"mcpServers": {
"marklayer": {
"command": "npx",
"args": ["-y", "marklayer-mcp", "--room", "https://marklayer.app/s/abc123"]
}
}
}
Windsurf uses the identical mcpServers JSON shape as Cursor, in a different file: ~/.codeium/windsurf/mcp_config.json. Same block as above, pasted into that path instead.
Any MCP-capable client works the same way in principle: a command plus args telling it to run npx -y marklayer-mcp (optionally with --room <url>), written wherever that client keeps its MCP config. Zed, Aider, Gemini CLI, Amazon Q Developer, Cline, and Roo Code all support the standard MCP stdio transport this server uses, even though their config file's name and location differ from the four above; check that client's own MCP documentation for the exact path, and everything past that point (the tools, the rooms, the statuses) is identical.
For how this compares to the four other tools that also ship an MCP server for feedback (Marker.io, BugHerd, Jam, Usersnap), see the MCP servers compared breakdown — the short version is that most of them hand the agent a one-way link or a read-only report, where this one is a room the agent is a live participant in.
Almost every first-run failure is the same cause: npx -y downloads the package fresh, and a slow or cold download outlasts the MCP client's own startup timeout, which reads as a generic "connection closed." Run npx -y marklayer-mcp --help once on its own to warm the cache, or skip the download step entirely with a global install (npm i -g marklayer-mcp) pointed at directly. A "room is not connected" error well into a session is a different thing: the room's WebSocket dropped from being idle, and the fix is calling marklayer_connect_room again with the same URL, not starting a new room.
Paste any URL at marklayer.app and annotate the live page in your browser. No install, no account, no sign-up. Recipients of your share links don't need to install anything either.
Annotate a page