Miro MCP server
Enables interaction with Miro boards via MCP tools, supporting listing items, creating stickies, frames, shapes, connectors, and manipulating mind maps.
README
Miro MCP server (custom)
TypeScript Model Context Protocol server that talks to the Miro REST API v2 (plus experimental mind map endpoints under v2-experimental). It exposes tools for listing board items, board metadata, native mind maps, creating stickies, frames, shapes, and connectors, and updating, moving, or deleting items. The host (Cursor, Claude Desktop, or another MCP client) spawns this process over stdio; the model decides when to call each tool from the tool descriptions.
Requirements: Node.js 18+, a Miro OAuth access token with boards:read and boards:write.
Setup
1. Clone the repository
git clone https://github.com/DChuhin/miro-mcp-server.git
cd miro-mcp-server
Use your fork’s URL if you cloned from elsewhere.
2. Install dependencies and build
npm install
npm run build
The MCP entrypoint is dist/index.js. Re-run npm run build after changing TypeScript sources if your client runs the compiled file (see Cursor / Claude below).
3. Miro token and board ID
Token (required for the server to call Miro)
- In Miro, open the Developer / Your apps area and create an app.
- Enable scopes
boards:readandboards:write. - Complete the OAuth flow to obtain an access token (see Miro OAuth).
You can keep secrets out of the shell by copying the example env file:
cp .env.example .env
# Edit .env and set MIRO_TOKEN=...
For Cursor and Claude Desktop, the most reliable approach is to put MIRO_TOKEN in the MCP config’s env block (see below). The spawned process may not load .env unless the client sets the working directory to the project root.
Never commit .env or paste tokens into chat.
Board ID (required in normal use)
Tools take a board_id argument. The model needs the board ID whenever you ask for board-specific work. Find it in the board URL: the segment after /board/ (example shape: uXjVGnXi5V0=). Mention it explicitly in prompts, for example: “On board uXjV…, list sticky notes.”
The server does not read a default board from the environment for MCP tool calls. MIRO_BOARD_ID is only useful for the optional integration test script (see Development).
Cursor
- Complete setup steps 1–3 (clone,
npm install,npm run build, obtain a token). - Open Cursor Settings → MCP (or edit the MCP config file directly). Cursor commonly uses
~/.cursor/mcp.json.
Example (replace the path with the absolute path to this repo on your machine):
{
"mcpServers": {
"miro-custom": {
"command": "node",
"args": ["/absolute/path/to/miro-mcp-server/dist/index.js"],
"env": {
"MIRO_TOKEN": "your_miro_oauth_token_here"
}
}
}
}
Alternative (development): point args at tsx and the TypeScript entry so you can skip npm run build while iterating:
{
"mcpServers": {
"miro-custom": {
"command": "npx",
"args": ["tsx", "/absolute/path/to/miro-mcp-server/src/index.ts"],
"env": {
"MIRO_TOKEN": "your_miro_oauth_token_here"
}
}
}
}
Reload MCP servers or restart Cursor after saving the config.
Claude Desktop
- Complete setup steps 1–3 (clone,
npm install,npm run build, obtain a token). - Edit Claude Desktop MCP configuration (location varies by OS; search for
claude_desktop_config.jsonin Claude’s documentation). - Under
mcpServers, add the same shape as in Cursor, using the absolute path todist/index.js:
{
"mcpServers": {
"miro-custom": {
"command": "node",
"args": ["/absolute/path/to/miro-mcp-server/dist/index.js"],
"env": {
"MIRO_TOKEN": "your_miro_oauth_token_here"
}
}
}
}
Restart Claude Desktop after changes. Enable the miro-custom server in the app if your client lists MCP servers per conversation.
Sanity check (optional)
npm start
This runs the MCP server on stdio. On its own it will appear to “hang”; that is normal. You normally do not run it in a terminal unless you are debugging—the editor spawns it once MCP is configured.
Using the agent (LLM + tools)
After the MCP server is connected in Cursor or Claude:
- Open a chat that has MCP tools enabled for this server.
- Give the board ID (from the board URL) when you ask for board-specific work.
- The model can call tools such as
get_board_info,list_board_items,list_mindmap_nodes,create_mindmap_node,delete_mindmap_node,create_sticky_note,create_frame,create_connector,update_item_content,move_item, anddelete_item.
Example prompts:
- “Call
get_board_infofor boarduXjV…and summarize the board.” - “List all sticky notes on board
…, then add a yellow sticky at (100, -50) with the text ‘Review Q2’.” - “Create a frame titled ‘Backlog’ and two stickies inside it connected by a curved connector.”
- “On board
…, calllist_mindmap_nodes, then add a child node under id…with text ‘New branch’.”
Mind maps use Miro’s native widget (text nodes; connectors are managed by Miro). Use list_mindmap_nodes / create_mindmap_node / delete_mindmap_node—not shapes plus create_connector.
Why coordinates? In the desktop app, + uses Miro’s internal layout; the experimental REST create mind map node API still expects a position and defaults omitted coordinates to (0,0), which stacks every node. That endpoint does not expose the same auto-placement as the UI, so this server computes x/y unless you pass them explicitly. Parent positions for that math come from list_mindmap_nodes (or a direct experimental mind map node read), not from generic GET /v2/boards/.../items/{id}—nested mind map nodes can report widget-local coordinates there, which would shift deeper children incorrectly.
Layout rule (this tool): Left-to-right mind maps only—the root is leftmost; every child is placed to the right of its parent (parent.x + offset). Siblings of the same parent share that X column and are spaced vertically using layout_sibling_index (0, 1, 2, …)—pass it when creating several children in a row because list_mindmap_nodes can lag. The create payload must stay within MindmapCreateRequest only. Overview: Mind map (Experimental).
Example hierarchy — use each create response’s id (or list_mindmap_nodes) as the next parent_node_id:
| Order | content |
parent_node_id |
layout_sibling_index |
|---|---|---|---|
| 1 | Center | (omit = root) | (omit) |
| 2 | node1 | Center’s id | 0 |
| 3 | node2 | Center’s id | 1 |
| 4–7 | nebula, quartz, velvet, ember | node1’s id | 0, 1, 2, 3 |
| 8–11 | cascade, prism, lotus, raven | node2’s id | 0, 1, 2, 3 |
Optional: set root position with x / y on the first call (e.g. 1160, 0).
The agent chooses tools based on their registered names and descriptions; you do not call the REST API yourself in normal use.
Development
Run the server with tsx (no separate build step):
npm run dev
Ensure MIRO_TOKEN is set (for example via .env in the project root). The dev server still uses stdio, so it is mainly useful with an MCP client attached or for quick sanity checks.
Optional integration test against a real board (creates and then deletes test widgets unless SKIP_CLEANUP=1):
export MIRO_TOKEN='your_token'
export MIRO_BOARD_ID='board_id_from_url'
npx tsx scripts/miro-integration-test.ts
Compile manually when not using npm run dev with tsx:
npm run build
Project layout
| Path | Role |
|---|---|
src/index.ts |
MCP server entry, registers tools |
src/miro-client.ts |
HTTP client for https://api.miro.com/v2 |
src/tools/items.ts |
list_board_items, get_board_info |
src/tools/mindmap.ts |
list_mindmap_nodes, create_mindmap_node, delete_mindmap_node (experimental API) |
src/tools/create.ts |
Create stickies, frames, shapes, connectors |
src/tools/mutate.ts |
Update content, move, delete |
scripts/miro-integration-test.ts |
Optional real-board test |
Troubleshooting
- 401 / token errors: Regenerate or refresh the OAuth token; confirm
boards:readandboards:write. - Server not listed: Fix JSON in the MCP config, use absolute paths, restart the app.
- Old behaviour after edits: Run
npm run buildagain if the client usesdist/index.js.
License
MIT
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。