excalidraw-skill について
Excalidraw Skillは、MCPツール、CLI、REST APIを通じて、エージェントがライブのExcalidrawキャンバスを操作できるスキルです。図の作成・編集に加え、レイアウト指針とスクリーンショットによる確認手順を備えています。
主な機能
- 01MCP、CLI、RESTでキャンバスを操作
- 02要素の一括作成・更新・削除
- 03Mermaid図をキャンバスに変換
- 04スナップショットの保存・復元・管理
- 05スクリーンショットで配置と可読性を確認
活用シーン
- 01システム構成図やフロー図の作成
- 02Mermaid図のキャンバスへの変換
- 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:インターフェースを選択する
3 つのインターフェースで同じライブキャンバスを操作できます。最初に当てはまるものを選んでください。
- 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 を伝えてください。URL を開くと、描画の様子を見てもらえます。
CLI クイックリファレンス
結果は stdout に JSON で出力されます。ただし、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 '{...}' |
| 1 回の呼び出しで複数の操作を適用 | apply patch.json — {"create":[...],"update":[{"id":"a","set":{...}}],"delete":[...]} |
| 1 つを読み取る/複数を検索 | 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](PNG で --out を省略すると、JSON に一時ファイルのパスを出力。SVG で --out を省略すると、生の 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>(プロジェクトまたはグローバルのルートはエージェントが選択) |
要素の形式(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}})のどちらかを使用できます。1 つの更新エントリーで両方の形式を混在させないでください。
生の REST はより厳密です:ラベルは "label": {"text": "..."}、バインドは "start": {"id": "..."}/"end": {"id": "..."} の形式で指定する必要があります。API に直接 POST する場合にのみ、この点に注意してください。
座標系
キャンバスは2D座標グリッドを使用します。(0, 0) が原点で、x は右方向に増加し、y は下方向に増加します。JSON を記述する前に、レイアウトを計画してください。
一般的な間隔のガイドライン:
- 階層間の垂直方向の間隔:80~120px(矢印がラベルに近づきすぎない程度)
- 兄弟要素間の水平方向の間隔:最低40~60px、ラベル付き矢印には120px以上
- 図形の幅:ラベルを1行に収めるには
max(160, labelCharCount * 12) - 図形の高さ:1行のラベルは60px、2行のラベルは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 ツールは 1 対 1 で対応しています。チートシートを参照してください)
- 座標グリッドを計画します。JSON を書く前に、階層と x 座標を割り当てます。(MCP モード:色やサイズについては
read_diagram_guideを呼び出します。同じガイダンスはreferences/cheatsheet.mdにもあります。) - 必要に応じて初期化します:
npx -y mcp-excalidraw-server clear --yes - 1 回の呼び出しで図形と矢印を作成します。カスタムの
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は標準入力を読み取ります。) - 次の式を使って図形の幅を設定します:
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
}
使い分け:
- 分岐(1 つの始点 → 複数の対象):ウェイポイントを分散させた曲線矢印を使い、重なりを避けます
- レーンをまたぐ接続(サイドパネルへの接続):上へ進み、横へ進み、下へ進む直角矢印を使います
- 長い水平接続:垂直方向に少しずらした曲線矢印を使います
ルール: 矢印が無関係な図形を横切る場合は、ウェイポイントを追加して迂回させます。
ワークフロー:反復的な調整
describe と screenshot を組み合わせることで、このスキルの真価を発揮できます。
describe(MCP ではdescribe_scene)→ 構造化テキスト:要素 ID、種類、位置、ラベル、接続。プログラムで更新する前に、キャンバス上に何があるかを把握するために使います(ID を見つけ、バウンディングボックスを確認します)。screenshot(MCP ではget_canvas_screenshot)→ Excalidraw 独自のレンダラーを使って、正規のキャンバス状態からヘッドレスで生成される PNG(ブラウザータブは不要で、数ミリ秒で生成されます)。視覚的な品質確認に使います。切り詰めや重なり、矢印の経路も含め、図が実際にどのように見えるかを確認できます。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 と位置を確認します。- 座標は変わるため、x/y 座標ではなく
idまたはラベルテキストで要素を特定します。 update <id> --set '{...}'でサイズ変更、色変更、移動を行います。削除するにはdelete <id>を使うか、すべてをまとめて 1 つの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 で位置を調整します。
ワークフロー:ファイルの入出力
- シーンをエクスポート:
export --out diagram.excalidraw(--outを指定しない場合は、JSON を標準出力に出力) - シーンをインポート:
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 モードでは、scrollToContent: trueを指定してset_viewportを使うか、scrollToElementIdsと省略可能なviewportZoomFactorを使って特定のサブグラフにフォーカスしてください。ブラウザーでは、ズームを合わせるボタンを押してください。 - 矢印が接続されませんか?
get <id>で要素 ID を確認してください。startElementId/endElementIdが既存の要素 ID と一致していることを確認してください。 - キャンバスの状態がおかしいですか? まず
snapshot saveを実行してから、clear --yesを実行し、再構築してください。または、snapshot restoreで元に戻してください。 - 要素を更新できませんか? ロックされている可能性があります。まず
arrange unlock --ids <id>を実行してください。 - テキスト要素が重複する/要素数が倍増しますか? フロントエンドの自動同期タイマーは、Excalidraw のシーン全体を定期的にサーバーに書き戻します。Excalidraw は、ラベルのある図形ごとに、内部的に紐づいたテキスト要素を生成します。要素を消去して再送信すると、キャッシュされた紐づきテキストが再挿入されることがあります。クリーンアップするには、
query --type textでcontainerIdを持つ要素を見つけ、不要な要素をdeleteし、自動同期が落ち着くまで数秒待ってください。これを防ぐ最も安全な方法は、背景ゾーンの四角形にラベルを付けないことです。代わりに、独立したテキスト要素を使ってください。
参考資料
references/cheatsheet.md:CLI の完全なリファレンス、26 個の MCP ツール、REST API のエンドポイントとペイロードの形式、図のデザインガイド(色、サイズ)。