Codync
무료 오픈소스 1:1 대안, Grok Bot과 Muse 대신
코드 기반 Excalidraw 다이어그램 생성기 – CLI, MCP 서버, 템플릿, SVG·PNG 내보내기
Code-first Excalidraw diagram generator — CLI, MCP server, templates, SVG/PNG export
개발 도구GitHub @guohaonan-shy직접 설치운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
저장소 정보는 아직 수집하지 않았습니다.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Code-first Excalidraw diagram generation — CLI, MCP server, and SVG/PNG/WebP export.
Hand-drawn Excalidraw diagrams from code, an MCP call, or a plain-language
request to an agent. Every figure below is real output — a .excalidraw file you
can still open and edit, plus SVG/PNG/WebP — generated by
examples/gallery.mjs with no browser involved.
Nine diagram types, each with its own agent skill. Click a figure for full size.
New in 0.6.0: state machines, pyramids and funnels, bar and line charts, and a left-to-right data-stack overview as a fourth architecture layout — plus WebP output.
Excalidraw is a fantastic drawing tool — you open a canvas and arrange boxes by hand. excalidrawer is a generation tool: it turns code (or a structured spec, or an agent's intent) into the same hand-drawn-style diagrams, with no browser and no manual dragging.
Use Excalidraw when a human is sketching once. Reach for excalidrawer when the diagram needs to come out of an automated pipeline:
.svg / .png as a build step so the diagrams
in your README or docs site never drift from the system they describe.It produces real .excalidraw files, so the output is still fully editable in
Excalidraw afterward — generate the first draft programmatically, hand-tweak if
you want.
Most users want the agent plugin — it bundles the flowchart / timeline / architecture / sequence / comparison / tree skills and wires them to the MCP server, so you can just say "draw the auth flow" inside Claude Code or Codex. The CLI and library entry points are below for scripting and custom use cases.
Two commands and you're done — the plugin bundles the skills and
auto-registers the MCP server via its manifest (no global npm install, no
separate claude mcp add / codex mcp add).
In Claude Code:
/plugin marketplace add guohaonan-shy/excalidrawer
/plugin install excalidrawer@excalidrawer-dev
In Codex:
codex plugin marketplace add guohaonan-shy/excalidrawer
codex plugin add excalidrawer@excalidrawer-dev
Codex reads this repo's .claude-plugin/marketplace.json directly, so both
clients get the same skills and the same auto-registered MCP server — verify
with codex plugin list / codex mcp list.
The MCP server runs via npx, so the first invocation downloads the package
into the npx cache (~5-10 s); subsequent runs use the cache.
Auto-registering the MCP server from the plugin manifest is a plugin-host feature. In a client that doesn't install plugins, register the MCP server directly — see MCP Server below.
If you only want the binaries (e.g. to script excalidrawer render in a build):
npm install -g excalidrawer
This puts two commands on your PATH:
excalidrawer — the CLI (render, compute-layout)excalidrawer-mcp — the MCP server that MCP clients launchOnly needed for the programmatic API (see Custom Scripts):
npm install excalidrawer
excalidrawer-mcp is a stdio MCP server exposing two tools:
| Tool | What it does |
|---|---|
render_diagram | Render an array of sugar shorthand or raw Excalidraw elements to .excalidraw / .svg / .png / .webp files. |
compute_layout | Compute coordinates from a layout helper (grid, chain, swimlane, hub-and-spoke, edge anchors, U-routing, label anchors, titled boxes, row equalization). |
Each command below registers the server with
npx -y -p excalidrawer@latest -c excalidrawer-mcp — no global install needed,
and always the latest published version.
claude mcp add excalidrawer -- npx -y -p excalidrawer@latest -c excalidrawer-mcp
Verify with claude mcp list — it should report ✓ Connected.
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)
or %APPDATA%\Claude\claude_desktop_config.json (Windows), then restart the app:
{
"mcpServers": {
"excalidrawer": {
"command": "npx",
"args": ["-y", "-p", "excalidrawer@latest", "-c", "excalidrawer-mcp"]
}
}
}
Only if you want the two MCP tools without the skills. The recommended
Codex path is the plugin, which
brings the skills and this MCP server together — a bare codex mcp add gives
you render_diagram / compute_layout but none of the skills' guidance (palette
conventions, back-edge routing, layout components, quality gates).
codex mcp add excalidrawer -- npx -y -p excalidrawer@latest -c excalidrawer-mcp
The skills/ directory holds two layers: one entry skill per diagram type
(the one you invoke), and a step skill steps they call when they reach a step. They ship as part of the agent plugin above —
Claude Code and Codex both install them.
| Skill | Use for | Trigger keywords |
|---|---|---|
flowchart | Decision flows, process diagrams, branching logic | flowchart, 流程图, decision tree, yes/no, approval flow |
timeline | Timelines, roadmaps, project milestones | timeline, 时间线, roadmap, milestone, Q1/Q2 phases |
architecture | System architecture, layered components, topology; a left-to-right data-stack overview (sources → ingest → storage → compute → consume) | architecture, 架构图, 3-tier, microservices, data platform, data stack, 数据全景 |
sequence | Sequence diagrams, multi-actor interactions, call chains | sequence diagram, 时序图, interaction, handshake, OAuth |
comparison | Left-vs-right comparisons, A vs B, before/after, trade-offs | compare, A vs B, 对比图, side-by-side, before and after |
tree | Hierarchies from one root — taxonomies, org charts, user-story maps; left→right or top→down | tree, 树状图, hierarchy, org chart, 层级图, 分类树 |
state-machine | Object lifecycles and state transitions — events, guards, self-loops, two-way transitions, start/end states | state machine, 状态机, state diagram, lifecycle, 订单状态 |
pyramid | Pyramids (ranked layers) and funnels (stage-by-stage drop-off with counts and conversion) | pyramid, funnel, 金字塔, 漏斗, 转化漏斗 |
chart | Simple bar and line charts — category comparisons and trends, up to three series | bar chart, line chart, 柱状图, 折线图, 趋势图 |
steps | Step skill — how to ask, which component to use and how to fill it (one reference per component), output rules, quality gate (called by the entry skills, not invoked directly) | — |
An entry skill is a single SKILL.md in plain language: what to ask, what a
good diagram of that type looks like, and how it usually goes wrong. It holds
no coordinates, sizes, tool calls or code (a test,
tests/skills-entry.test.mjs, keeps it that
way). When it reaches a step that needs mechanics, it calls steps (in Claude
Code, the Skill tool with excalidrawer:steps; other hosts read
../steps/SKILL.md) and names the one section to read - clarify, 组件,
出图 - so the cross-cutting rules and each component's usage live in one place
instead of being copied into every entry skill. Given a request, an entry skill
asks a couple of AskUserQuestion prompts (skipping the ones about what to draw if your description already
lists everything in the diagram), composes the diagram with the component
references in skills/steps/references/, then calls
the MCP server's render_diagram tool to emit .excalidraw / .svg / .png /
.webp.
To add a diagram type, follow the checklist in the 新增一种图类型 section of
skills/steps/SKILL.md.
All skills call the
excalidrawer-mcpserver. The plugin install above ships a manifest that registers it automatically; without the plugin, wire up the MCP server per MCP Server.
# Render sugar / raw Excalidraw elements to files
excalidrawer render -i elements.json -o docs/diagram
cat elements.json | excalidrawer render -o docs/diagram -f svg,png
# Lossless WebP for web pages / blogs (opt-in; not in the default set)
excalidrawer render -i elements.json -o docs/diagram -f webp
# Compute layout coordinates (prints JSON)
excalidrawer compute-layout --helper gridLayout -a '{"count":6,"cols":3,"cellW":140,"cellH":50}'
render accepts either a bare element array or { "elements": [...] }. The
render / compute-layout commands share the exact tool definitions the MCP
server uses, so the two surfaces never drift.
render() takes the same sugar shorthand the MCP server uses and returns the
rendered outputs — drop it into any script:
import { writeFileSync } from "fs";
import { render } from "excalidrawer";
const elements = [
{ shape: "rect", id: "start", at: [20, 80], size: [130, 56], fill: "yellow", text: "Start" },
{ shape: "rect", id: "process", at: [240, 80], size: [150, 56], fill: "blue", text: "Process" },
{ shape: "rect", id: "done", at: [460, 80], size: [130, 56], fill: "green", text: "Done" },
{ shape: "arrow", from: "start", to: "process" },
{ shape: "arrow", from: "process", to: "done" },
];
const { outputs } = await render(elements, { formats: ["excalidraw", "svg", "png"] });
writeFileSync("diagram.excalidraw", outputs.excalidraw);
writeFileSync("diagram.svg", outputs.svg);
writeFileSync("diagram.png", outputs.png);
The sugar schema is documented per component under
skills/steps/references/: shapes and text
(fill / stroke / textColor) in
shapes.md, arrows and lines in
connectors.md, and one file for each
layout helper.
| Function | Returns | Description |
|---|---|---|
render(elements, opts?) | Promise<{ outputs, elementCount }> | Desugar + render to { excalidraw, svg, png, webp }. opts.formats picks the outputs (default: excalidraw, svg, png; webp is opt-in); opts.scale (1–4) sets the PNG / WebP scale. |
desugar(elements) | element[] | Expand sugar shorthand into raw Excalidraw elements without rendering. |
| Function | Description |
|---|---|
gridLayout, chain, swimlane, hubSpoke | Position helpers — coordinates for grids, chains, swimlanes, hub-and-spoke. |
edgePoint, routeU, labelAnchor | Edge anchors, U-route detours, and label anchors for arrows. |
titledBox, fitContainer | Auto-sized geometry — a header+body card, and a container fitted to its children. |
equalize | One height that fits a group of cells, so a wrapped label can't leave a row of sibling boxes ragged. |
stack | Lay cells along one axis and size the container from their content — absolute coordinates for every cell, natural widths capped at maxW, optional equalize / justify / fixed size, nested stacks. |
panel | A container of a title area plus a stack of cells, sized from both — title on top or in a left column, optional fixed w, usable as a { panel } cell of a stack (an outer equalize re-flows it). Coordinates only. |
treeLayout | Tidy tree (right or down): parents centered on their children, subtrees never overlap, connectors as ready-to-draw segments. compute_layout name: tree. |
axis | A marked line: mark positions (even, or linear over a value domain), the line broken around each mark, optional ticks, and the value → coordinate scale. Coordinates only — you draw the dots and labels. |
taper | Layers that narrow by an equal step — a pyramid or a funnel: each layer's four corners, a label box sized to the narrowest edge, value and conversion-rate anchors. Coordinates only; draw the layers with the polygon sugar shape. |
legend | Legend geometry — a sample slot and a text slot per row plus the block size, placeable in a corner of the diagram's bounds (inside or outside). Coordinates only; you draw the swatch or line. |
contrastText, readableOn | Pick a legible label color for a given fill (3:1 WCAG floor). |
These back the compute_layout MCP tool — see the component references in
skills/steps/references/ for usage.
| Function | Returns | Description |
|---|---|---|
excalidraw(elements) | string | JSON for a .excalidraw file |
toSvg(elements) | string | SVG markup with embedded fonts |
toPng(elements, scale?) | Promise<Buffer> | PNG buffer (resvg-js native rendering) |
toWebp(elements, scale?) | Promise<Buffer> | Lossless WebP buffer — same rasterization as toPng, encoded with @jsquash/webp |
excalidraw / toSvg / toPng / toWebp take already-desugared elements; call
desugar() first if you're starting from sugar.
import { colors } from "excalidrawer";
colors.blue / colors.green / colors.yellow / colors.purple / colors.red / colors.orange / colors.gray
colors.bgBlue / colors.bgGreen / colors.bgYellow / colors.bgPurple // section backgrounds
colors.strokeBlue / colors.strokeGreen / colors.strokeYellow / colors.strokeOrange // stroke accents
In sugar, set fill for the background, stroke for the border, and
textColor (palette key or #rrggbb) for a bound label.
Directions being explored, each tracked in its own design note under
docs/ (see docs/roadmap.md for the versioned
engineering roadmap):
docs/diagram-types.mddocs/mermaid-import.mddocs/drawio-import.mddocs/icon-library.mddocs/ecosystem-integration.mdMIT