mcpField
E
excalidraw-skill

excalidraw-skill

github.com/yctimlinデザイン・UI2.6k515 回インストール1 週間前に更新
リポジトリ

excalidraw-skill について

Excalidraw Skillは、MCPツール、CLI、REST APIを通じて、エージェントがライブのExcalidrawキャンバスを操作できるスキルです。図の作成・編集に加え、レイアウト指針とスクリーンショットによる確認手順を備えています。

主な機能

  1. 01MCP、CLI、RESTでキャンバスを操作
  2. 02要素の一括作成・更新・削除
  3. 03Mermaid図をキャンバスに変換
  4. 04スナップショットの保存・復元・管理
  5. 05スクリーンショットで配置と可読性を確認

活用シーン

  1. 01システム構成図やフロー図の作成
  2. 02Mermaid図のキャンバスへの変換
  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:インターフェースを選択する

3 つのインターフェースで同じライブキャンバスを操作できます。最初に当てはまるものを選んでください。

  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 を伝えてください。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 を実行するたびに、スクリーンショットを撮って確認します。

  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 対 1 で対応しています。チートシートを参照してください)
  1. 座標グリッドを計画します。JSON を書く前に、階層と x 座標を割り当てます。(MCP モード:色やサイズについては read_diagram_guide を呼び出します。同じガイダンスは references/cheatsheet.md にもあります。)
  2. 必要に応じて初期化します:npx -y mcp-excalidraw-server clear --yes
  3. 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 は標準入力を読み取ります。)
  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
}

使い分け:

  • 分岐(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

ワークフロー:既存の図を調整する

  1. describe で現在の状態を把握し、要素 ID と位置を確認します。
  2. 座標は変わるため、x/y 座標ではなく id またはラベルテキストで要素を特定します。
  3. update <id> --set '{...}' でサイズ変更、色変更、移動を行います。削除するには delete <id> を使うか、すべてをまとめて 1 つの 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 で位置を調整します。

ワークフロー:ファイルの入出力

  • シーンをエクスポート: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 ルールに従うため、同じファイルを再インポート、編集、再エクスポートしても、ほかのノートからのリンクは維持されます。

ワークフロー:スナップショット

  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 モードでは、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 のエンドポイントとペイロードの形式、図のデザインガイド(色、サイズ)。

コメント