Skip to main content
Glama
mirva-ai

mirva-mcp

Official
by mirva-ai

mirva-mcp

MCP server for Mirva. Lets an MCP client — Claude Code, Claude Desktop, or anything else speaking the protocol — work on your boards and canvases with your own account.

Install

Nothing to install: MCP clients run it on demand straight from this repository (an npm release follows).

{
  "mcpServers": {
    "mirva": {
      "command": "npx",
      "args": ["-y", "github:mirva-ai/mirva-mcp#release"],
      "env": { "MIRVA_API_KEY": "your-api-key" }
    }
  }
}

Variable

Required

Default

MIRVA_API_KEY

one of

API key for the account to act as, from its API page. Revocable there; the credential to use.

MIRVA_TOKEN

one of

Session token, as an alternative when no API key is available

MIRVA_URL

no

https://mirva.ai

Server origin

Related MCP server: Miro MCP server

What it does

Tools are provided by the server, not declared here, so the set matches whatever your server offers rather than whatever this package shipped with. That is the point of the design: the capabilities belong to the product, and a client that declared its own would drift.

What a current server offers, by area:

  • Drawings — list and inspect them, join one as a live participant, capture what is on the canvas as a PNG.

  • Painting — create canvases and layers, stroke paths and fills, compose images onto a canvas, and restack, copy, duplicate or remove layers.

  • Boards — read what is on a board and where, draw named sections, move a card, document or section to a new rect, pin a sticky note and rewrite one, and write a rich document.

  • Working with the agent — open a session, send a message with reference images attached, read the reply along with the tools it ran, the images it produced and the layers it added, fetch one of those images, and undo a turn's board edits.

How it works

MCP client ──stdio──> mirva-mcp ──Deepkit RPC / WebSocket──> Mirva

This package is a protocol translator and nothing more. Every operation runs server-side in a session that acts with the authority of the account whose credential you configured — the same permission checks that guard that user in the web app, because it is the same API. Nothing here renders, stores, or bypasses anything.

That also keeps the package small: no native modules and no database, so npx works anywhere Node 20+ does.

The release branch and the vX.Y.Z tags hold the built package; main holds the TypeScript source and is not installable, because Node does not run TypeScript from inside an installed package. Pin a tag (github:mirva-ai/mirva-mcp#v0.2.4) to stay on one version, or #release to follow the latest build.

Viewer

A browser page that shows a board exactly as an agent gets it and drives it with the same tools: every pixel is a capture_drawing PNG and every click is a tool call, so what the page cannot do, the agent cannot do either. It is the way to see what the bridge will do before an agent does it, and to find the gaps.

MIRVA_API_KEY=your-api-key npx -y -p github:mirva-ai/mirva-mcp#release mirva-mcp-viewer

Then open http://localhost:5177. The key stays in the local process, which proxies the page's calls; MIRVA_URL and MIRVA_TOKEN work as above and VIEWER_PORT changes the port. viewer/README.md describes the page.

Security

Either credential acts as the account — treat it like a password. An API key can be revoked from the account's API page without touching the session; a session token cannot, which is why the key is the one to hand out. Anything this server can do, it does as you; it grants no authority you do not already have, and takes none away. There is no separate agent identity and no elevated mode.

Tools

tools/audit-board.mjs reads a board and reports three faults that are hard to see by eye: a canvas referenced by more than one layer — a move that left its old layer behind — cards overlapping each other, and cards sitting outside every section.

MIRVA_URL=http://localhost:8080 MIRVA_API_KEY=<key> \
  node tools/audit-board.mjs <boardId>

It lists the whole board rather than a region on purpose. A region answers only what is inside it, and each of these faults is about something being somewhere you did not think to look.

Testing

npm test runs the geometry behind that audit — seventeen cases covering the pairs that would otherwise pass falsely, such as cards that abut without overlapping, and a card overhanging the section it looks like it is in. It needs no server.

test/hard-cases.mjs exercises the surface adversarially against a running server — malformed arguments, absent and unreadable ids, oversized and unicode input, bound clamping, concurrency, socket loss, and bad tokens.

MIRVA_URL=http://localhost:8080 \
MIRVA_API_KEY=<account key> \
MIRVA_OUTSIDER_TOKEN=<second account, no shared membership> \
MIRVA_BOARD=<a board shortId the account can see> \
  node test/hard-cases.mjs

MIRVA_BOARD enables the board-composition cases, which check that the board tools refuse an unknown board, a half-specified region, a zero-sized section, a nonexistent drawing and an unknown layer. They only read and refuse — nothing in the suite writes to the board you name.

MIRVA_OUTSIDER_TOKEN enables the cross-account cases, which assert that one account cannot read another's drawings or chats and that refusal is byte-identical to not-found — so the tools cannot be used to discover what exists. They are the cases worth keeping honest: removing the server's permission check makes them fail.

License

MIT

Development

The source is TypeScript and runs directly under Node 24 (node src/index.ts, npm run viewer, node tools/soak.ts …); npm run check type-checks the sources, tools and tests, npm test runs the geometry tests, and test/hard-cases.ts exercises a live server. npm run build emits dist/, which is never committed. A release is npm version <x.y.z> followed by npm run release, which type-checks, builds, and publishes the built package to the release branch and a version tag with publish-to-git. The build runs as the package is packed, so a Git install of a published payload runs no build of its own. The commands in bin/ run dist/ when it exists and the sources otherwise, which serves a checkout without a build; an install cannot take that path, since Node refuses TypeScript under node_modules.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    B
    maintenance
    Standalone backend for a self-hosted Excalidraw fork with per-board access control, providing an MCP remote endpoint that lets AI agents draw on real collaboration boards as specific users.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables interaction with Miro whiteboards via MCP and REST API, including board manipulation, sticky notes, shapes, and bulk operations.
    27 npm
    1
    Apache 2.0