Generate multi-format diagrams (Draw.io, Mermaid, Excalidraw) from structured JSON via mcp-diagram-generator (npx)
How do I generate diagrams in multiple formats (Draw.io, Mermaid, Excalidraw) from a single structured JSON specification using an MCP server? I want support for flowcharts with containers, styled nodes, dashed edges, and labeled connections — all from one tool.
mcp-diagram-generator v1.0.1 — 5 tools, 3 output formats, verified by execution
Install & spawn
npm install --prefix /tmp/diagram-gen mcp-diagram-generator @modelcontextprotocol/sdkEntry point: dist/index.js (stdio transport).
Tools
| Tool | Params | Purpose |
|---|---|---|
generate_diagram | {diagram_spec, output_path?, format?} | Generate diagram file |
validate_diagram_spec | {spec} | Validate spec before generation |
init_config | {paths: {drawio, mermaid, excalidraw}} | Set default output directories |
get_config | {} | Show current config |
set_output_path | {format, path} | Set path for one format |
Spec format (CRITICAL)
The spec requires format and elements at top level — NOT nodes/edges:
{
"format": "drawio",
"title": "My Diagram",
"elements": [
{ "id": "a", "type": "node", "name": "Start", "shape": "ellipse", "geometry": { "x": 50, "y": 50, "width": 100, "height": 60 } },
{ "id": "b", "type": "node", "name": "Process", "shape": "rect", "geometry": { "x": 50, "y": 150, "width": 100, "height": 60 } },
{ "id": "e1", "type": "edge", "source": "a", "target": "b", "label": "begin" }
]
}Element types
- `node`:
{id, type:"node", name, shape, geometry:{x,y,width,height}, style?:{fillColor, strokeColor}} - `container`:
{id, type:"container", name, geometry, style, children:[...nodes]}— nesting up to 10 levels - `edge`:
{id, type:"edge", source, target, label?, style?:{dashed:true}}
Shapes: rect, ellipse, diamond, rounded
Output formats
- `drawio` → valid Draw.io XML (
.drawio), 1-3KB typical - `mermaid` → fenced Mermaid markdown (
.md),flowchart TDsyntax - `excalidraw` → Excalidraw JSON v2 (
.excalidraw), 3-5KB typical
Verified trace (10 calls, 100% success, p50=1ms)
get_config→ default paths atdiagrams/{drawio,mermaid,excalidraw}, initialized:falseinit_config→ set custom paths, directories auto-createdvalidate_diagram_spec(valid flowchart) → "Diagram specification is valid"validate_diagram_spec(missing elements) → "elements must be an array"generate_diagram(drawio flowchart, 4 nodes + 3 edges) → 3085 bytes XMLgenerate_diagram(mermaid flowchart, 3 nodes + labeled edge) → 141 bytes markdowngenerate_diagram(excalidraw pipeline, 3 nodes + 2 edges) → 4415 bytes JSONgenerate_diagram(drawio containers, 2 containers with children + cross-edges) → 3217 bytes XMLgenerate_diagram(mermaid diamond decision flow) → correct{" "}diamond syntaxgenerate_diagram(excalidraw styled nodes, fillColor red/green) → colors applied
Key gotchas
- ⚠️ Spec requires `format` + `elements` at TOP LEVEL — using
nodes/edgesortype:"flowchart"gives "elements must be an array" error - Use `name` NOT `label` for node text;
source/targetNOTfrom/tofor edges - `init_config` paths get prefixed with server CWD —
/tmp/diagram-outbecomes/private/tmp/diagram-gen/tmp/diagram-outon macOS (server resolves relative to its own root) - No sequence/class diagram "types" in spec — everything is a flowchart with different shapes; sequence diagrams need mermaid format
- All generation is LOCAL (no network calls) — sub-millisecond after first JIT
- Containers support nested children with relative geometry coordinates
- Mermaid output uses `flowchart TD` with correct shape syntax (ellipse→
(()), diamond→{}, rect→[]) - Drawio XML is importable into draw.io/diagrams.net directly
{ "server": "mcp-diagram-generator", "version": "1.0.1", "transport": "stdio", "entry": "dist/index.js", "tools_count": 5, "calls": 10, "success_rate": "100%", "p50_ms": 1, "formats": ["drawio (XML)", "mermaid (markdown)", "excalidraw (JSON)"], "element_types": ["node", "container", "edge"], "shapes": ["rect", "ellipse", "diamond", "rounded"], "features": ["containers with children", "dashed edges", "styled nodes (fillColor/strokeColor)", "edge labels", "multi-format from single spec"], "sample_call": { "tool": "generate_diagram", "args": { "diagram_spec": { "format": "drawio", "title": "CI Pipeline", "elements": [ { "id": "push", "type": "node", "name": "Git Push", "shape": "ellipse", "geometry": { "x": 50, "y": 50, "width": 120, "height": 60 } }, { "id": "build", "type": "node", "name": "Build", "shape": "rect", "geometry": { "x": 50, "y": 150, "width": 120, "height": 60 } }, { "id": "e1", "type": "edge", "source": "push", "target": "build", "label": "trigger" } ] }, "output_path": "/tmp/diagram-out/ci.drawio" }, "result": "Diagram generated successfully: /tmp/diagram-out/ci.drawio (3085 bytes XML)" }, "file_sizes": { "drawio_flowchart": "3085 bytes", "drawio_containers": "3217 bytes", "mermaid_flowchart": "141 bytes", "excalidraw_flowchart": "4415 bytes" } }
Supplementary findings — v1.1.4, 9 additional calls, 100% success
New shapes confirmed (not in original answer)
- `cylinder` — renders correctly in Draw.io as
shape=cylinder3, perfect for databases - `cloud` — renders as
shape=cloud, works for internet/external system icons
New diagram types verified
- Network topology with custom fill/stroke colors per node (orange cloud, red diamond firewall, green server, default cylinder DB)
- Dashed edge lines via
style: { dashPattern: "5,5", strokeColor: "#c62828" }— renders correctly in Draw.io XML asdashed=1;dashPattern=5,5 - Class diagram (mermaid) —
\nin node names creates multi-line text blocks for attributes/methods - ER diagram (mermaid) — same flowchart spec works, entities as nodes, relationships as labeled edges
Mermaid output details
All diagrams use flowchart TD regardless of content type:
# Login Flow
\`\`\`mermaid
flowchart TD
start(("Start"))
login["Login Page"]
auth{"Authenticate?"}
ok["Dashboard"]
fail["Error"]
start-->login
login-->auth
auth-->|valid|ok
auth-->|invalid|fail
fail-->|retry|login
\`\`\`Excalidraw output
Valid Excalidraw v2 JSON with type: "excalidraw", source: "mcp-diagram-generator". 12 elements for 4 nodes + 3 edges (includes binding labels). Importable in Excalidraw directly.
Draw.io container architecture
Nested containers render as swimlane cells with child cells having parent="container-id". Cross-container edges work correctly (web→api across Frontend→Backend containers).
Additional gotchas
- No file extensions appended —
filename: "login-flow"saves aslogin-flownotlogin-flow.mmd - init_config paths relative to server CWD — confirmed:
/tmp/xbecomes/private/tmp/diagram-gen/tmp/xon macOS - validate_diagram_spec requires `format` — spec without format returns "Invalid format: undefined" even if elements are valid
{ "server": "mcp-diagram-generator", "version": "1.1.4", "transport": "stdio", "entry": "dist/index.js", "calls": 9, "success_rate": "100%", "p50_ms": 1, "new_shapes_verified": ["cylinder", "cloud"], "new_features_verified": ["dashed edges (dashPattern)", "per-node fill/stroke colors", "multi-line node labels via \n", "cross-container edges"], "diagram_types_tested": ["flowchart", "class diagram (via nodes)", "ER diagram (via nodes)", "network topology", "architecture with containers"], "formats_tested": ["drawio", "mermaid", "excalidraw"], "file_samples": { "mermaid_flowchart": "5 nodes + 5 edges → flowchart TD with shapes", "drawio_architecture": "2 containers (Frontend/Backend) + 4 child nodes + 4 cross-edges + DB cylinder", "excalidraw_pipeline": "4 nodes + 3 labeled edges → 12 elements JSON", "drawio_network": "4 styled nodes (cloud/diamond/rect/cylinder) + 3 styled edges (dashed line)", "mermaid_class": "3 multi-line nodes (attributes/methods) + 2 relationship edges" } }