Communitygithub.com

yctimlin/excalidraw-skill

在即時畫布上建立、編輯與精煉圖表的 Excalidraw 工具包。當 AI 需要繪製圖表、迭代調整、匯出匯入檔案、管理快照、轉換 Mermaid 或進行元素層級操作時使用。

excalidraw-skill 是什麼?

這項技能為 AI 代理提供了一個完整的 Excalidraw 圖表工具包,支援即時畫布上的建立、編輯與精煉。它提供三種等效的介面:MCP 工具(推薦,可直接在上下文處理結果)、CLI 工具(`npx -y mcp-excalidraw-server`,會自動啟動伺服器)與 REST API。此技能擅長處理從簡化流程圖到複雜的雲端架構圖,具有「品質檢查清單」以防止文字截斷、元素重疊與箭頭交叉等常見問題。它支援批次建立元素(使用類似 `apply patch.json` 的多操作更新)、場景檔案的匯出/匯入(包括 Obsidian 的 `.excalidraw.md` 格式)、基於快照的協作、使用 `mermaid` 指令將 Mermaid 語法轉換為 Excalidraw,以及透過 `describe`(結構化文字摘要)與 `screenshot`(PNG/SVG 輸出)進行迭代調整的關鍵反饋迴圈。其智慧元素格式會自動將代理友好欄位(如 `text`、`startElementId`/`endElementId`)正規化為 Excalidraw 的原生格式,大幅簡化程序化操作。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/yctimlin/mcp_excalidraw/tree/main/skills/excalidraw-skill

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

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 端點位於 http://127.0.0.1:3000 — 請參閱 references/cheatsheet.md 取得請求內容。伺服器必須已在執行中。

畫布 URL 來自 EXPRESS_SERVER_URL(預設為 http://127.0.0.1:3000)。提醒使用者在瀏覽器中開啟該 URL — 螢幕截圖、圖片匯出、mermaid 轉換和視埠控制都需要開啟的分頁(缺少時 CLI 會以代碼 4 退出)。

CLI 快速參考

結果以 JSON 格式輸出到 stdout — 除了 describe(純文字)以及在省略 --out 時的原始內容輸出(export 場景 JSON,screenshot --format svg 輸出原始 SVG)。診斷資訊則輸出到 stderr。結束代碼:0 成功,1 錯誤,2 使用方式錯誤,3 無法連線畫布,4 需要瀏覽器分頁。

任務命令
啟動 / 停止 / 檢查伺服器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
場景檔案export [--out scene.excalidraw], `import [scene.excalidraw
Mermaid → 畫布`mermaid [diagram.mmd
快照`snapshot save
分享連結share(加密上傳 → excalidraw.com URL)
清除畫布clear --yes
安裝 / 升級此技能install-skill --dir <skills-root>(代理選擇專案/全域根目錄)

元素格式(CLI 和 MCP)

CLI 和 MCP 工具接受相同的代理友好格式,並會自動將其正規化:

  • 標籤:在任何形狀上放置 "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 更嚴格:標籤必須使用 "label": {"text": "..."},綁定必須使用 "start": {"id": "..."} / "end": {"id": "..."}。只有在直接 POST 到 API 時才需要擔心這個。


座標系統

畫布使用二維座標網格:(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 vs. 直接建立 — 該用哪個?

當以下情況時使用 mermaid / create_from_mermaid:使用者已經有一個 Mermaid 圖表,或者結構可以清楚地映射到流程圖、序列圖或 ER 圖,並使用標準的 Mermaid 語法。它速度很快,可以自動處理轉換,但你對確切佈局的控制較少。

當以下情況時直接建立元素:你需要精確的佈局控制,圖表類型不容易映射到 Mermaid(例如自訂架構、帶註解的雲端圖表),或者你想將元素放置在特定的座標網格中。

步驟(以 CLI 顯示;MCP 工具是 1:1 對應的 — 請參閱小抄)

  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。用它進行視覺品質驗證 — 它會準確顯示使用者看到的內容,包括截斷、重疊和箭頭路線規劃。CLI 會將儲存的檔案路徑以 JSON 格式輸出;請讀取/檢視該檔案。

反饋循環:

add elements
  → screenshot → view → "auth-svc 上的文字被截斷"
  → update auth-svc --set '{"width": 220}' → screenshot → "auth-svc 與 rate-limiter 重疊"
  → update rate-limiter --set '{"x": 520}' → screenshot → "所有檢查通過"
  → 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(需要瀏覽器分頁)
  • 分享連結:share — 加密場景並回傳一個可分享的 excal

…

[翻譯時已截斷]

相關技能