Skip to main content
miro-core-workflow-b Manage Miro connectors, images, embeds, app cards, and document items via REST API v2.
Use for visual workflows, embedding content, and building rich board layouts.
Trigger with phrases like "miro connectors", "miro embed",
"miro app card", "miro image upload", "connect miro items".
跳到安装 Skills Marketplace 发现并探索由社区构建的 Agent Skills
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/jeremylongshore/claude-code-plugins-plus-skills --skill miro-core-workflow-b命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
下载 Zip 下载中... jeremylongshore
jeremylongshore/claude-code-plugins-plus-skills
打开 GitHub 仓库 name miro-core-workflow-b description Manage Miro connectors, images, embeds, app cards, and document items via REST API v2.
Use for visual workflows, embedding content, and building rich board layouts.
Trigger with phrases like "miro connectors", "miro embed",
"miro app card", "miro image upload", "connect miro items".
allowed-tools Read, Write, Edit, Bash(npm:*), Bash(curl:*), Grep version 1.6.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","miro","connectors","embeds","app-cards"] compatibility Designed for Claude Code
Miro Core Workflow B — Connectors, Embeds & Rich Items
Overview
Advanced item operations: connectors between items, image uploads, embedded content, app cards for custom integrations, and document items — all via the Miro REST API v2.
Prerequisites
Completed miro-core-workflow-a (boards and basic items)
Access token with boards:read and boards:write scopes
Connectors
Connectors are lines that visually link two items on a board. They replaced "lines" from the v1 API.
Create a Connector
const connector = await miroFetch (`/v2/boards/${boardId} /connectors` , 'POST' , {
startItem : {
id : startItemId,
position : {
x : 1.0 ,
y : 0.5 ,
},
},
endItem : {
id : endItemId,
snapTo : 'left' ,
},
captions : [
{
content : 'depends on' ,
position : 0.5 ,
textAlignVertical : 'top' ,
},
],
shape : 'curved' ,
style : {
color : ,
: ,
: ,
: ,
: ,
: ,
: ,
},
});
. ( );
'#1a1a2e'
fontSize
12
strokeColor
'#1a1a2e'
strokeWidth
2
strokeStyle
'normal'
startStrokeCap
'none'
endStrokeCap
'stealth'
console
log
`Connector ${connector.id} : ${startItemId} → ${endItemId} `
List All Connectors on a Board
const connectors = await miroFetch (`/v2/boards/${boardId} /connectors?limit=50` );
for (const c of connectors.data ) {
console .log (`${c.startItem.id} --[${c.captions?.[0 ]?.content ?? '' } ]--> ${c.endItem.id} ` );
}
Update a Connector
await miroFetch (`/v2/boards/${boardId} /connectors/${connectorId} ` , 'PATCH' , {
captions : [{ content : 'blocks' , position : 0.5 }],
style : { strokeColor : '#ff0000' , endStrokeCap : 'filled_triangle' },
});
Delete a Connector
await miroFetch (`/v2/boards/${boardId} /connectors/${connectorId} ` , 'DELETE' );
Images
Upload Image from URL
const image = await miroFetch (`/v2/boards/${boardId} /images` , 'POST' , {
data : {
url : 'https://example.com/architecture-diagram.png' ,
title : 'System Architecture' ,
},
position : { x : 500 , y : 0 },
geometry : { width : 400 },
});
Upload Image from Base64 Data URL import fs from 'fs' ;
const imageBuffer = fs.readFileSync ('diagram.png' );
const base64 = imageBuffer.toString ('base64' );
const dataUrl = `data:image/png;base64,${base64} ` ;
const image = await miroFetch (`/v2/boards/${boardId} /images` , 'POST' , {
data : { url : dataUrl, title : 'Local Diagram' },
position : { x : 0 , y : 400 },
});
Embed Items Embed external content (URLs rendered as previews).
const embed = await miroFetch (`/v2/boards/${boardId} /embeds` , 'POST' , {
data : {
url : 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' ,
mode : 'inline' ,
previewUrl : '' ,
},
position : { x : -400 , y : 400 },
geometry : { width : 480 , height : 270 },
});
App Cards App cards display custom data from your integration, with structured fields and status indicators.
const appCard = await miroFetch (`/v2/boards/${boardId} /app_cards` , 'POST' , {
data : {
title : 'JIRA-1234: Fix login bug' ,
description : 'Users unable to log in after password reset' ,
status : 'connected' ,
fields : [
{ value : 'High' , iconUrl : '' , fillColor : '#ff0000' , iconShape : 'round' , tooltip : 'Priority' },
{ value : 'In Progress' , fillColor : '#ffd700' , iconShape : 'square' , tooltip : 'Status' },
{ value : 'John Doe' , tooltip : 'Assignee' },
],
},
style : { cardTheme : '#2d9bf0' },
position : { x : 600 , y : 200 },
});
Update App Card Status
await miroFetch (`/v2/boards/${boardId} /app_cards/${appCardId} ` , 'PATCH' , {
data : {
status : 'connected' ,
fields : [
{ value : 'Done' , fillColor : '#00c853' , tooltip : 'Status' },
],
},
});
Document Items
const doc = await miroFetch (`/v2/boards/${boardId} /documents` , 'POST' , {
data : {
url : 'https://example.com/spec.pdf' ,
title : 'Technical Specification v2' ,
},
position : { x : -600 , y : 0 },
});
Building a Visual Workflow Complete example: Kanban-style board with frames, cards, and connectors.
async function buildKanbanBoard (boardId : string ) {
const todoFrame = await miroFetch (`/v2/boards/${boardId} /frames` , 'POST' , {
data : { title : 'To Do' , format : 'custom' },
position : { x : 0 , y : 0 },
geometry : { width : 400 , height : 800 },
});
const doingFrame = await miroFetch (`/v2/boards/${boardId} /frames` , 'POST' , {
data : { title : 'In Progress' , format : 'custom' },
position : { x : 500 , y : 0 },
geometry : { width : 400 , height : 800 },
});
const doneFrame = await miroFetch (`/v2/boards/${boardId} /frames` , 'POST' , {
data : { title : 'Done' , format : 'custom' },
position : { x : 1000 , y : 0 },
geometry : { width : 400 , height : 800 },
});
const card1 = await miroFetch (`/v2/boards/${boardId} /cards` , 'POST' , {
data : { title : 'Design API schema' , description : 'OpenAPI 3.1 spec' },
position : { x : 0 , y : -200 },
parent : { id : todoFrame.id },
});
const card2 = await miroFetch (`/v2/boards/${boardId} /cards` , 'POST' , {
data : { title : 'Implement auth' , description : 'OAuth 2.0 flow' },
position : { x : 500 , y : -200 },
parent : { id : doingFrame.id },
});
await miroFetch (`/v2/boards/${boardId} /connectors` , 'POST' , {
startItem : { id : card1.id , snapTo : 'right' },
endItem : { id : card2.id , snapTo : 'left' },
captions : [{ content : 'blocks' }],
style : { endStrokeCap : 'stealth' , strokeStyle : 'dashed' },
});
}
Error Handling Error Status Cause Solution connectorStartItemNotFound404 Start item deleted Verify both items exist connectorEndItemNotFound404 End item deleted Verify both items exist invalidImageUrl400 URL inaccessible Check URL is publicly reachable imageTooLarge400 File exceeds size limit Resize image before upload embedUrlNotSupported400 URL cannot be embedded Check Miro's supported embed providers
Resources
Next Steps For common errors and troubleshooting, see miro-common-errors.