关于 excalidraw-skill
Excalidraw Skill 帮助 Agent 通过 MCP 工具、CLI 或 REST API 操作实时 Excalidraw 画布,创建和修改图表,并检查渲染结果。它提供布局建议与质量检查流程,适用于需要绘制或迭代图示的场景。
主要功能
- 01通过 MCP、CLI 或 REST 操作画布
- 02批量创建、更新和删除图形元素
- 03将 Mermaid 图表转换为画布内容
- 04导入、导出和管理快照
- 05截图检查布局与可读性
适用场景
- 01绘制系统架构或流程图
- 02把 Mermaid 图表转为画布图示
- 03批量调整已有画布元素
- 04检查并修正图形重叠或箭头路径
MCP 相关
可优先使用 Excalidraw MCP 工具直接操作实时画布;这些工具与 CLI 使用相同的元素格式。MCP 模式还可调用绘图指南工具获取颜色和尺寸建议。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ yctimlin/ mcp_excalidraw --skill excalidraw-skill安装后在 Claude Code 中输入/excalidraw-skill确认已加载。
附带文件evals/evals.jsonreferences/cheatsheet.md
详细介绍
Excalidraw 技能
步骤 0:选择接口
三个接口都操作同一个实时画布。选择第一个适用的接口:
- MCP 工具 — 如果你的工具列表中有
excalidraw/*工具(例如batch_create_elements),优先使用它们:结果会直接返回到你的上下文中,截图也会以图像形式返回,无需写入磁盘。 - CLI(默认选项,适用于没有 MCP 工具的情况):
无需设置 — 任何操作画布的命令都会自动启动画布服务,地址为npx -y mcp-excalidraw-server <command>http://127.0.0.1:3000(首次运行npx时会下载软件包)。如果已全局安装 CLI(npm i -g mcp-excalidraw-server),也可以使用更简短的别名excalidraw-canvas <command>。 - REST API(最后的选择,例如从应用代码中调用):
http://127.0.0.1:3000上的 HTTP 端点 — 负载格式见references/cheatsheet.md。服务必须已在运行。
画布 URL 来自 EXPRESS_SERVER_URL(默认值为 http://127.0.0.1:3000)。截图和图像导出会在画布服务中以无头方式渲染,因此无需打开浏览器标签页检查自己的工作。只有 Mermaid 转换和视口控制需要打开的标签页(缺少标签页时 CLI 会以代码 4 退出)。仍要告知用户该 URL — 打开后,他们就能看到你绘制的内容。
CLI 快速参考
结果以 JSON 形式输出到 stdout — describe(纯文本)和省略 --out 时的原始内容输出(export 场景 JSON、screenshot --format svg)除外。诊断信息输出到 stderr。退出代码:0 表示正常,1 表示错误,2 表示用法错误,3 表示无法连接画布,4 表示需要浏览器标签页(仅适用于 mermaid 和 screenshot --renderer browser)。
| 任务 | 命令 |
|---|---|
| 启动 / 停止 / 检查服务 | start、stop、status |
| 创建元素(批量) | add elements.json 或 echo '[...]' | add 或 add --one '{...}' |
| 单次调用执行多项操作的补丁 | apply patch.json — {"create":[...],"update":[{"id":"a","set":{...}}],"delete":[...]} |
| 读取单项 / 查询多项 | get <id>、query [--type t] [--bbox x0,y0,x1,y1] [--filter k=v] [--filter-json '{...}'] |
| 更新 / 删除 | update <id> --set '{...}'、delete <id> [...] |
| 了解场景 | describe(纯文本摘要:ID、位置、标签、连接) |
| 查看场景 | screenshot [--out f.png](不带 --out 的 PNG → JSON 中的临时文件路径;不带 --out 的 SVG → 原始 SVG) |
| 布局操作 | arrange align|distribute|group|ungroup|lock|unlock|duplicate --ids a,b,c [--to left|horizontal|...] |
| 场景文件 | export [--out scene.excalidraw]、`import [scene.excalidraw |
| Mermaid → 画布 | `mermaid [diagram.mmd |
| 快照 | snapshot save|list|restore <name> |
| 分享链接 | share(加密上传 → excalidraw.com URL) |
| 清空画布 | clear --yes |
| 安装 / 升级此技能 | install-skill --dir <skills-root>(由 Agent 选择项目级 / 全局根目录) |
元素格式(CLI 和 MCP)
CLI 和 MCP 工具接受相同的、便于 Agent 使用的格式,并会自动规范化:
- 标签:在任意形状上设置
"text": "My Label"— 系统会为你转换为 Excalidraw 的绑定标签格式。 - 箭头绑定:
"startElementId": "a"/"endElementId": "b"— 箭头会自动连接到元素边缘。 - fontFamily:可传入字符串名称(
"helvetica"、"cascadia"、"excalifont"等),或字符串数字"1"–"8"。 - points:接受
[[x,y], ...]元组和[{"x":..,"y":..}]对象两种格式。 - 补丁更新:在
apply中,更新条目可以使用直接字段({"id":"a","x":120})或set对象({"id":"a","set":{"x":120}})。同一个更新条目中不要混用这两种格式。
原始 REST API 的要求更严格:标签必须写成 "label": {"text": "..."},绑定必须写成 "start": {"id": "..."} / "end": {"id": "..."}。只有直接向 API 发送 POST 请求时才需要注意这一点。
坐标系
画布使用二维坐标网格:(0,0)是原点,x 向右递增,y 向下递增。编写任何 JSON 之前,先规划布局。
常规间距指南:
- 层级之间的垂直间距:80–120px(确保箭头不会挤到标签)
- 同级元素之间的水平间距:至少 40–60px;带标签的箭头需留出 120px 以上
- 形状宽度:
max(160, labelCharCount * 12),确保标签显示在一行 - 形状高度:单行标签为 60px,双行标签为 80px
- 背景/区域的内边距:所含元素四周各留 50px
专业风格设置:
- 在形状上使用
"fillStyle": "solid",可获得清晰的纯色填充——默认样式为素描式排线图案 - 为柔和的
backgroundColor填充搭配较深的strokeColor(配色见速查表) - 在区域边框和异步箭头上使用
"strokeStyle": "dashed",以体现“边界/背景”
布局反模式(复杂图表的关键注意事项)
以下是最常见的易读性问题。请全部避免。
1. 不要在大型背景区域矩形上使用 label.text(或 text)
在背景矩形上添加标签时,Excalidraw 会创建一个绑定文本元素,并将其置于形状中央——也就是服务框的放置位置。文本会与区域内的所有内容重叠,而且无法重新定位。
错误:
{"id": "vpc-zone", "type": "rectangle", "x": 50, "y": 50, "width": 800, "height": 400, "text": "VPC (10.0.0.0/16)"}
正确——使用独立文本元素,将其锚定在区域顶部:
{"id": "vpc-zone", "type": "rectangle", "x": 50, "y": 50, "width": 800, "height": 400, "backgroundColor": "#e3f2fd"},
{"id": "vpc-label", "type": "text", "x": 70, "y": 60, "width": 300, "height": 30, "text": "VPC (10.0.0.0/16)", "fontSize": 18}
独立文本元素会位于区域的顶部角落,不会干扰其中的元素。
2. 避免复杂图表中的跨区域箭头
从一个布局区域中的元素指向另一个远处区域中的元素时,箭头会画出一条很长的对角线,穿过中间的所有内容。在多区域基础设施图表中,这会形成难以辨认的线团。
**设计规则:**箭头应保持在同一区域或同一层级内。若要展示跨区域关系,请使用注释文本,或将区域分开,使其边缘相邻(中间不放置元素),并沿边缘绘制箭头。
如果必须跨区域连接,请使用折线箭头沿外围绘制——绝不要穿过其他区域的中央。
3. 谨慎使用箭头标签
箭头标签会放在箭头的中点。对于较短的箭头,标签会与两端的形状重叠;在拥挤的图表中,标签还会与附近元素碰撞。
- 只有当关系名称确实不可或缺时(例如协议、端口号、数据方向),才添加箭头标签。
- 如果你给每个箭头都添加了标签,请重新考虑——这通常只会增加视觉干扰,而不会提升清晰度。
- 箭头标签请控制在 ≤ 12 个字符。对于密集的图表,最好完全省略标签。
质量:为何重要(以及如何检查)
Excalidraw 图表用于视觉传达。如果文本被截断、元素相互重叠,或箭头穿过无关形状,图表就会变得令人困惑且不够专业——这违背了绘图的初衷。因此,每批元素添加完成后,都应先检查,再继续添加。
质量检查清单
每次执行 add / apply / batch_create_elements 后,都要截图并检查:
- 文本截断 — 标签文本是否全部清晰可见?文本被截断意味着形状太小。增大
width和/或height。 - 重叠 — 是否有形状占据相同空间?背景区域必须留出内边距,完整包含子元素。
- 箭头交叉 — 箭头是否穿过了无关元素?如果是,请使用曲线箭头或折线箭头绕开(参见下文的箭头路径规划)。
- 箭头与标签重叠 — 箭头标签位于中点。如果与形状重叠,请缩短标签或调整箭头路径。
- 间距 — 元素之间至少间隔 40px。布局过于拥挤会难以阅读。
- 可读性 — 正文的字号 ≥ 16,标题的字号 ≥ 20。
- 区域标签位置 — 如果在背景区域矩形上使用了
text/label.text,区域标签会位于区域中央,与内部的所有内容重叠。解决方法:删除绑定的文本元素,并在区域顶部添加一个独立文本元素(参见上文的布局反模式)。
如果发现任何问题:停止操作,修复问题,重新截图,然后再继续。 要说“我发现了[问题],正在修复”,不要轻描淡写地略过问题。只有所有检查都通过后,才能继续。
工作流:绘制新图表
Mermaid 与直接创建 — 应该使用哪种方式?
在以下情况下使用 mermaid / create_from_mermaid:用户已经有 Mermaid 图表,或者其结构可以轻松映射为采用标准 Mermaid 语法的流程图、时序图或 ER 图。这种方式速度快,且可自动处理转换,不过对精确布局的控制较少。
在以下情况下直接创建元素:需要精确控制布局、图表类型难以映射到 Mermaid(例如自定义架构图、带注释的云图),或者需要将元素放置在特定的坐标网格中。
步骤(此处展示 CLI;MCP 工具一一对应 — 参见速查表)
- 规划坐标网格 — 在编写 JSON 前,先规划各层级和 x 坐标。(MCP 模式:调用
read_diagram_guide获取颜色/尺寸指南;相同指南也位于references/cheatsheet.md中。) - 可选:重新开始:
npx -y mcp-excalidraw-server clear --yes - 在一次调用中创建形状和箭头。自定义
id字段(例如"id": "auth-svc")便于后续更新:
(位置参数npx -y mcp-excalidraw-server add - <<'EOF' [ {"id": "lb", "type": "rectangle", "x": 300, "y": 50, "width": 180, "height": 60, "text": "Load Balancer"}, {"id": "svc-a", "type": "rectangle", "x": 100, "y": 200, "width": 160, "height": 60, "text": "Web Server 1"}, {"id": "svc-b", "type": "rectangle", "x": 450, "y": 200, "width": 160, "height": 60, "text": "Web Server 2"}, {"id": "db", "type": "rectangle", "x": 275, "y": 350, "width": 210, "height": 60, "text": "PostgreSQL"}, {"type": "arrow", "x": 0, "y": 0, "startElementId": "lb", "endElementId": "svc-a"}, {"type": "arrow", "x": 0, "y": 0, "startElementId": "lb", "endElementId": "svc-b"}, {"type": "arrow", "x": 0, "y": 0, "startElementId": "svc-a", "endElementId": "db"}, {"type": "arrow", "x": 0, "y": 0, "startElementId": "svc-b", "endElementId": "db"} ] EOF-可选 — 不提供文件参数时,add会从 stdin 读取输入。) - 使用
max(160, labelLength * 12)设置形状宽度。 screenshot→ 查看文件 → 执行质量检查清单 → 在下一批操作前修复问题。
箭头路径规划 — 避免重叠
在复杂图表中,直线箭头可能会穿过其他元素。必要时使用曲线箭头或折线箭头:
曲线箭头(沿平滑弧线绕过障碍物):
{
"type": "arrow", "x": 100, "y": 100,
"points": [[0, 0], [50, -40], [200, 0]],
"roundness": {"type": 2}
}
中间航点 [50, -40] 会使箭头向上绕行。roundness: {type: 2} 可使箭头平滑弯曲。
折线箭头(直角 / L 形路径):
{
"type": "arrow", "x": 100, "y": 100,
"points": [[0, 0], [0, -50], [200, -50], [200, 0]],
"elbowed": true
}
使用场景:
- 扇出(一个源 → 多个目标):使用曲线箭头,并分散设置航点以避免重叠
- 跨通道(连接到侧边面板):使用先向上、再横向、最后向下的折线箭头
- 长水平连接:使用略微偏移垂直位置的曲线箭头
规则: 如果箭头会穿过无关形状,就添加航点绕开它。
工作流:迭代优化
将 describe 与 screenshot 配合使用,才能充分发挥此技能的优势。
describe(MCP 中的describe_scene)→ 结构化文本:元素 ID、类型、位置、标签、连接关系。在进行程序化更新之前,用它了解 画布上有什么(查找 ID,了解边界框)。screenshot(MCP 中的get_canvas_screenshot)→ PNG,由 Excalidraw 自带渲染器从规范画布状态无头渲染而成(无需浏览器标签页,只需几毫秒)。用它进行 视觉质量验证——它能准确显示图表的外观,包括截断、重叠和箭头走向。CLI 会以 JSON 格式输出保存的文件路径;读取/查看该文件。密集图表可用--scale 2提高可读性;用--ids a,b或--frame <id>放大查看某个部分;用--dark切换到深色模式。
反馈循环:
add elements
→ screenshot → view → "text truncated on auth-svc"
→ update auth-svc --set '{"width": 220}' → screenshot → "overlap between auth-svc and rate-limiter"
→ update rate-limiter --set '{"x": 520}' → screenshot → "all checks pass"
→ proceed
工作流:优化现有图表
- 使用
describe了解当前状态——记下元素 ID 和位置。 - 通过
id或标签文本识别元素(不要使用 x/y 坐标——它们会变化)。 - 使用
update <id> --set '{...}'调整大小、更改颜色或移动元素;使用delete <id>删除元素;也可以将所有操作合并到一个apply补丁中。移动或调整端点大小时,绑定的箭头会自动重新规划路径——无需删除并重新创建。 - 使用
screenshot确认更改后的效果。 - 如果更新失败:使用
get <id>检查 ID 是否存在;如果元素已锁定,则使用arrange unlock --ids <id>解锁。
工作流:Mermaid 转换
echo 'graph TD
A[Client] --> B[API]
B --> C[(DB)]' | npx -y mcp-excalidraw-server mermaid
需要打开浏览器标签页(转换在前端运行;退出代码 4 表示需要打开画布 URL)。之后使用 screenshot 验证布局。如果自动布局效果不佳(节点拥挤、边交叉),使用 describe 找出问题元素,再用 update 重新定位。
工作流:文件 I/O
- 导出场景:
export --out diagram.excalidraw(不带--out→ 将 JSON 输出到 stdout) - 导入场景:
import diagram.excalidraw(追加)或import diagram.excalidraw --replace - 图像:
screenshot --out diagram.png/screenshot --format svg --out diagram.svg(无头;SVG 会嵌入字体) - 离线:
render diagram.excalidraw --out diagram.png可在没有画布服务的情况下渲染已保存的文件(适用于 CI,标志与screenshot相同) - 分享链接:
share——加密场景并返回可分享的 excalidraw.com URL(若已设置EXCALIDRAW_SHARE_UPLOAD_URL/EXCALIDRAW_SHARE_BASE_URL,则返回可自托管实例的链接)
图表可这样保存在代码仓库中:提交 .excalidraw 文件;架构发生变化时,再次 import、编辑并 export。
Obsidian 库:使用 .excalidraw.md
写入前请检查目标位置:如果任一上级目录包含 .obsidian/,则该目录属于 Obsidian 库。原始 .excalidraw 文件在此处只能以 兼容模式 在 Excalidraw 插件中打开(并显示“转换为新格式”警告),无法使用块引用或全库搜索,且默认的 Obsidian Sync 会跳过非 .md 文件。为导出文件指定 .excalidraw.md 扩展名,CLI 就会自动写入插件的原生格式:
npx -y mcp-excalidraw-server export --out "$VAULT/diagrams/system-map.excalidraw.md" # .md → Obsidian format (or force with --format obsidian)
npx -y mcp-excalidraw-server import "$VAULT/diagrams/system-map.excalidraw.md" --replace # reads both plain and compressed Drawing blocks
往返转换是安全的:文本元素的块引用遵循插件自身的 ID 规则,因此重新导入、编辑并重新导出同一文件,不会影响其他笔记中的链接。
工作流:快照
- 在进行有风险的更改前,使用
snapshot save <name>。 - 进行更改,并使用
describe/screenshot评估。 - 如需回滚,使用
snapshot restore <name>。snapshot list可查看已保存的快照。
工作流:复制
arrange duplicate --ids a,b --offset 40,40(默认偏移量为 20,20)。适用于重复图案或复制布局。
错误恢复
- 退出代码 3(画布无法访问)? 自动启动已禁用(
EXCALIDRAW_NO_AUTOSTART=1),或设置了非回环的EXPRESS_SERVER_URL。请显式运行start,或修正环境变量。 - 退出代码 4(需要浏览器)? 只有
mermaid和screenshot --renderer browser需要打开的标签页。请在浏览器中打开http://127.0.0.1:3000后重试,或移除--renderer browser——截图和图像导出会以无头模式渲染。 - 元素没有显示? 检查
describe——元素可能在屏幕之外。在 MCP 模式下,使用set_viewport并设置scrollToContent: true,或使用scrollToElementIds及可选的viewportZoomFactor聚焦特定子图;在浏览器中,点击缩放至适应按钮。 - 箭头未连接? 使用
get <id>验证元素 ID。确保startElementId/endElementId与现有元素 ID 匹配。 - 画布状态异常? 先运行
snapshot save,然后运行clear --yes并重新构建。或者运行snapshot restore恢复到之前的状态。 - 元素无法更新? 元素可能已锁定——先运行
arrange unlock --ids <id>。 - 文本元素重复/元素数量翻倍? 前端的自动同步计时器会定期将完整的 Excalidraw 场景写回服务端。Excalidraw 会在内部为每个带标签的形状生成一个绑定文本元素;清除并重新发送元素时,可能会重新注入缓存的绑定文本。清理方法:运行
query --type text查找带有containerId的元素,删除不需要的元素,然后等待几秒,让自动同步完成。最稳妥的预防方法:切勿给背景区域矩形添加标签——请改用独立的文本元素。
参考资料
references/cheatsheet.md:完整的 CLI 参考、26 个 MCP 工具、REST API 端点及其载荷结构,以及图表设计指南(颜色、尺寸)。