lingzhi227/claude-skills/excalidraw-skill
Claude Code and agent skill by lingzhi227/claude-skills
- community
Checking that the SKILL.md file is still in the repository.
Programmatic canvas toolkit for creating, editing, and refining Excalidraw diagrams via MCP tools with real-time canvas sync. Use when an agent needs to (1) draw or lay out diagrams on a live canvas, (2) iteratively refine diagrams using describe_scene and get_canvas_screenshot to see its own work, (3) export/import .excalidraw files or PNG/SVG images, (4) save/restore canvas snapshots, (5) convert Mermaid to Excalidraw, or (6) perform element-level CRUD, alignment, distribution, grouping, duplication, and locking. Requires a running canvas server (EXPRESS_SERVER_URL, default http://localhost:3000).
Install
npx vskill@latest install lingzhi227/claude-skills/excalidraw-skillSKILL.md
Excalidraw Skill
Step 0: Detect Connection Mode
Before doing anything, determine which mode is available. Run these checks in order:
Check 1: MCP Server (Best experience)
If you see tools like excalidraw/batch_create_elements → use MCP mode. Call MCP tools directly.
Check 2: REST API (Fallback — works without MCP server)
If you get {"status":"ok"} → use REST API mode. Use HTTP endpoints (curl / fetch) from the cheatsheet.
Check 3: Nothing works → Guide user to install
If neither works, tell the user:
The Excalidraw canvas server is not running. To set up:1. Clone:git clone https://github.com/yctimlin/mcp_excalidraw && cd mcp_excalidraw2. Build:npm ci && npm run build3. Start canvas:HOST=0.0.0.0 PORT=3000 npm run canvas4. Openhttp://localhost:3000in a browser5. (Recommended) Install the MCP server for the best experience:```claude mcp add excalidraw -s user -e EXPRESS_SERVER_URL=http://localhost:3000 -- node /path/to/mcp_excalidraw/dist/index.js```
MCP vs REST API Quick Reference
| Operation | MCP Tool | REST API Equivalent | |
|---|---|---|---|
| Create elements | batch_create_elements | POST /api/elements/batch with {"elements": [...]} | |
| Get all elements | query_elements | GET /api/elements | |
| Get one element | get_element | GET /api/elements/:id | |
| Update element | update_element | PUT /api/elements/:id | |
| Delete element | delete_element | DELETE /api/elements/:id | |
| Clear canvas | clear_canvas | DELETE /api/elements/clear | |
| Describe scene | describe_scene | GET /api/elements (parse manually) | |
| Export scene | export_scene | GET /api/elements (save to file) | |
| Import scene | import_scene | POST /api/elements/sync with {"elements": [...]} | |
| Snapshot | snapshot_scene | POST /api/snapshots with {"name": "..."} | |
| Restore snapshot | restore_snapshot | GET /api/snapshots/:name then POST /api/elements/sync | |
| Screenshot | get_canvas_screenshot | Only via MCP (needs browser) | |
| Design guide | read_diagram_guide | Not available — see cheatsheet for guidelines | |
| Viewport | set_viewport | POST /api/viewport (needs browser) | |
| Export image | export_to_image | POST /api/export/image (needs browser) | |
| Export URL | export_to_excalidraw_url | Only via MCP |
REST API Gotchas (Critical — read before using REST API)
- Labels: Use
"label": {"text": "My Label"}(not"text": "My Label"). MCP tools auto-convert, REST API does not. - Arrow binding: Use
"start": {"id": "svc-a"}, "end": {"id": "svc-b"}(not"startElementId"/"endElementId"). MCP tools acceptstartElementIdand convert, REST API requires thestart/endobject format directly. - fontFamily: Must be a string (e.g.
"1") or omit it entirely. Do NOT pass a number like1. - Updating labels: When updating a shape via
PUT /api/elements/:id, include the fulllabelin the update body to preserve it. Omittinglabelfrom the update won't delete it, but re-sending ensures it renders correctly. - Screenshot in REST mode:
POST /api/export/imagereturns{"data": "<base64>"}. Save to file and read it back for visual verification. Requires browser open.
Quality Gate (MANDATORY — read before creating any diagram)
After EVERY iteration (each batch of elements added), you MUST run a quality check before proceeding. NEVER say "looks great" unless ALL checks pass.
Quality Checklist — verify ALL before adding more elements:
- Text truncation: Is ALL text fully visible? Labels must fit inside their shapes. If text is cut off or wrapping badly → increase
widthand/orheight. - Overlap: Do ANY elements overlap each other? Check that no rectangles, ellipses, or text elements share the same space. Background zones must fully contain their children with padding.
- Arrow crossing: Do arrows cross through unrelated elements or overlap with text labels? If yes → use curved/elbowed arrows with waypoints to route around obstacles (see "Arrow Routing" section). Never accept crossing arrows.
- Arrow-text overlap: Do any arrow labels ("charge", "event", etc.) overlap with shapes? Arrow labels are positioned at the midpoint — if they overlap, either remove the label, shorten it, or adjust the arrow path.
- Spacing: Is there at least 40px gap between elements? Cramped layouts are unreadable.
- Readability: Can all labels be read at normal zoom? Font size >= 16 for body text, >= 20 for titles.
If ANY issue is found:
- STOP adding new elements
- Fix the issue first (resize, reposition, delete and recreate)
- Re-verify with a new screenshot
- Only proceed to next iteration after ALL checks pass
Sizing Rules (prevent truncation):
- Shape width:
max(160, labelTextLength * 9)pixels. For multi-word labels like "API Gateway (Kong)", count all characters. - Shape height: 60px for single line, 80px for 2 lines, 100px for 3 lines.
- Background zones: Add 50px padding on ALL sides around contained elements.
- Element spacing: 60px vertical between tiers, 40px horizontal between siblings.
- Side panels: Place at least 80px away from main diagram elements.
- Arrow labels: Keep labels short (1-2 words). Long arrow labels overlap with other elements.
Layout Planning (prevent overlap):
Before creating elements, plan your coordinate grid on paper first:
- Tier 1 (y=50-130): Client apps
- Tier 2 (y=200-280): Gateway/Edge
- Tier 3 (y=350-440): Services (spread wide: each service ~180px apart)
- Tier 4 (y=510-590): Data stores
- Side panels: x < 0 (left) or x > mainDiagramRight + 80 (right)
Do NOT place side panels (observability, external APIs) at the same x-range as the main diagram — they WILL overlap.
Quick Start
- Run Step 0 above to detect your connection mode.
- Open the canvas URL in a browser (required for image export/screenshot).
- MCP mode: Use MCP tools for all operations. REST mode: Use HTTP endpoints from cheatsheet.
- For full tool/endpoint reference, read
references/cheatsheet.md.
Workflow: Draw A Diagram
MCP Mode
- Call `read_diagram_guide` first to load design best practices.
- Plan your coordinate grid (see Quality Gate → Layout Planning) before writing any JSON.
- Optional:
clear_canvasto start fresh. - Use
batch_create_elementswith shapes AND arrows in one call. - Assign custom `id` to shapes (e.g.
"id": "auth-svc"). Settextfield to label shapes. - Size shapes for their text — use
width: max(160, textLength * 9). - Bind arrows using
startElementId/endElementId— arrows auto-route. set_viewportwithscrollToContent: trueto auto-fit the diagram.- Run Quality Checklist —
get_canvas_screenshotand critically evaluate. Fix issues before proceeding.
REST API Mode
- Read
references/cheatsheet.mdfor design guidelines. - Plan your coordinate grid (see Quality Gate → Layout Planning) before writing any JSON.
- Optional:
curl -X DELETE http://localhost:3000/api/elements/clear - Create elements in one call (use
@file.jsonfor large payloads):
``bash curl -X POST http://localhost:3000/api/elements/batch \ -H "Content-Type: application/json" \ -d '{"elements": [ {"id": "svc-a", "type": "rectangle", "x": 0, "y": 0, "width": 160, "height": 60, "label": {"text": "Service A"}}, {"id": "svc-b", "type": "rectangle", "x": 0, "y": 200, "width": 160, "height": 60, "label": {"text": "Service B"}}, {"type": "arrow", "x": 0, "y": 0, "start": {"id": "svc-a"}, "end": {"id": "svc-b"}} ]}' ``
- Use `"label": {"text": "..."}` for shape labels (not
"text": "..."). - Bind arrows with `"start": {"id": "..."}` / `"end": {"id": "..."}` — server auto-routes edges.
- Size shapes for their text — use
width: max(160, labelTextLength * 9). - Run Quality Checklist — take screenshot, critically evaluate. Fix issues before adding more elements.
Arrow Binding (Recommended)
Bind arrows to shapes for auto-routed edges. The format differs between MCP and REST API:
MCP Mode — use startElementId / endElementId:
REST API Mode — use start: {id} / end: {id} and label: {text}:
Arrows without binding use manual x, y, points coordinates.
Arrow Routing — Avoid Overlaps (Critical for complex diagrams)
Straight arrows (2-point) cause crossing and overlap in complex diagrams. Use curved or elbowed arrows instead:
Option 1: Curved arrows — add intermediate waypoints + roundness:
The waypoint [50, -40] pushes the arrow upward to arc over elements. roundness: {type: 2} makes it a smooth curve.
Option 2: Elbowed arrows — right-angle routing (L-shaped or Z-shaped):
When to use which:
- Fan-out arrows (one source → many targets): Use curved arrows with waypoints spread vertically to avoid overlapping each other.
- Cross-lane arrows (connecting to side panels): Use elbowed arrows that route around the main diagram — go UP first, then ACROSS, then DOWN.
- Inter-service arrows (horizontal connections): Use curved arrows with a slight vertical offset to avoid crossing through adjacent elements.
Rule of thumb: If an arrow would cross through an unrelated element, add a waypoint to route around it. Never accept crossing arrows — always fix them.
Workflow: Iterative Refinement (Key Differentiator)
The feedback loop that makes this skill unique. Each iteration MUST include a quality check.
MCP Mode (full feedback loop)
- Add elements (
batch_create_elements,create_element). set_viewportwithscrollToContent: true.get_canvas_screenshot— critically evaluate against the Quality Checklist.- If issues found → fix them (
update_element,delete_element, resize, reposition). get_canvas_screenshotagain — re-verify fix.- Only proceed to next iteration when ALL quality checks pass.
REST API Mode (partial feedback loop)
- Add elements via
POST /api/elements/batch. POST /api/viewportwith{"scrollToContent": true}.- Take screenshot:
POST /api/export/image→ save PNG → critically evaluate against Quality Checklist. - If issues found → fix via
PUT /api/elements/:idor delete and recreate. - Re-screenshot and re-verify.
- Only proceed to next iteration when ALL quality checks pass.
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNeutral, 60 of 100Ineffective. 1 run. Evaluated 8 months ago.
Source
- SKILL.md in the repositoryCheckingskills/excalidraw-skill/SKILL.md
Popularity
- Repository stars
- 24
- Repository forks
- 5
- 7-day trend score
- 16
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 5 Apr 2026, 7 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/lingzhi227/claude-skills/excalidraw-skill)