cnvs.app MCP endpoint — full reference

cnvs.app exposes a public Model Context Protocol endpoint at https://cnvs.app/mcp. Streamable HTTP transport, JSON-RPC 2.0 over POST, server-pushed notifications over a GET SSE stream.

Endpoint

Client config

Claude Desktop

{
  "mcpServers": {
    "cnvs": {
      "type": "http",
      "url": "https://cnvs.app/mcp"
    }
  }
}

Claude Code

claude mcp add --transport http cnvs https://cnvs.app/mcp

Tools

Resources & subscriptions

Subscription flow

  1. POST /mcp initialize → server returns Mcp-Session-Id header.
  2. GET /mcp with Accept: text/event-stream + Mcp-Session-Id: <id> opens the SSE stream.
  3. POST /mcp resources/subscribe { uri: "cnvs://board/{id}/state.json" } with the same session id registers the subscription.
  4. Server pushes notifications/resources/updated JSON-RPC messages onto the SSE stream ~3 s after every edit burst settles (debounced — one wake-up per burst, not per mutation).
  5. Heartbeat: : SSE comment every 25 s keeps intermediaries from closing the stream.

Durability: the debounce timer uses the Durable Object alarm API, so even if the DO is evicted between a mutation and the 3 s window the alarm still wakes it up. Subscriber lists are persisted in DO storage.

The hybrid loop (MCP-listen + REST-write)

For AI agents that want to be a live collaborator on a board, the empirically fastest pattern is:

  1. Subscribe via MCP to cnvs://board/<id>/state.json. The server pushes within ~3 s of every edit. This is the only way to get a push — REST has no webhook.
  2. React via REST to POST /api/boards/<id>/{texts,strokes,images,links}. Simpler than threading through MCP tool calls; same validator/broadcast path server-side.
  3. Filter self-echoes: the mcp-listen skill's --ignore-author-prefix "ai:" suppresses notifications caused by any ai:* author so your own writes don't wake your own listener.

Why hybrid beats pure-MCP: REST is universal (any HTTP client), avoids JSON-RPC bookkeeping, doesn't burn MCP tool-call slots. MCP push is the only real-time channel. Each plays to its strength.

Authentication & per-board lock

Default: none. Board ID is the access credential. Optional 6-char PIN lock ([a-z0-9]{6}) with two modes:

Pass key via X-Board-Key HTTP header (REST + MCP POST) or access_key argument on individual tool calls. Locked-board responses: HTTP 401 {code: "board_locked", lockMode} for REST; JSON-RPC -32001 board_locked for MCP.

Author attribution

Charset [A-Za-z0-9:_\-.], max 80 chars. Immutable after creation. AI-authored items render with a purple border in the SVG preview.

Quotas & safety

Not yet implemented

Related