agentsclimarketplace

Excalidraw

Skill vanducng/skills/skills/excalidraw

A daily-driver collection of skills for agentic coding — a portable, agent-agnostic catalog managed with the vd CLI.

Install
npx -y skills add vanducng/skills --skill excalidraw

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

MANDATORY prerequisite for ALL Excalidraw MCP tool usage. Read BEFORE calling any Excalidraw tool (batch_create_elements, create_element, update_element, etc.). Without the sizing formulas, two-batch ordering (shapes-then-arrows), compact legends, domain styling presets, and write-check-review cycle in this skill, diagrams have invisible arrows, truncated text, and inconsistent colors. Use whenever the user asks to draw, sketch, visualize, or diagram anything technical - system architecture, microservices topology, C4 diagrams, data pipelines / ETL flows / lakehouse, sequence diagrams, ER diagrams, deployment / Kubernetes diagrams, network topology, flowcharts, decision trees. Includes ready-to-apply color palettes for software engineering, system architecture, and data solutions.

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

18.8 KB, as published. Nobody here has run it

Excalidraw - Technical Diagram Skill

Build professional, consistent Excalidraw diagrams via MCP. Skill covers: tool mechanics, sizing formulas, write-check-review verification cycle, and domain-specific styling presets for software engineering, system architecture, and data solutions.

Step 0 - Detect Connection

Check in order:

  1. MCP server: tools prefixed mcp__excalidraw-mcp__* (e.g. batch_create_elements, describe_scene) available → use MCP mode. This is the default for this user.
  2. REST fallback: only if MCP missing - curl -s $EXPRESS_SERVER_URL/health returns {"status":"ok"}.
  3. Nothing → auto-bootstrap the MCP config (see below), then tell user to reconnect the MCP so it registers. Do not fake output.

Auto-bootstrap .mcp.json

When neither the MCP tools nor the REST fallback are available:

  1. Resolve project root: git rev-parse --show-toplevel (fallback to CWD if not a git repo). Inside a git worktree this correctly returns the worktree itself - .mcp.json must live at the working root the session runs in, so the MCP registers for that session.

  2. Derive project name = basename of the project root.

  3. If <project_root>/.mcp.json does not exist, create it with this exact template (substitute <project_name>):

    {
      "mcpServers": {
        "excalidraw-mcp": {
          "type": "http",
          "url": "https://mcp.dataplanelabs.com/excalidraw/mcp",
          "headers": {
            "Authorization": "Bearer ${EXCALIDRAW_MCP_TOKEN}",
            "X-Tenant-Id": "<project_name>"
          }
        }
      }
    }
    
  4. If .mcp.json already exists, merge - add the excalidraw-mcp entry under mcpServers without clobbering other servers. Skip if excalidraw-mcp already present.

  5. Tell the user: file written, ensure EXCALIDRAW_MCP_TOKEN is exported in shell env, then reconnect before re-running the skill - Claude Code: restart it (or run /mcp). Codex: the .mcp.json above is Claude Code-specific; register the same server with codex mcp add excalidraw-mcp or add [mcp_servers.excalidraw-mcp] (url + headers) to ~/.codex/config.toml, then restart Codex.

Never write the bootstrap file outside the resolved project root, and never echo the token value.

