Create and edit diagrams on a live Excalidraw canvas using the Excalidraw MCP server. Use when asked to draw, diagram, sketch, or visualise architectures, workflows, data flows, system designs, flowcharts, mind maps, or sequence diagrams. Trigger phrases include "create an excalidraw", "draw me a diagram", "make a flowchart", "visualise the system", "diagram this architecture", "export to PNG/SVG". Can export to PNG, SVG, .excalidraw file, or a shareable URL. Do NOT use for Draw.io or diagrams.net output (use drawio-mcp-diagramming instead).
npx skills add https://github.com/thomast1906/github-copilot-agent-skills --skill excalidraw-mcp-diagramming
Create diagrams on a live Excalidraw canvas that renders in the browser and
updates in real time. You are not generating a static file — you are painting
onto a shared whiteboard through MCP tools. The canvas persists between calls,
so what you put on it in one call is visible in the next screenshot.
drawio-mcp-diagramming for that)..excalidraw file, or a shareable URL.The excalidraw MCP server must be present in .vscode/mcp.json:
{
"servers": {
"excalidraw": {
"type": "http",
"url": "https://mcp.excalidraw.com"
}
}
}
If the MCP tools are not available, tell the user to add the server and reload
VS Code, then stop.
Essential — use on every diagram:
| Tool | Purpose | When |
|---|---|---|
| read_diagram_guide | Returns server-side colour palette and sizing rules | First call — before any elements |
| batch_create_elements | Creates multiple shapes and arrows atomically | Main workhorse |
| get_canvas_screenshot | Returns a photo of the current canvas | After every change — verify before continuing |
| clear_canvas | Wipes all content | Start of every new diagram |
| set_viewport | Scrolls and zooms to fit content | After creating elements |
Secondary — use when needed:
| Tool | When |
|---|---|
| create_from_mermaid | Quick drafts — 3–8 node sequential flows |
| update_element | Small corrections (position, colour, text) |
| export_to_image | User requests PNG or SVG file |
| export_scene | User requests editable .excalidraw file |
| export_to_excalidraw_url | User wants a shareable link |
| describe_scene | Audit what is currently on the canvas |
Mermaid path — use for simple sequential flows (3–8 nodes, no zones):
create_from_mermaid(
mermaidDiagram="graph TD; A[Frontend] -->|REST| B[API]; B -->|SQL| C[DB]"
)
Then jump to Step 6 (screenshot). Skip Steps 2–5.
Batch path — use for everything else: layered architectures, data flows,
hub-and-spoke, any diagram needing zones or colour-coded roles. Continue below.
read_diagram_guide()
Retrieve the server's current colour palette and sizing rules. This call is
mandatory — the values may differ from the defaults in this skill. The server
guide takes precedence.
clear_canvas()
get_canvas_screenshot() // must verify the canvas is truly empty
Previous diagrams leave ghost data even after clear_canvas. If any element
is visible in the screenshot, call clear_canvas() again before proceeding.
Do not skip this confirmation — ghost elements silently break arrow bindings
on new diagrams.
Before writing any JSON, decide:
for coordinate templates. Load it now if you are unsure which pattern fits.
Budget 440px column pitch (230px box + 210px gap) for labeled arrows.
arrows, labels, and breathing room).
Zone background: y = row_y - 50, height = box_height + 100.
Sketch coordinates to paper or comments before writing the batch payload.
Call batch_create_elements with all elements in one payload. Arrow
binding resolves at batch time — if the target shape and arrow are not in the
same call, the arrow will not connect.
Element order within the elements array matters for render layering:
id to eachstartElementId / endElementIdget_canvas_screenshot()
Inspect the image:
Load references/iterative-refinement.md if
the user asks to change, fix, or update an existing diagram. Quick reference:
Audit first:
describe_scene() // returns all element ids, types, labels, positions
Use this before any edit — you need the exact element id to target.
Small corrections (label text, colour, position):
update_element({ id: "box-1", text: "New Label" })
update_element({ id: "box-1", backgroundColor: "#b2f2bb" })
Then get_canvas_screenshot() to verify.
Shape replacement (size, shape type, structural change):
batch_create_elements([{ "type": "delete", "ids": "old-id" }, ...newShapes, ...newArrows])
Arrows bound to the deleted shape must also be deleted and recreated in the
same batch — binding cannot be re-attached after the fact.
Decision rule:
| Change | Method |
|---|---|
| Text / colour / opacity / position | update_element |
| Shape size, shape type | delete + redraw in one batch |
| Moving an arrow endpoint | delete + redraw arrow in one batch with target shape |
| Restructuring a zone (adding/removing shapes) | delete zone bg + all children + redraw all in one batch |
set_viewport({ scrollToContent: true })
// PNG or SVG
export_to_image({ format: "png", filePath: "/path/to/output.png" })
// Editable JSON file
export_scene({ filePath: "/path/to/output.excalidraw" })
// Shareable link — no file needed
export_to_excalidraw_url()
Minimum font sizes — never go smaller. Labels that look correct in JSON are
frequently unreadable in screenshots at display scale.
| Context | Minimum fontSize | Notes |
|---|---|---|
| Shape labels / body text | 16 | Default for all labeled boxes |
| Diagram title | 24 | Standalone text above the diagram |
| Zone / section heading | 16 | Inside or above zone background |
| Secondary annotations | 14 | Data form notes, layer labels only — use sparingly |
| Absolute minimum | 14 | Never use below 14 under any circumstance |
Camera scale warning: At XXL (1600×1200) the canvas renders at roughly
40% of original size in the chat panel. A fontSize: 14 label renders at
~5px — invisible. Use fontSize: 20+ for any label that must be readable
without the user zooming in. When in doubt, go larger.
{
"type": "rectangle",
"id": "api-server",
"x": 440, "y": 200,
"width": 230, "height": 160,
"backgroundColor": "#d0bfff",
"strokeColor": "#7048e8",
"roughness": 0,
"text": "API Server\nExpress.js"
}
roughness: 0 — crisp professional edges. roughness: 1 — hand-drawn feel.\n in text creates multi-line labels.rectangle, ellipse, diamond, text (standalone).strokeStyle: "dashed" andopacity: 30.
{
"type": "arrow",
"x": 0, "y": 0,
"startElementId": "api-server",
"endElementId": "database",
"strokeColor": "#2f9e44",
"text": "SQL"
}
x, y are approximate — binding to startElementId/endElementIdoverrides position. The server auto-routes to the nearest edges.
startArrowhead / endArrowhead: "arrow", "dot", "bar", or null.strokeStyle: "dashed" — async or optional flows.strokeStyle: "dotted" — weak dependency.Read references/color-palette.md for the full
semantic colour table — load it when choosing colours for a new diagram type.
| Role | Fill | Stroke |
|---|---|---|
| Frontend / UI | #a5d8ff | #1971c2 |
| Backend / API | #d0bfff | #7048e8 |
| Database | #b2f2bb | #2f9e44 |
| Queue / Events | #fff3bf | #fab005 |
| External / Third-party | #ffc9c9 | #e03131 |
| Zone background | #e9ecef + opacity:30 | #868e96 dashed |
Rule: Same architectural role → same colour pair. Limit diagrams to 3–4
fills. More colours add noise, not clarity.
Run through this before calling set_viewport. Fix any failures before
finishing — they compound and are harder to fix after zooming out.
Arrow bindings
startElementId and endElementId referencingelements that exist in the same batch
Typography
fontSize ≥ 16fontSize ≥ 2414 anywhere\n) have enough box height (≥ 60px per line)Colour discipline
opacity: 25–40 and strokeStyle: "dashed"Layout and spacing
Viewport
set_viewport({ scrollToContent: true }) called as the final step800×600, 1200×900, 1600×1200)
| Anti-pattern | Why it causes problems |
|---|---|
| Skip screenshot after clear_canvas | Ghost elements silently corrupt new arrow bindings |
| Place arrows before their target shapes in a batch | Arrow IDs reference non-existent shapes — no binding |
| Column gap under 100px | Arrow labels bleed into adjacent shapes |
| Arrows without startElementId/endElementId | Arrow floats, doesn't update when shapes move |
| Skip set_viewport after creation | Diagram is off-screen and user sees a blank canvas |
| Zone backgrounds in a separate later batch | Zones render on top of shapes already on the canvas |
| More than 4 fill colours | Diagram becomes unreadable without a legend |
| fontSize below 16 on shape labels | Unreadable at XL/XXL camera scale |
| Editing a bound arrow with update_element | Binding is preserved but endpoints may drift — delete and redraw |
"Draw me a 3-tier web architecture"
read_diagram_guide() — get coloursclear_canvas() → get_canvas_screenshot() — confirm emptybatch_create_elements([zones..., shapes..., arrows..., titles...])get_canvas_screenshot() — verifyset_viewport({ scrollToContent: true })"Quick flowchart of user login"
create_from_mermaid("graph TD; A[Enter email] --> B[Verify] --> C[Dashboard]")get_canvas_screenshot() — verifyagent-im 会话技能 - 通过 liblib.tv 的 AI 能力生成和编辑图片/视频。覆盖场景包括:生成(文生图、文生视频、图生视频、做动画、画一个xxx、来段xxx)、编辑修改(把xxx换成yyy、去掉xxx、加上xxx、改成xxx、调整xxx、局部修改、改镜头)、风格转换(风格迁移、转绘、换风格)、视频续写延长、复刻视频/TVC/宣传片、短剧/短漫剧生成、音乐MV生成、产品广告/展示片制作、分镜/故事板设计、教育视频/短视频制作。当用户提到 liblib、libtv、上传参考图/视频、查看生成进度时也应触发。关键判断:只要用户的请求涉及 AI 图片或视频的创作、生成、编辑、修改,无论措辞如何(如"画只猫"、"做个海报"、"把纸船换成爱心"、"这个视频帮我改一下"、"帮我复刻这段视频"、"用这首歌做个MV"、"一句话生成短剧"),都必须触发此技能。
This skill should be used when the user asks to "generate video prompts", "create Seedance prompts", "write video descriptions", mentions "Seedance", "seedance", "即梦", "即梦平台", "视频提示词", "视频生成", "AI视频", "短剧", "广告视频", "视频延长", or discusses video prompt engineering, AI video generation, or Seedance 2.0 workflows.
Best practices and techniques for writing effective AI video generation prompts. Covers: Veo, Seedance, Wan, Grok, Kling, Runway, Pika, Sora prompting strategies. Learn: shot types, camera movements, lighting, pacing, style keywords, negative prompts. Use for: improving video quality, getting consistent results, professional video prompts. Triggers: video prompt, how to prompt video, veo prompts, video generation tips, better ai video, video prompt engineering, video prompt guide, video prompt template, ai video tips, video prompt best practices, video prompt examples, cinematography prompts
This skill is a practical, 'use-it-while-debugging' reference for getting a LiveKit + Letta voice agent working reliably.
Download screenshot baselines from the latest CI run and commit them. Use when asked to update, accept, or refresh component screenshot baselines from CI, or after the screenshot-test GitHub Action reports differences. This skill should be run as a subagent.
| Turn vague taste, screenshots, URLs, product notes, or "make it feel like this" references into a grounded DESIGN.md plus an implementation handoff. Use it before prototypes, decks, redesigns, or image remix work when the user needs a reusable visual direction rather than a one-off prompt.
>- Upload local assets (images, mockups, extracted HTML, design markdown) to a Stitch project. ALWAYS use this skill when you need to upload visual assets, HTML pages, or design docs to Stitch, particularly when direct MCP tool calls fail or truncate due to base64 token limits.
This skill helps users automatically extract channel-level and video detail data from a specific YouTube channel via BrowserAct API. Agent should proactively apply this skill when users express needs like extracting channel video data, getting latest or popular videos from a YouTube channel, tracking competitor channel content, extracting video metrics such as views likes comments, retrieving subscriber count and channel info, monitoring posting cadence of a YouTube channel, gathering video data for content strategy analysis, getting earliest videos of a YouTube creator, analyzing engagement signals across a full channel, and downloading structured YouTube video details without manual scraping.
Take thomast1906/excalidraw-mcp-diagramming from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.