Excalidraw Skill
Excalidraw 技能
Step 0: Detect Connection Mode
步骤0:检测连接模式
Before doing anything, determine which mode is available. Run these checks in order:
在进行任何操作之前,先确定可用的模式。按顺序运行以下检查:
Check 1: MCP Server (Best experience)
检查1:MCP服务器(最佳体验)
bash
mcp-cli tools | grep excalidraw
If you see tools like
excalidraw/batch_create_elements
→
use MCP mode. Call MCP tools directly.
bash
mcp-cli tools | grep excalidraw
如果看到
excalidraw/batch_create_elements
这类工具 →
使用MCP模式。直接调用MCP工具即可。
Check 2: REST API (Fallback — works without MCP server)
检查2:REST API(备选方案 — 无需MCP服务器即可运行)
bash
curl -s http://localhost:3000/health
If you get
→
use REST API mode. Use HTTP endpoints (
/
) from the cheatsheet.
bash
curl -s http://localhost:3000/health
如果返回
→
使用REST API模式。使用备忘单中的HTTP端点(
/
)。
Check 3: Nothing works → Guide user to install
检查3:均不可用 → 引导用户安装
If neither works, tell the user:
The Excalidraw canvas server is not running. To set up:
- Clone:
git clone https://github.com/yctimlin/mcp_excalidraw && cd mcp_excalidraw
- Build:
- Start canvas:
HOST=0.0.0.0 PORT=3000 npm run canvas
- Open in a browser
- (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
如果上述两种方式都无法使用,请告知用户:
Excalidraw画布服务器未运行。设置步骤如下:
- 克隆仓库:
git clone https://github.com/yctimlin/mcp_excalidraw && cd mcp_excalidraw
- 构建项目:
- 启动画布:
HOST=0.0.0.0 PORT=3000 npm run canvas
- 在浏览器中打开
- (推荐)安装MCP服务器以获得最佳体验:
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
MCP与REST API快速参考
| Operation | MCP Tool | REST API Equivalent |
|---|
| Create elements | | with |
| Get all elements | | |
| Get one element | | |
| Update element | | |
| Delete element | | |
| Clear canvas | | DELETE /api/elements/clear
|
| Describe scene | | (parse manually) |
| Export scene | | (save to file) |
| Import scene | | with |
| Snapshot | | with |
| Restore snapshot | | then |
| Screenshot | | Only via MCP (needs browser) |
| Design guide | | Not available — see cheatsheet for guidelines |
| Viewport | | (needs browser) |
| Export image | | (needs browser) |
| Export URL | | Only via MCP |
| 操作 | MCP工具 | REST API等效操作 |
|---|
| 创建元素 | | ,请求体为 |
| 获取所有元素 | | |
| 获取单个元素 | | |
| 更新元素 | | |
| 删除元素 | | |
| 清空画布 | | DELETE /api/elements/clear
|
| 描述场景 | | (需手动解析) |
| 导出场景 | | (保存到文件) |
| 导入场景 | | ,请求体为 |
| 快照 | | ,请求体为 |
| 恢复快照 | | 先调用,再调用 |
| 截图 | | 仅支持MCP模式(需要浏览器) |
| 设计指南 | | REST API不支持 — 请查看备忘单获取规范 |
| 视口控制 | | (需要浏览器) |
| 导出图片 | | (需要浏览器) |
| 导出URL | | 仅支持MCP模式 |
REST API Gotchas (Critical — read before using REST API)
REST API注意事项(关键 — 使用前务必阅读)
- Labels: Use
"label": {"text": "My Label"}
(not ). MCP tools auto-convert, REST API does not.
- Arrow binding: Use
"start": {"id": "svc-a"}, "end": {"id": "svc-b"}
(not /). MCP tools accept and convert, REST API requires the / object format directly.
- fontFamily: Must be a string (e.g. ) or omit it entirely. Do NOT pass a number like .
- Updating labels: When updating a shape via , include the full in the update body to preserve it. Omitting from the update won't delete it, but re-sending ensures it renders correctly.
- Screenshot in REST mode: returns . Save to file and read it back for visual verification. Requires browser open.
- 标签格式:使用
"label": {"text": "My Label"}
(而非)。MCP工具会自动转换格式,但REST API不会。
- 箭头绑定:使用
"start": {"id": "svc-a"}, "end": {"id": "svc-b"}
(而非/)。MCP工具接受并自动转换,但REST API要求直接使用/对象格式。
- fontFamily:必须是字符串类型(例如),或完全省略该字段。请勿传入数字类型如。
- 更新标签:通过更新形状时,更新请求体中需包含完整的字段以保留标签内容。更新时省略不会删除标签,但重新传入可确保其正确渲染。
- REST模式下的截图:会返回。需将其保存为文件后再读取以进行视觉验证,且需要保持浏览器处于打开状态。
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 and/or .
- 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.
- 文本截断:所有文本是否都完全可见?标签必须能完全容纳在其形状内部。如果文本被截断或换行效果不佳 → 增大和/或。
- 元素重叠:是否有任何元素相互重叠?检查所有矩形、椭圆或文本元素是否占用同一空间。背景区域必须完全包含其子元素,并留有内边距。
- 箭头交叉:箭头是否穿过无关元素或与文本标签重叠?如果是 → 使用带路径点的曲线/肘形箭头来绕过障碍物(请查看“箭头路由”部分)。绝不接受交叉的箭头。
- 箭头与文本重叠:箭头标签(如“charge”、“event”等)是否与形状重叠?箭头标签位于箭头中点位置 — 如果重叠,可移除标签、缩短标签内容或调整箭头路径。
- 间距:元素之间是否至少有40px的间距?布局过于紧凑会导致可读性下降。
- 可读性:在正常缩放比例下,所有标签是否都清晰可读?正文文本的字体大小应≥16px,标题文本应≥20px。
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.
- 形状宽度:像素。对于多词标签如“API Gateway (Kong)”,需统计所有字符的长度。
- 形状高度:单行文本为60px,两行文本为80px,三行文本为100px。
- 背景区域:在包含的元素四周均添加50px的内边距。
- 元素间距:层级之间的垂直间距为60px,同级元素之间的水平间距为40px。
- 侧边面板:与主图表元素的距离至少为80px。
- 箭头标签:标签内容需简短(1-2个单词)。过长的箭头标签会与其他元素重叠。
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.
在创建元素之前,先在纸上规划坐标网格:
- 第1层(y=50-130):客户端应用
- 第2层(y=200-280):网关/边缘服务
- 第3层(y=350-440):服务(横向分散排列:每个服务之间间隔约180px)
- 第4层(y=510-590):数据存储
- 侧边面板:放置在x < 0(左侧)或x > 主图表最右侧元素 + 80px(右侧)的位置
请勿将侧边面板(可观测性、外部API等)放置在与主图表相同的x轴范围内 — 否则必然会重叠。
- 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 .
- 运行上述步骤0以检测连接模式。
- 在浏览器中打开画布URL(导出图片/截图时需要)。
- MCP模式:所有操作均使用MCP工具。REST模式:使用备忘单中的HTTP端点。
- 如需完整的工具/端点参考,请查看。
Workflow: Draw A Diagram
工作流:绘制图表
- Call first to load design best practices.
- Plan your coordinate grid (see Quality Gate → Layout Planning) before writing any JSON.
- Optional: to start fresh.
- Use with shapes AND arrows in one call.
- Assign custom to shapes (e.g. ). Set field to label shapes.
- Size shapes for their text — use
width: max(160, textLength * 9)
.
- Bind arrows using / — arrows auto-route.
- with to auto-fit the diagram.
- Run Quality Checklist — and critically evaluate. Fix issues before proceeding.
- 首先调用加载设计最佳实践。
- 在编写任何JSON之前,先规划坐标网格(请查看质量检查 → 布局规划部分)。
- 可选操作:调用清空画布,从头开始。
- 使用一次性创建形状和箭头。
- 为形状分配自定义(例如)。设置字段为形状添加标签。
- 根据文本内容调整形状大小 — 使用
width: max(160, 文本长度 * 9)
。
- 使用 / 绑定箭头 — 箭头会自动路由。
- 调用并设置,使图表自动适配画布。
- 运行质量检查清单 — 调用并进行严格评估。修复问题后再继续操作。
- Read for 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 for 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 for shape labels (not ).
- Bind arrows with / — server auto-routes edges.
- Size shapes for their text — use
width: max(160, labelTextLength * 9)
.
- Run Quality Checklist — take screenshot, critically evaluate. Fix issues before adding more elements.
- 查看获取设计规范。
- 在编写任何JSON之前,先规划坐标网格(请查看质量检查 → 布局规划部分)。
- 可选操作:执行
curl -X DELETE http://localhost:3000/api/elements/clear
清空画布。
- 一次性创建元素(对于大型请求体,可使用):
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"}}
]}'
- 形状标签请使用格式(而非)。
- 使用 / 绑定箭头 — 服务器会自动路由边缘。
- 根据文本内容调整形状大小 — 使用
width: max(160, 标签文本长度 * 9)
。
- 运行质量检查清单 — 截取截图并进行严格评估。添加更多元素前需先修复问题。
Arrow Binding (Recommended)
箭头绑定(推荐方式)
Bind arrows to shapes for auto-routed edges. The format differs between MCP and REST API:
json
{"elements": [
{"id": "svc-a", "type": "rectangle", "x": 0, "y": 0, "width": 120, "height": 60, "text": "Service A"},
{"id": "svc-b", "type": "rectangle", "x": 0, "y": 200, "width": 120, "height": 60, "text": "Service B"},
{"type": "arrow", "x": 0, "y": 0, "startElementId": "svc-a", "endElementId": "svc-b", "text": "calls"}
]}
REST API Mode — use
/
and
:
json
{"elements": [
{"id": "svc-a", "type": "rectangle", "x": 0, "y": 0, "width": 120, "height": 60, "label": {"text": "Service A"}},
{"id": "svc-b", "type": "rectangle", "x": 0, "y": 200, "width": 120, "height": 60, "label": {"text": "Service B"}},
{"type": "arrow", "x": 0, "y": 0, "start": {"id": "svc-a"}, "end": {"id": "svc-b"}, "label": {"text": "calls"}}
]}
Arrows without binding use manual
,
,
coordinates.
将箭头绑定到形状上可实现自动路由边缘。MCP与REST API的格式有所不同:
json
{"elements": [
{"id": "svc-a", "type": "rectangle", "x": 0, "y": 0, "width": 120, "height": 60, "text": "Service A"},
{"id": "svc-b", "type": "rectangle", "x": 0, "y": 200, "width": 120, "height": 60, "text": "Service B"},
{"type": "arrow", "x": 0, "y": 0, "startElementId": "svc-a", "endElementId": "svc-b", "text": "calls"}
]}
json
{"elements": [
{"id": "svc-a", "type": "rectangle", "x": 0, "y": 0, "width": 120, "height": 60, "label": {"text": "Service A"}},
{"id": "svc-b", "type": "rectangle", "x": 0, "y": 200, "width": 120, "height": 60, "label": {"text": "Service B"}},
{"type": "arrow", "x": 0, "y": 0, "start": {"id": "svc-a"}, "end": {"id": "svc-b"}, "label": {"text": "calls"}}
]}
Arrow Routing — Avoid Overlaps (Critical for complex diagrams)
箭头路由 — 避免重叠(复杂图表的关键)
Straight arrows (2-point) cause crossing and overlap in complex diagrams. Use curved or elbowed arrows instead:
Option 1: Curved arrows — add intermediate waypoints +
:
json
{
"type": "arrow", "x": 100, "y": 100,
"points": [[0, 0], [50, -40], [200, 0]],
"roundness": {"type": 2},
"strokeColor": "#1971c2"
}
The waypoint
pushes the arrow upward to arc over elements.
makes it a smooth curve.
Option 2: Elbowed arrows — right-angle routing (L-shaped or Z-shaped):
json
{
"type": "arrow", "x": 100, "y": 100,
"points": [[0, 0], [0, -50], [200, -50], [200, 0]],
"elbowed": true,
"strokeColor": "#1971c2"
}
When to use which:
- Fan-out arrows (one source → many targets): Use curved arrows with waypoints spread vertically to avoid overlapping each other.
- Cross-lane arrows (connecting to side panels): Use elbowed arrows that route around the main diagram — go UP first, then ACROSS, then DOWN.
- Inter-service arrows (horizontal connections): Use curved arrows with a slight vertical offset to avoid crossing through adjacent elements.
Rule of thumb: If an arrow would cross through an unrelated element, add a waypoint to route around it. Never accept crossing arrows — always fix them.
直线箭头(2个路径点)在复杂图表中会导致交叉和重叠。请改用曲线或肘形箭头:
json
{
"type": "arrow", "x": 100, "y": 100,
"points": [[0, 0], [50, -40], [200, 0]],
"roundness": {"type": 2},
"strokeColor": "#1971c2"
}
路径点
会将箭头向上推,使其绕过元素。
会使箭头成为平滑曲线。
选项2:肘形箭头 — 直角路由(L形或Z形):
json
{
"type": "arrow", "x": 100, "y": 100,
"points": [[0, 0], [0, -50], [200, -50], [200, 0]],
"elbowed": true,
"strokeColor": "#1971c2"
}
使用场景建议:
- 扇出箭头(一个源 → 多个目标):使用带路径点的曲线箭头,并将路径点垂直分散排列,避免箭头之间相互重叠。
- 跨区域箭头(连接到侧边面板):使用肘形箭头,先向上路由,再横向穿过,最后向下连接,绕过主图表区域。
- 服务间箭头(横向连接):使用带轻微垂直偏移的曲线箭头,避免穿过相邻元素。
经验法则:如果箭头会穿过无关元素,请添加路径点使其绕过。绝不接受交叉的箭头 — 必须进行修复。
Workflow: Iterative Refinement (Key Differentiator)
工作流:迭代优化(核心优势)
The feedback loop that makes this skill unique. Each iteration MUST include a quality check.
这是本技能独有的反馈循环机制。每次迭代必须包含质量检查步骤。
MCP Mode (full feedback loop)
MCP模式(完整反馈循环)
- Add elements (, ).
- with .
- — critically evaluate against the Quality Checklist.
- If issues found → fix them (, , resize, reposition).
- again — re-verify fix.
- Only proceed to next iteration when ALL quality checks pass.
- 添加元素(、)。
- 调用并设置。
- 调用 — 根据质量检查清单进行严格评估。
- 如果发现问题 → 修复问题(、、调整大小、重新定位)。
- 再次调用 — 重新验证修复效果。
- 只有当所有质量检查项都通过后,才能进入下一次迭代。
REST API Mode (partial feedback loop)
REST API模式(部分反馈循环)
- Add elements via .
- with
{"scrollToContent": true}
.
- Take screenshot: → save PNG → critically evaluate against Quality Checklist.
- If issues found → fix via or delete and recreate.
- Re-screenshot and re-verify.
- Only proceed to next iteration when ALL quality checks pass.
- 通过添加元素。
- 调用并设置
{"scrollToContent": true}
。
- 截取截图:调用 → 保存为PNG图片 → 根据质量检查清单进行严格评估。
- 如果发现问题 → 通过进行修复,或删除后重新创建。
- 重新截取截图并验证。
- 只有当所有质量检查项都通过后,才能进入下一次迭代。
How to critically evaluate a screenshot:
如何严格评估截图:
- Look at EVERY label — is any text cut off or overflowing its container?
- Look at EVERY arrow — does any arrow pass through an unrelated element?
- Look at ALL element pairs — do any overlap or touch?
- Look at spacing — is anything crammed together?
- Be honest. If you see ANY issue, say "I see [issue], fixing it" — not "looks great".
Example flow (MCP):
batch_create_elements → get_canvas_screenshot → "text truncated on 2 shapes"
→ update_element (increase widths) → get_canvas_screenshot → "overlap between X and Y"
→ update_element (reposition) → get_canvas_screenshot → "all checks pass"
→ proceed to next iteration
- 查看所有标签 — 是否有文本被截断或溢出容器?
- 查看所有箭头 — 是否有箭头穿过无关元素?
- 查看所有元素对 — 是否有元素重叠或接触?
- 查看间距 — 是否有布局过于紧凑的情况?
- 务必诚实。如果发现任何问题,请说“我发现了[问题],正在修复” — 而不是“看起来没问题”。
示例流程(MCP模式):
batch_create_elements → get_canvas_screenshot → "2个形状上的文本被截断"
→ update_element(增大宽度) → get_canvas_screenshot → "元素X和Y之间存在重叠"
→ update_element(重新定位) → get_canvas_screenshot → "所有检查项均通过"
→ 进入下一次迭代
Workflow: Refine An Existing Diagram
工作流:优化现有图表
- to understand current state.
- Identify targets by id, type, or label text (not x/y coordinates).
- to move/resize/recolor, to remove.
- to verify changes visually.
- If updates fail: check element id exists (), element isn't locked ().
- 调用了解当前图表状态。
- 通过id、类型或标签文本(而非x/y坐标)定位目标元素。
- 使用移动/调整大小/重新着色,使用删除元素。
- 调用可视化验证更改效果。
- 如果更新失败:检查元素id是否存在(调用),元素是否被锁定(调用)。
Workflow: File I/O (Diagrams-as-Code)
工作流:文件I/O(图表即代码)
- Export to .excalidraw format: with optional .
- Import from .excalidraw: with or .
- Export to image: with or (requires browser open).
- CLI export:
node scripts/export-elements.cjs --out diagram.elements.json
- CLI import:
node scripts/import-elements.cjs --in diagram.elements.json --mode batch|sync
- 导出为.excalidraw格式:调用,可选择指定。
- 导入.excalidraw文件:调用,设置或。
- 导出为图片:调用,设置或(需要保持浏览器打开)。
- CLI导出:
node scripts/export-elements.cjs --out diagram.elements.json
- CLI导入:
node scripts/import-elements.cjs --in diagram.elements.json --mode batch|sync
Workflow: Snapshots (Save/Restore Canvas State)
工作流:快照(保存/恢复画布状态)
- with a name before risky changes.
- Make changes, / to evaluate.
- to rollback if needed.
- 在进行风险操作之前,调用并指定名称保存快照。
- 进行更改,调用 / 评估效果。
- 如果需要回滚,调用恢复快照。
Workflow: Duplication
工作流:复制元素
- with and optional / (default 20,20).
- Useful for creating repeated patterns or copying existing layouts.
- 调用并传入,可选择指定/(默认值为20,20)。
- 此功能适用于创建重复模式或复制现有布局。
Points Format for Arrows/Lines
箭头/线条的路径点格式
The
field accepts both formats:
- Tuple:
- Object:
[{"x": 0, "y": 0}, {"x": 100, "y": 50}]
Both are normalized to tuples automatically.
- 元组格式:
- 对象格式:
[{"x": 0, "y": 0}, {"x": 100, "y": 50}]
两种格式都会自动被标准化为元组格式。
Workflow: Share Diagram (excalidraw.com URL)
工作流:分享图表(excalidraw.com URL)
- Create your diagram using any of the above workflows.
- — uploads encrypted scene, returns a shareable URL.
- Share the URL — anyone can open it in excalidraw.com to view and edit.
- 使用上述任意工作流创建图表。
- 调用 — 上传加密后的场景数据,返回一个可分享的URL。
- 分享该URL — 任何人都可在excalidraw.com中打开并查看、编辑图表。
Workflow: Viewport Control
工作流:视口控制
- with — auto-fit all elements (zoom-to-fit).
- with
scrollToElementId: "my-element"
— center view on a specific element.
- with
zoom: 1.5, offsetX: 100, offsetY: 200
— manual camera control.
- 调用并设置 — 自动适配所有元素(缩放到合适大小)。
- 调用并设置
scrollToElementId: "my-element"
— 将视口居中显示指定元素。
- 调用并设置
zoom: 1.5, offsetX: 100, offsetY: 200
— 手动控制相机位置。
- : Complete MCP tool list (26 tools) + REST API endpoints + payload shapes.
- :完整的MCP工具列表(共26个工具)+ REST API端点 + 请求体格式。
- See also: figure-generation, algorithm-design, slide-generation
- 另请参阅:figure-generation、algorithm-design、slide-generation