mcpField
E
excalidraw-skill

excalidraw-skill

github.com/yctimlin设计与 UI2.6k515 次安装1 周前更新
代码仓库

关于 excalidraw-skill

Excalidraw Skill 帮助 Agent 通过 MCP 工具、CLI 或 REST API 操作实时 Excalidraw 画布,创建和修改图表,并检查渲染结果。它提供布局建议与质量检查流程,适用于需要绘制或迭代图示的场景。

主要功能

  1. 01通过 MCP、CLI 或 REST 操作画布
  2. 02批量创建、更新和删除图形元素
  3. 03将 Mermaid 图表转换为画布内容
  4. 04导入、导出和管理快照
  5. 05截图检查布局与可读性

适用场景

  1. 01绘制系统架构或流程图
  2. 02把 Mermaid 图表转为画布图示
  3. 03批量调整已有画布元素
  4. 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:选择接口

三个接口都操作同一个实时画布。选择第一个适用的接口:

  1. MCP 工具 — 如果你的工具列表中有 excalidraw/* 工具(例如 batch_create_elements),优先使用它们:结果会直接返回到你的上下文中,截图也会以图像形式返回,无需写入磁盘。
  2. 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>。
  3. 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 后,都要截图并检查:

  1. 文本截断 — 标签文本是否全部清晰可见?文本被截断意味着形状太小。增大 width 和/或 height。
  2. 重叠 — 是否有形状占据相同空间?背景区域必须留出内边距,完整包含子元素。
  3. 箭头交叉 — 箭头是否穿过了无关元素?如果是,请使用曲线箭头或折线箭头绕开(参见下文的箭头路径规划)。
  4. 箭头与标签重叠 — 箭头标签位于中点。如果与形状重叠,请缩短标签或调整箭头路径。
  5. 间距 — 元素之间至少间隔 40px。布局过于拥挤会难以阅读。
  6. 可读性 — 正文的字号 ≥ 16,标题的字号 ≥ 20。
  7. 区域标签位置 — 如果在背景区域矩形上使用了 text/label.text,区域标签会位于区域中央,与内部的所有内容重叠。解决方法:删除绑定的文本元素,并在区域顶部添加一个独立文本元素(参见上文的布局反模式)。

如果发现任何问题:停止操作,修复问题,重新截图,然后再继续。 要说“我发现了[问题],正在修复”,不要轻描淡写地略过问题。只有所有检查都通过后,才能继续。


工作流:绘制新图表

Mermaid 与直接创建 — 应该使用哪种方式?

在以下情况下使用 mermaid / create_from_mermaid:用户已经有 Mermaid 图表,或者其结构可以轻松映射为采用标准 Mermaid 语法的流程图、时序图或 ER 图。这种方式速度快,且可自动处理转换,不过对精确布局的控制较少。

在以下情况下直接创建元素:需要精确控制布局、图表类型难以映射到 Mermaid(例如自定义架构图、带注释的云图),或者需要将元素放置在特定的坐标网格中。

步骤(此处展示 CLI;MCP 工具一一对应 — 参见速查表)
  1. 规划坐标网格 — 在编写 JSON 前,先规划各层级和 x 坐标。(MCP 模式:调用 read_diagram_guide 获取颜色/尺寸指南;相同指南也位于 references/cheatsheet.md 中。)
  2. 可选:重新开始:npx -y mcp-excalidraw-server clear --yes
  3. 在一次调用中创建形状和箭头。自定义 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 读取输入。)
  4. 使用 max(160, labelLength * 12) 设置形状宽度。
  5. 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

工作流:优化现有图表

  1. 使用 describe 了解当前状态——记下元素 ID 和位置。
  2. 通过 id 或标签文本识别元素(不要使用 x/y 坐标——它们会变化)。
  3. 使用 update <id> --set '{...}' 调整大小、更改颜色或移动元素;使用 delete <id> 删除元素;也可以将所有操作合并到一个 apply 补丁中。移动或调整端点大小时,绑定的箭头会自动重新规划路径——无需删除并重新创建。
  4. 使用 screenshot 确认更改后的效果。
  5. 如果更新失败:使用 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 规则,因此重新导入、编辑并重新导出同一文件,不会影响其他笔记中的链接。

工作流:快照

  1. 在进行有风险的更改前,使用 snapshot save <name>。
  2. 进行更改,并使用 describe / screenshot 评估。
  3. 如需回滚,使用 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 端点及其载荷结构,以及图表设计指南(颜色、尺寸)。

评论

支持 Markdown