Excalidraw Skill
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).
- Skill ID
- lingzhi227/agent-research-skills/excalidraw-skill
- Publisher
- lingzhi227
- Repository
- agent-research-skills
- Installs
- 0
- Files
- 9
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
lingzhi227/agent-research-skills/excalidraw-skillInstalls these files- SKILL.md
- references/cheatsheet.md
- scripts/clear-canvas.cjs
- scripts/create-element.cjs
- scripts/delete-element.cjs
- scripts/export-elements.cjs
- scripts/healthcheck.cjs
- scripts/import-elements.cjs
- scripts/update-element.cjs
What this skill tells the agent
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)
mcp-cli tools | grep excalidrawIf you see tools like excalidraw/batch_create_elements → use MCP mode. Call MCP tools directly.
Check 2: REST API (Fallback — works without MCP server)
curl -s http://localhost:3000/healthIf 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 browser 5. (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": "...").
More from lingzhi227
Use this skill in a project
Open any RiverX project, search the Skills panel for lingzhi227/agent-research-skills/excalidraw-skill, and install it in one click.
