For developers & AI agents
cnvs.app speaks the Model Context Protocol and a plain REST API. Claude Desktop, Claude Code and any MCP-capable client can read and edit the same whiteboard or kanban board your teammates are looking at — in real time, with no API key.
01 — Protocol
Strokes and text nodes an AI adds appear instantly for everyone connected, tagged with an ai:<name> author label. The MCP server is a single HTTPS endpoint that accepts JSON-RPC 2.0 over POST:
https://cnvs.app/mcp
No API key, no OAuth. The board ID is the key — anyone who knows the board ID (the bit after the # in the URL) can read and write to that board, just like any human visitor. Keep your board URLs private if the content is sensitive.
Open Settings → Developer → Edit Config and add a streamable HTTP server entry:
{
"mcpServers": {
"cnvs": {
"type": "http",
"url": "https://cnvs.app/mcp"
}
}
}
Restart Claude Desktop. Ask the model to “open the cnvs board at https://cnvs.app/#<your-id> and add a sticky with today's agenda” and the note will land on the live canvas.
claude mcp add --transport http cnvs https://cnvs.app/mcp
02 — Tools & resources
open_boardResolve a cnvs URL or ID; creates the board if it doesn't exist yet.
get_boardFull structured snapshot — ids, coordinates, text content — for precise edits.
get_previewSchematic SVG render (a few kB) so the model can see the layout without blowing up context.
add_textCreate or update a text node. Supports Markdown, Mermaid diagrams, sticky-note style.
add_linkDrop a URL capsule onto the canvas.
add_imagePlace a raster or SVG image from a data URL (capped at ~900 kB).
draw_strokeFreehand stroke from a list of world-coordinate points.
moveReposition an existing text node by id.
eraseDelete a text, stroke or image by id.
wait_for_updateLong-poll: block until the next edit lands (debounced ~3 s), then return — for turn-based loops on clients that don't surface resources/subscribe pushes to the model.
set_board_modeSwitch an empty board to draw or todo (kanban). Immutable once the board has content.
create_column / update_column / delete_columnManage kanban columns — title, sort, lane and colour.
create_task / update_task / move_task / delete_taskManage kanban cards — name, description, due date, priority, assignee — across columns.
list_tasksRead a whole todo board in one call → { mode, columns, tasks }.
cnvs://board/{id}/state.jsonFull JSON snapshot — best for editing. Image base64 payloads are elided. Supports resources/subscribe.
cnvs://board/{id}/preview.svgCompact SVG preview — best for visual orientation. Tiny pixelated image thumbnails embedded when available.
cnvs://board/{id}/tasks.jsonKanban state of a todo board — { mode, columns, tasks }. Subscribable, so AI agents react to card moves and edits in real time.
03 — Realtime
Standard MCP Streamable-HTTP session flow: initialize returns an Mcp-Session-Id header, the client opens GET /mcp with Accept: text/event-stream to hold the notification stream, and resources/subscribe returns a plain JSON result. The server then emits notifications/resources/updated onto the GET stream whenever anyone (human or AI) edits a subscribed board — aggregated into a single event ~3 seconds after activity settles, so a burst of strokes or typing produces one wake-up rather than dozens. Claude Desktop and Claude Code pick this up automatically once the capabilities.resources.subscribe capability is advertised. Same live sync humans see in the browser — see real-time collaboration.
Most chat-UI MCP clients consume the push inside their session cache but never re-invoke the model on it — so the AI stays blind to edits until the user prompts again. Two Agent Skills close this loop: /cnvs-whiteboard/SKILL.md (primary skill that owns the cnvs.app read/write workflow) and /mcp-listen/SKILL.md (generic listener — runs a tiny @modelcontextprotocol/sdk client under Claude Code's Monitor tool, so each push becomes a real in-chat notification that triggers a fresh model turn). No polling, and an optional author filter (--ignore-author-prefix "ai:") stops the AI from waking itself on its own writes. Install both:
mkdir -p ~/.claude/skills/mcp-listen && cd ~/.claude/skills/mcp-listen
curl -O https://cnvs.app/mcp-listen/SKILL.md \
-O https://cnvs.app/mcp-listen/package.json \
--create-dirs -o scripts/listen.mjs https://cnvs.app/mcp-listen/scripts/listen.mjs
npm install
mkdir -p ~/.claude/skills/cnvs-whiteboard && cd ~/.claude/skills/cnvs-whiteboard
curl -O https://cnvs.app/cnvs-whiteboard/SKILL.md
Skill sources: cnvs-whiteboard/SKILL.md · mcp-listen/SKILL.md · listen.mjs · package.json. mcp-listen works against any Streamable-HTTP MCP server with resources/subscribe, not just cnvs.app.
curl -X POST https://cnvs.app/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "add_text",
"arguments": {
"board_id": "<your-board-id>",
"x": 200, "y": 160,
"content": "Hello from MCP!",
"postit": true
}
}
}'
04 — Limits & safety
Quotas are applied equally to browser, REST and MCP clients — an AI agent gets exactly the same surface and the same ceilings as a human in a tab.
/quotas.json for live values.Content-Length and during the streaming read.Access-Control-Allow-Origin: * on every public HTTP endpoint so browser-based clients can GET snapshots and POST mutations cross-origin without a proxy.-32000 with a human-readable message.ai:<label> for AI, user:<uuid> for humans) so the origin of each item is preserved.open_board creates new boards.