@xmarts/miro-mcp
v0.1.0
Published
Production-grade Model Context Protocol server for Miro REST API v2 — boards, items, connectors, tags, webhooks, audit logs and ready-to-use workshop templates (kanban, retro, SWOT, BMC, mindmap).
Maintainers
Readme
Miro MCP
Production-grade Model Context Protocol server for the Miro REST API v2. Lets Claude, GPT, or any MCP-compatible AI agent drive Miro boards programmatically — boards, items, connectors, tags, members, webhooks, audit logs, and ready-to-use workshop templates (kanban, retro, SWOT, BMC, mindmap, brainstorm grid).
Built by Xmarts for AI-augmented consulting workflows in LATAM. Apache 2.0 licensed.
What's inside
97 tools organized in 4 tiers, loadable on demand.
| Tier | # | What it gives you |
|-------------|---|-------------------|
| core | 27 | Boards CRUD, items list/get/delete, sticky notes, shapes, text, identity, and the polymorphic create_workshop_board |
| extended | 46 | Cards, app cards, frames, images, documents, embeds, connectors, tags, board members, item groups, layout helpers, native mind-map nodes, code widgets |
| advisor | 23 | Bulk create, webhooks, audit logs, comment events (Enterprise Content Logs), token revocation, board export (PDF/SVG/HTML), enterprise governance (projects, board classification) |
| templates | 1 | create_mindmap_native — Miro's native, auto-laying-out mind map |
The headline feature is
create_workshop_board(incore): one polymorphic tool that scaffolds 36 fully laid-out boards — 30 generic workshops plus 6 Xmarts-native "Visual" templates that turn Brain knowledge, process docs, and Odoo code into diagrams.
Why create_workshop_board is the killer feature
Most Miro MCPs stop at low-level CRUD. Ours adds composite primitives that turn one prompt into a fully laid-out board — picked by a single template discriminator:
"Build a sprint-14 retro with these 5 starter notes…" → create_workshop_board(template="retro")
"Make a Q3 OKR kanban with 4 columns…" → create_workshop_board(template="kanban")
"Lay out our SWOT for Acme based on this brief…" → create_workshop_board(template="swot")Xmarts Visual — knowledge / process / code → diagram
Beyond the 30 generic workshops, 6 Xmarts-native templates encode consulting knowledge a vanilla LLM doesn't have (sourced from the Genius Brain) and reverse-engineer Odoo work into visuals:
| template= | Turns… into a board |
|---|---|
| l10n_country_checklist | the 19-item LATAM fiscal-localization build checklist (per country) |
| implementation_roadmap | the phased Odoo delivery roadmap (Descubrimiento → Go-Live) |
| fiscal_localization_canvas | a country's fiscal setup (authority, EDI, doc types, payroll, repo) |
| process_flow | a process doc (AS-IS/TO-BE .md) → colour-coded flow + checkpoints + GAPs |
| odoo_module_diagram | a custom module's code → ERD (dbdiagram.io-style) |
| odoo_dependency_graph | an instance's modules → layered dependency graph |
Quick start
1. Get a Miro access token
Either:
- Personal/dev token: https://miro.com/app/settings/user-profile/apps → install a custom app → copy the access token, or
- OAuth 2.0 flow (for multi-user / production): https://developers.miro.com/docs/getting-started-with-oauth
Required scopes (minimum): boards:read, boards:write, identity:read. Add team:read for team listing. Enterprise audit logs need auditlogs:read.
2. Install
git clone https://github.com/Bananoman/MiroMCP.git
cd MiroMCP
npm install
npm run build3. Configure
Copy .env.example to .env and set:
MIRO_ACCESS_TOKEN=your_token_here
MIRO_DEFAULT_TEAM_ID= # optional
MIRO_TOOL_TIERS=core,extended,advisor,templates # default = allNote: the server reads
process.envdirectly — it does not auto-load a.env. Put these vars in the MCPenvblock (step 4); a local.envis only used by the test scripts. For board export + enterprise tiers also setMIRO_DEFAULT_ORG_ID.
4. Wire it into Claude
Claude Desktop / Claude Code — add to your MCP config:
{
"mcpServers": {
"miro": {
"command": "node",
"args": ["/absolute/path/to/miro-mcp/dist/index.js"],
"env": {
"MIRO_ACCESS_TOKEN": "your_token_here"
}
}
}
}For Claude Code, this lives at ~/.claude.json under your project entry. Restart Claude after editing.
5. Smoke test
In Claude, ask:
Use the miro mcp
whoamitool to confirm auth works.
You should see your user id, team id, and granted scopes echoed back.
Configuration reference
| Env var | Default | Purpose |
|---|---|---|
| MIRO_ACCESS_TOKEN | required | Bearer token for the Miro REST API |
| MIRO_DEFAULT_TEAM_ID | none | Used when listing boards / creating boards if team_id arg omitted |
| MIRO_API_BASE_URL | https://api.miro.com | Override only for proxy/testing |
| MIRO_MAX_CONCURRENT | 5 | Max in-flight HTTP requests |
| MIRO_MIN_TIME_MS | 350 | Min ms between consecutive requests (rate-limit floor) |
| MIRO_CACHE_TTL_SECONDS | 120 | Cache TTL for GET responses (set 0 to disable) |
| MIRO_TOOL_TIERS | all | Comma list of tiers to load: core,extended,advisor,templates |
| MIRO_LOG_LEVEL | info | error / warn / info / debug |
Tool catalog
A complete list lives in docs/TOOLS.md (auto-generated). Highlights:
Boards — list_boards, get_board, create_board, update_board, delete_board, copy_board
Identity — whoami, revoke_token
Items (any type) — list_items, get_item, delete_item, search_items_by_text
Sticky notes — create_sticky_note, update_sticky_note
Shapes — create_shape, update_shape
Text — create_text, update_text
Cards — create_card, update_card
App cards — create_app_card, update_app_card
Frames — create_frame, update_frame, list_frame_items
Images — create_image_by_url, update_image
Documents — create_document_by_url, update_document
Embeds — create_embed, update_embed
Connectors — list_connectors, create_connector, update_connector, delete_connector
Tags — list_tags, create_tag, update_tag, delete_tag, attach_tag_to_item, detach_tag_from_item, list_item_tags
Members — list_board_members, get_board_member, share_board, update_board_member_role, remove_board_member
Bulk — bulk_create_items
Webhooks — list_webhooks, create_webhook, update_webhook, delete_webhook
Audit logs — list_audit_logs (Enterprise only)
Comments — list_board_comments (Enterprise Content Logs; event metadata only). Miro's REST API v2 has no comments endpoint — comment text is Web-SDK-only. For an API-accessible feedback channel use sticky notes (create_sticky_note + list_items).
Groups — list_groups, get_group, list_group_items, create_group, update_group, ungroup, delete_group_with_items
Layout helpers — move_items, align_items, distribute_items, arrange_in_grid, arrange_in_circle, duplicate_items
Workshop templates — create_workshop_board(template=…) (one polymorphic tool; the 30 layouts are not exposed individually): kanban, retro, swot, business_model_canvas, mindmap, brainstorm_grid, lean_coffee, sailboat_retro, event_storming, customer_journey_map, user_story_map, lean_canvas, okr_tree, raci_matrix, eisenhower_matrix, five_whys, empathy_map, service_blueprint, impact_effort_matrix, north_star_canvas, icp_canvas, persona_card, fishbone, six_thinking_hats, now_next_later_roadmap, speedboat_retro, starfish_retro, pirate_metrics, porter_five_forces, pestle (i18n EN/ES/PT)
Xmarts Visual templates — also via create_workshop_board: l10n_country_checklist, implementation_roadmap, fiscal_localization_canvas, process_flow, odoo_module_diagram, odoo_dependency_graph
Native mind map — create_mindmap_node, list_mindmap_nodes, get_mindmap_node, delete_mindmap_node, create_mindmap_native
Code widgets — create_code_widget, get_code_widget, update_code_widget, delete_code_widget
Board export — create_board_export_job, get_board_export_job, get_board_export_results (Enterprise)
Enterprise governance — create_project, list_projects, get_project, update_project, delete_project, list_project_members, add_project_member, remove_project_member, get_org_classification_settings, get_board_classification, set_board_classification
Facilitation runtime — dot_vote_tally, cluster_stickies_by_position, label_cluster, export_board_summary, export_action_items, set_items_locked
Production hardening
Built in by default:
- ✅ Rate limiting with bottleneck — 5 concurrent / 350ms min spacing, tunable
- ✅ Retry with backoff on 429 and 5xx, honors
Retry-Afterheaders - ✅ GET response cache (
node-cache, 2-min TTL) — mutations auto-invalidate the parent resource - ✅ Typed error hierarchy (
MiroAuthError,MiroNotFoundError,MiroRateLimitError, …) — tools surface errors viaisError: true, never as protocol errors - ✅ Zod input validation on every tool — invalid args caught before hitting Miro
- ✅ Tool annotations (
readOnlyHint,destructiveHint,idempotentHint) so clients can auto-approve safe calls - ✅ Tier filtering via
MIRO_TOOL_TIERSenv — load only what you need (saves LLM context window) - ✅ Graceful shutdown on SIGINT / SIGTERM
- ✅ Stdout reserved for transport — all diagnostics go to stderr
Use cases
See docs/USE_CASES.md for end-to-end recipes — sales workshops, design sprints, retros, BPMN migrations, OKR cascades.
A taste:
| Use case | Prompt | Resulting Miro board | |---|---|---| | Sales discovery | "Build a stakeholder map for prospect Acme based on this LinkedIn data" | Frame with shape-per-role + connectors between reporting lines | | Sprint retro | "Set up a Sprint 14 retro, mad-sad-glad, seed it with these 3 mads from yesterday" | 3-frame retro board with seeded stickies, ready to facilitate | | OKR cascade | "Convert this strategy doc into an OKR mindmap for Q3" | Radial mindmap: company OKR → team OKRs → key results | | BPMN draft | "Diagram this AS-IS payment workflow as shapes + connectors" | Flowchart skeleton ready for stakeholder review |
Architecture
src/
index.ts # Entry — reads env, builds client, registers tools, connects stdio transport
types/miro.ts # Miro REST v2 typings (intentionally loose; LLM sees raw JSON)
core/
MiroClient.ts # axios + bottleneck + retry + cache + error classification
errors.ts # Typed error hierarchy
response.ts # ToolResult helpers (ok/fail/safe wrapper)
pagination.ts # Cursor pagination utility
tools/
index.ts # Tool registry + tier filter
boards/
identity/
items/ # one file per item type (sticky, shape, text, card, …)
connectors/
tags/
members/
bulk/
webhooks/
audit/
templates/ # composite tools (the differentiator)Every domain module exports a factory (client) => ToolDefinition[]. Adding a new domain = add a file + one import in tools/index.ts.
Roadmap
- [ ] OAuth 2.0 + PKCE flow for multi-tenant deployments
- [ ]
create_image_by_base64for inline image upload (currently URL-only) - [ ] More templates: User Story Map, Customer Journey, Service Blueprint, Lean Canvas, OKR Tree, RACI Matrix
- [ ] HTTP / Streamable transport (currently stdio only)
- [ ] Spanish-localized template seed copy
- [ ] CLI mode:
npx miro-mcp create-retro --format=mad_sad_glad
License
Apache 2.0. See LICENSE.
Contributions welcome — see CONTRIBUTING.md.