The remote canvas (when this user's MCP is used) is at https://draw.dataplanelabs.com. For visual verification beyond get_canvas_screenshot, use Chrome DevTools MCP to take_screenshot of the canvas URL - get_canvas_screenshot sometimes returns blank PNGs.

Step 1 - Tenant & Project Setup

The remote Excalidraw MCP is multi-tenant. Tenant is selected via the X-Tenant-Id header (configured in .mcp.json) or via tools.

Before any drawing:

  1. list_tenants - confirm active tenant
  2. list_projects - confirm active project; switch_project with createName if a fresh canvas is wanted
  3. describe_scene - read existing diagram zones + suggested next placement coordinates

Never call clear_canvas unless the user explicitly says wipe. Place new diagrams spatially offset (≥300px) from existing ones.

Core Principles (Read Before Any Diagram)

1. Write → Check → Review → Fix (Mandatory Loop)

WRITE batch → set_viewport(scrollToContent: true) → screenshot
  → REVIEW against Quality Checklist → FIX issues → re-screenshot
    → only proceed when all checks pass

2. Use batch_create_elements - Not create_from_mermaid

create_from_mermaid produces overlapping text and broken layouts. Use it only as a quick preview, never for final output. For quality, always plan coordinates and call batch_create_elements.

3. Two Batches: Shapes First, Arrows Second

Arrow binding (startElementId/endElementId) requires shapes to exist already. Mixing in one batch causes binding errors.

4. roughness: 0 for Technical Diagrams

Excalidraw defaults to hand-drawn (roughness > 0). For professional system / data / architecture diagrams, set roughness: 0 on every element. Use strokeWidth: 2 for arrows.

5. Multi-Diagram Canvas

Never clear canvas between diagrams. Place side-by-side or stacked with ≥300px gap. Add a title text element (fontSize 24-28) above each. Group with group_elements so describe_scene reports it as a named zone.

6. Add a Compact Legend When It Clarifies

Include a small legend whenever colors, shapes, stroke styles, or arrow colors encode non-obvious meaning. Keep it minimal:

  • Trigger: 3+ semantic node colors, 2+ arrow styles/colors, or mixed ownership/status meanings (internal/external, allow/deny, batch/stream).
  • Size: 3-5 entries total; include only semantics actually used in the diagram.
  • Placement: top-right or bottom-right whitespace, outside primary flow paths; fontSize 13-14.
  • Content: one swatch/mini-line + a short label (Stream, Batch, External, Denied).
  • Skip it when labels already make the encoding obvious and the diagram only uses 1-2 semantic styles.

Do not build a full catalog. A legend should explain the visual language, not duplicate every node or edge label.

Sizing Rules (Prevents Truncation)

Excalidraw's font is ~30% wider than typical sans-serif. Use these formulas:

ShapeWidthHeightfontSize
Rectanglemax(200, chars * 11)70 (1 line) / 80 (2) / 100 (3)16-20
Diamond (text uses ~50% of bbox - double)max(400, longestLine * 18)max(160, lines * 50)16
Ellipse (text ~60% of bbox)max(280, chars * 14)max(65, lines * 35)16-18
Title text--24-28

Arrow Visibility (Prevents Invisible Arrows)

Bound arrows shrink to gap_between_shapes - 16 (8px binding padding each side). Below 80px, arrows vanish.

DirectionMin gapRecommended
Vertical80px120px
Horizontal100px140px
gap = nextShape.y - (currentShape.y + currentShape.height)

Domain Styling Presets

Pick the preset matching the diagram type. Apply fill + stroke + shape per row. Don't mix palettes within one diagram unless intentional.

Active Color Budget

Use at most 5 active semantic colors in any one diagram. Similar components share one color family: all internal services together, all data stores together, all compute/jobs together, all external systems together, all security/blocked paths together.

Treat long preset tables as menus, not a requirement to use every color. If the diagram needs more than five meanings, keep the color and vary shape, stroke style, arrow width, grouping boundary, or label. Neutral gray boundaries/backgrounds and black/white text do not count against the 5-color budget.

Minimal Legend Defaults

Use these entries only when the matching semantics appear in the diagram:

MeaningLegend mark
Sync/API callblue solid arrow #1976d2, width 2
Batch/data loadgray solid arrow #757575, width 2
Stream/eventorange solid arrow #f57c00, width 3
Async/queueorange dashed arrow #f57c00, width 2
Lineage/dependencypurple dotted arrow #9c27b0, width 1
Denied/security blockred solid arrow #d32f2f, width 3

For node legends, show only the shape/color roles that are not already obvious from labels, such as Internal service, External system, Database, Queue, or Security boundary.

Software Architecture (C4 / Microservices)

RoleShapeFillStrokeLabel format
Person / Actorhexagon or ellipse#fff3e0#f57c00User\n[Person]
Software System (Context)rectangle#e3f2fd#1976d2My System\n[Software System]
Containerrounded rectangle#a5d8ff#0d6efdAPI Gateway\n[Container: Node.js]
Componentrectangle#b9e0fb#0c8599OrderHandler\n[Component]
Databasecylinder approx (rect + ellipse top)#f3e5f5#7b1fa2Orders DB\n[PostgreSQL]
External systemrectangle, dashed stroke#fce4ec#c2185bStripe\n[External]
Async / Message Queuehexagon#f0f4c3#827717Order Events\n[Kafka topic]
Cacherounded rectangle#b2dfdb#00695cSession Cache\n[Redis]

Rule: all elements in one C4 view share the same abstraction level. Don't mix Container with Component shapes in one diagram - split into two.

Cloud Architecture (AWS / GCP / Azure)

Color by service category, label by service name + bracket type:

AWS CategoryFillStrokeExamples
Compute#ffe0b2#f57c00EC2, Lambda, ECS, Fargate
Storage#c8e6c9#388e3cS3, EBS, EFS, Glacier
Database#ffccbc#d84315RDS, DynamoDB, Aurora
Network#e1bee7#7b1fa2VPC, ALB, Route 53, CloudFront
Security#ffcdd2#d32f2fIAM, KMS, Secrets Manager, WAF
Analytics#ede7f6#3f51b5Athena, Redshift, EMR, QuickSight
Messaging#fff9c4#fbc02dSQS, SNS, Kinesis, EventBridge
Monitoring#bbdefb#1976d2CloudWatch, X-Ray

Bound zones (VPC, subnet, account) with a translucent rectangle: backgroundColor: "#e9ecef", opacity: 30, label as title above.

No icons? Use [Compute], [Storage], etc. in the label and the category color does the visual work.

Data Pipeline / Lakehouse / ETL

Encode batch vs stream via stroke width and color, lineage via dotted, async via dashed:

ComponentShapeFillStrokeLabel
Source (DB / API / files)cylinder#b3e5fc#0097a7PostgreSQL\n[Source]
Stream brokerhexagon#f0f4c3#827717Kafka\n[Topic: events]
Batch job (Airflow / dbt)rounded rectangle#fff9c4#fbc02ddbt run\n[Daily 02:00]
Stream processor (Spark / Flink)hexagon#ffecb3#f57f17Spark Stream\n[Processor]
Sink (warehouse / lake)cylinder#c8e6c9#388e3cSnowflake\n[Warehouse]
ML model / feature storerectangle#d1c4e9#3f51b5Recommender\n[Model]
BI / dashboardrounded rectangle#e1bee7#7b1fa2Looker\n[Dashboard]
Edge typeStyleColorWidthLabel
Batchsolid#7575752daily 02:00
Streamsolid#f57c003topic: orders
Async / queuedashed#f57c002queue: tasks
Lineage (dbt parent→child)dotted#9c27b01derived from
Sync APIsolid#1976d22POST /v1/...

Layout: sources top → processing middle → sinks bottom; warehouse layers (raw → staging → marts) flow top-down with consistent column alignment.

UML - Sequence / ER / State / Class

Sequence

  • Actors: hexagon #fff3e0 / #f57c00
  • Lifeline: vertical dashed line #999, strokeWidth 1
  • Service: rectangle on top of lifeline #e3f2fd / #1976d2
  • Sync message: solid arrow #1976d2, label method()
  • Async message: dashed arrow #f57c00, label event
  • Return: dashed arrow #b0bec5, label result

ER

  • Entity: rectangle #e8f5e9 / #388e3c, label = TableName
  • Attribute: ellipse #f3e5f5 / #7b1fa2, label = column\ntype
  • Primary key: ellipse, underline label
  • Relationship: diamond #fff3e0 / #f57c00, label = verb (has, owns)
  • Cardinality: text on the connection line (1:N, M:N)

State

  • State: rounded rectangle #bbdefb / #1976d2
  • Initial: small filled ellipse #212121
  • Final: ellipse with inner dot
  • Transition: solid arrow with event [guard] / action label

Class

  • Class: rectangle, three sections separated by horizontal lines (name / fields / methods)
  • Inheritance: solid arrow with empty triangle head, color #1976d2
  • Composition: arrow with filled diamond, color #d32f2f
  • Aggregation: arrow with empty diamond, color #757575

Deployment - Kubernetes / Docker

K8s blue is #326ce5. Use it as the cluster boundary.

ComponentShapeFillStroke
Cluster (bounding box)rectangle, opacity 30#e3f2fd#326ce5
Noderectangle#bbdefb#1976d2
Podrounded rectangle#a5d8ff#0d6efd
Servicehexagon#b2dfdb#00695c
Ingresshexagon#80cbc4#00897b
PVC / Storagecylinder#f3e5f5#7b1fa2
ConfigMap / Secretsmall rounded rectangle#fffde7#f57f17
NetworkPolicyrectangle, dashed stroke#ffcdd2#d32f2f

Arrows: API call solid #1976d2, mount dotted #7b1fa2, replication dashed #f57c00, denied policy thick red.

Quality Checklist

After every batch, verify ALL:

CheckLook ForFix
TruncationLabels cut off, especially in diamondsIncrease width using formulas above
Invisible arrowsConnections you cannot traceIncrease gap to ≥120px vertical
Arrow label collisionYES/NO labels overlap shapesShorten label or widen gap
Element overlapShapes share spaceReposition with proper spacing
ReadabilityText legible at 50–70% zoomBump fontSize to ≥16
Color consistencyColors match a single domain presetRe-pick from one table above
Color budgetMore than 5 active semantic colors in one diagramMerge similar components; use shape/stroke/labels for extra meaning
Stroke + fill contrastLight fill + dark stroke (or inverse)Use the pairs in tables - never light fill + light stroke
Legend clarityNeeded semantics absent, or legend lists everythingAdd 3-5 used meanings only, or remove if redundant

If any check fails: STOP. Use update_element or delete + recreate. Re-screenshot. Only proceed when all checks pass.

Standard Workflow

1. describe_scene                              # see existing
2. Plan: list elements, layout direction, IDs, coordinates
3. Pick a domain preset (architecture/cloud/data/UML/deployment)
4. batch_create_elements: shapes (Batch 1)
5. batch_create_elements: arrows (Batch 2)
6. Add compact legend if trigger conditions apply
7. group_elements                              # group new diagram
8. set_viewport(scrollToContent: true)
9. Screenshot → Quality Checklist → fix → repeat

Anti-Patterns (Avoid)

MistakeWhy it failsDo this
create_from_mermaid for productionoverlapping text, bad layoutbatch_create_elements with coordinates
Mixing C4 levels in one viewsuggests false relationshipsone diagram per level (Context, Container, Component)
Color chaos (6+ semantic colors)viewer loses semantic mappingcap at 5 active colors; merge similar roles
Unlabeled arrowsambiguous: sync? async? what data?label every arrow with what + how
Labeling shape by tech only ("Lambda")diagram describes infra, not domainname first: CheckoutHandler [Lambda]
Light fill + light strokeinvisible boundaryalways pair light fill with dark stroke
Default roughness > 0unprofessional for technical diagramsalways set roughness: 0
Shapes too closearrows shrink to 0px≥120px vertical, ≥140px horizontal gap
Single-batch shapes + arrowsbinding errorstwo separate batch_create_elements calls
Trusting a single screenshotMCP screenshot may be blankfall back to Chrome DevTools take_screenshot of canvas URL
Master diagram showing all levelsillegiblesplit by concern (data flow / deployment / security)
Oversized legendlegend becomes visual clutter3-5 used meanings, tucked into whitespace

MCP Tool Quick Reference

CategoryTools
Element CRUDcreate_element, get_element, update_element, delete_element, query_elements, batch_create_elements, duplicate_elements, search_elements, element_history
Layoutalign_elements, distribute_elements, group_elements, ungroup_elements, lock_elements, unlock_elements
Scenedescribe_scene, get_canvas_screenshot, get_resource, read_diagram_guide
File I/Oexport_scene, import_scene, export_to_image, export_to_excalidraw_url
Stateclear_canvas, snapshot_scene, restore_snapshot
Viewportset_viewport
Tenancylist_tenants, switch_tenant
Projectslist_projects, switch_project
Conversioncreate_from_mermaid (low-quality preview only)

When exporting through export_scene or export_to_image, write finalized images into the injected Visuals: path (it resolves under the umbrella even from a worktree, so exports survive worktree clean); fall back to a temp dir only when no Visuals: path was injected. Then hand off an openable output location:

  • Clickable absolute file link: [diagram.png](/absolute/path/to/diagram.png)
  • Plain browser URI when useful: file:///absolute/path/to/diagram.png
  • Remote share URL from export_to_excalidraw_url, if generated

Never report only diagram.png or another basename; include the canvas URL plus the file path/URI for every finalized exported file.

Element Creation Cheat Notes

  • Always assign a custom id to each shape so arrows can bind via startElementId / endElementId.
  • For shape labels (rectangles, diamonds, ellipses): set text directly on the element - MCP auto-creates the bound text child.
  • Curved arrows: roundness: { type: 2 } plus 3+ points.
  • Elbowed arrows: elbowed: true.
  • Dashed stroke: strokeStyle: "dashed". Dotted: strokeStyle: "dotted".
  • Translucent zone backgrounds: backgroundColor: "#e9ecef", opacity: 30.
  • Compact legend: small swatch rectangles or 80px mini-lines with short labels; group legend elements with the diagram.

References

  • references/styling-presets.md - full color palettes per domain, layout templates, accessibility, comprehensive examples.
  • references/cheatsheet.md - MCP tool list, REST API mapping, env vars, multi-tenancy notes.

When in doubt, re-read the preset table for your domain before drawing. Color and shape consistency matters more than how many shapes you draw.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.