Excalidraw diagrams
Use when creating, editing, or updating any Excalidraw scene, diagram, flowchart, architecture/system diagram, mind map, wireframe, timeline, or slide deck through the Excalidraw+ MCP — whenever the user says "excalidraw", "draw a diagram", "make a flowchart/architecture diagram", "put this on a canvas", or wants recognizable tech/logo icons (Postgres, React, Docker, AWS…) in a diagram. Covers the MCP workflow, element format, layout/centering/alignment, real library icons, and the MCP quirks that silently break diagrams (invisible text, z-order, bindings). Use even for a "simple" diagram — the gotchas bite there too.From its SKILL.md
npx -y skills add shaharsha/claude-skills --skill excalidraw-diagramsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 5 stars5 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.
SKILL.md
7.2 KB, as published. Nobody here has run it
Excalidraw diagrams (via the Excalidraw+ MCP)
Build scenes that read as a deliberate visual argument, not "boxes with text,"
and get them right the first time by knowing the MCP's non-obvious behaviours up
front. The element JSON here is standard Excalidraw, so it also applies if you ever
generate .excalidraw files directly — but this skill targets the hosted
Excalidraw+ MCP (shareable scenes, collections), which is the usual case.
The workflow
- Plan the structure first (see
reference/layout.md). Pick the family (workflow / architecture / timeline / hierarchy / comparison / cycle / slides), the reading direction, and the regions — before placing anything. The test: if you deleted every label, would the layout alone still convey the idea? - Call
read_excalidraw_formatonce before your first write this session. It's the MCP's own normative element guide (occasionally updated) and the server expects it.reference/elements.mdis your fast working subset. - Create or target a scene. New:
create_scene(needs acollectionId— get it fromlist_collections). Existing: find it vialist_scenes/get_workspace; to edit an earlier one, get real element IDs withsearch_scene_content. The shareable link ishttps://app.excalidraw.com/s/<workspace_id>/<scene_id>— both IDs come back in thecreate_scenemetadata (workspaceandid); give this link to the user. - Add content with
edit_scene_content— one coherent diagram per call. Build in placement order: regions/frames → containers → primary nodes → secondary nodes → labels → arrows (bound, once nodes are stable) → accents. - Add icons where they help (
reference/library-icons.md+ the bundled script) — real Postgres/React/Docker/AWS icons, inserted via the MCP. - Verify — this is mandatory, not optional (see "Verifying" below). Screenshot
for layout,
search_scene_contentfor text/geometry, fix, repeat.
Non-negotiables (each one silently ruins a diagram)
These are the traps that make a diagram look broken or fall apart on the next edit.
Full explanations in reference/mcp-gotchas.md — internalize these five:
- Screenshots don't render text. A screenshot that looks "empty" usually has all
its labels. Never judge text presence/content from a screenshot — use
search_scene_content. - New elements can land under existing fills (the server assigns indices
non-monotonically, even on a fresh delete-free build). Icons placed on cards, or
cards placed in a box, can render invisibly under the opaque fill — often
inconsistently (some show, some don't). Simplest robust fix: give grouping
containers AND cards
backgroundColor:"transparent"(keep the coloured border) — a transparent fill can never occlude, so z-order stops mattering for content inside a box, and a white card on a white canvas looked identical anyway. Only fall back to an explicit highindex(read the current max viasearch_scene_content, don't trust a literal like"b01") when you need one opaque element atop another. Seereference/mcp-gotchas.md. textAlign:"center"makes thexyou pass the CENTER of a standalone label (not the left edge). To center under a node at center X, passx: X.- Bound labels are always vertically centered in their shape. For an
icon-above-label block, use a standalone label positioned yourself, not a bound
label. - Arrows pointing at shapes must be bound (
startBinding/endBinding, mode"inside"), or they detach on the next edit. A bound arrow label (label:{}) is created only ataddtime — adding one viaupdatesilently no-ops (added:0), so re-add an arrow to (re)label it, and read the label as the arrow'slabelText(it's invisible to atypes:["text"]search). You can't delete a shape and its bound arrow in the same call — delete the arrow first.
Verifying (do not claim done without this)
A green edit_scene_content result is not verification. After building:
take_screenshot→ check layout, spacing, overlap, arrow routing, colour, icon shapes. (Not text — it won't render.)search_scene_content→ confirm every label exists with the righttext, and that positions/alignment are what you intended (e.g. equal top/bottom margins for a centered block; sharedyacross a row).- Fix and re-verify until both pass. Typical: 2–4 iterations.
Centering, alignment & icons — the fiddly parts
The bundled script does the error-prone math and the icon extraction. Run it from the skill directory:
# centering: where to put an icon + standalone label as one centered block in a box
python scripts/excalidraw_tools.py place --box X Y W H --icon-h H --font F
# find an icon pack, list its items, extract one positioned icon as add-JSON
python scripts/excalidraw_tools.py catalog <keyword>
python scripts/excalidraw_tools.py list <author/name.excalidrawlib>
python scripts/excalidraw_tools.py icon <lib> --item <idx|name> --at <cx> <top_y> --height <h> [--swap OLD=NEW]
place and icon both take --at as center-x, top-y (not the box's top-left
x,y) — feed icon --at the exact center_x/top_y that place printed.
Row/column alignment is just shared y+height (row) or x+width (column) with
a constant step — keeping those exact is what separates intentional from
hand-nudged. Details and the reasoning in reference/layout.md.
Reference map
Read the file that matches the task; don't load them all up front.
reference/mcp-gotchas.md— the MCP quirks above, in full. Read before any real scene work — these cause the most wasted time.reference/elements.md— element fields, fonts, semantic color palette, arrow bindings, frames/slides, charts. Your working reference while building.reference/layout.md— planning, spacing, centering/alignment math, and which structure to choose for a given idea (with a decision table).reference/library-icons.md— finding and inserting real community icons via the MCP; identifying unnamed icons; recommended packs.scripts/excalidraw_tools.py—catalog/list/icon/place. Run--helpfor any subcommand.
Professional vs hand-drawn
Excalidraw defaults to a hand-drawn look (roughness:1, Excalifont). For clean,
technical diagrams set roughness:0, use fontFamily:8 (mono) or 7 (titles),
and lean on gray/blue with one accent. For approachable/whiteboard diagrams, keep
the defaults. Match the register to the audience.