localfig について
localfig は、AI エージェントが Figma デスクトップアプリの Plugin API を通じて、開いているファイルを読み書きできる MCP サーバーです。Figma のクラウド API トークンや利用枠を使わず、ローカルで動作します。
主な機能
- 01Plugin API による読み書き
- 02任意の Plugin API JavaScript の実行
- 03メタデータ、スタイル、トークンの確認
- 04ページ検索と変更追跡
- 05デザインのエクスポートと画像配置
- 06編集の取り消しとスナップショット保存
活用シーン
- 01AI エージェントからデザインファイルを編集
- 02デザインシステムのトークンやコンポーネントを確認
- 03Figma 上での呼び出し間の変更を確認
- 04フレームのエクスポートやローカル画像の追加
MCP 対応
stdio 経由で MCP クライアントに Figma Plugin API のツールを提供し、ループバック HTTP ブリッジで起動中のデスクトッププラグインに接続します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
10掲載時のツール一覧 · 2 週間前に更新
このツールにパラメーターはありません。
詳細
localfig
Figma デスクトップアプリを MCP サーバーとして利用できます。 localfig は、小さな開発用プラグインとループバック HTTP ブリッジを介して、開いているファイルで Figma Plugin API の全機能を AI エージェントに提供します。すべてお使いのマシン上で動作します。
- 読み取りと書き込みに対応しています。 フレーム、テキスト、オートレイアウト、変数、コンポーネント、画像塗りつぶし、エクスポート、取り消しなど、Plugin API でできることは何でもエージェントが実行できます。
- Figma のクラウド API、個人用アクセストークン、アカウントごとのクォータは不要です。
- 依存関係はゼロです。 Node.js の組み込み機能のみを使用します。マシンの外にデータが送信されることはありません。
- stdio サーバーを起動できる MCP クライアントであれば、Claude Code、Cursor、Windsurf、Cline、Claude Desktop など、どれでも動作します。
MCP client --stdio JSON-RPC--> localfig --http localhost:8765--> Figma plugin --> Plugin API
localfig を選ぶ理由
| localfig | 公式 Figma MCP | REST API サーバー | 固定コマンドのプラグインブリッジ | |
|---|---|---|---|---|
| ファイルへの書き込み | Plugin API でできることは何でも | 限定的 | いいえ — REST API ではノードに書き込めません | 固定メニューのコマンド |
| 任意の Plugin API JavaScript | はい (figma_eval) | いいえ | いいえ | いいえ |
| クォータ/ログイン | なし | プランによる | トークンとレート制限 | なし |
| トークン、スタイル、コンポーネントの読み取り | figma_tokens、figma_metadata | はい。Code Connect を含む | 一部対応 | まれ |
| エージェントがデザインを画像として確認できる | はい。レスポンスにインラインで表示 | はい | ファイルまたはリンク。インライン表示ではない | 実装による |
| エージェントのステップごとの取り消し、変更追跡 | はい | いいえ | いいえ | いいえ |
要件
- Node.js 18 以降
- Figma デスクトップアプリ — 開発用プラグインはブラウザーではインポートできません
- MCP クライアント:Claude Code、Cursor、Windsurf、Cline、Claude Desktop など
インストール(初回のみ)
npx -y localfig --setup
これにより、ローカルシークレットが生成され、プラグインが ~/.localfig/plugin/ に書き込まれ、お使いのマシン上で見つかったすべての MCP クライアントに localfig が登録され、次の手順で使うマニフェストのパスが表示されます。--dry-run を指定すると、何も変更せずに実行内容を確認できます。--clients=cursor,vscode を指定すると、指定したクライアントのみに限定できます。クローンを使いたい場合は、git clone https://github.com/LucasGorgal/localfig.git && cd localfig && node server.mjs --setup でも同じことができます。
| クライアント | localfig の登録先 |
|---|---|
| Claude Code | claude mcp add --scope user |
| Claude Desktop | claude_desktop_config.json |
| Cursor | ~/.cursor/mcp.json |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| VS Code(Copilot エージェントモード) | ユーザーの mcp.json |
| Cline(拡張機能と CLI) | ~/.cline/data/settings/cline_mcp_settings.json、または旧バージョンでは VS Code の拡張機能ストレージ |
| Gemini CLI | ~/.gemini/settings.json |
| Codex | ~/.codex/config.toml |
| opencode | ~/.config/opencode/opencode.json |
| Zed | context_servers 内の settings.json |
| LM Studio | ~/.lmstudio/mcp.json |
クライアントの設定フォルダーが存在すれば、インストール済みと見なされます。セットアップでは既存ファイルを置き換えずに設定をマージするため、他のサーバーや設定は保持され、既存の localfig エントリの env も維持されます。また、変更の前に .localfig.bak のコピーが作成されます。コメントを含む settings.json など、安全に書き換えられないファイルはそのまま残され、貼り付けるエントリが表示されます。すでに起動しているクライアントは再起動してください。
一覧にないクライアントの場合は、MCP 設定に次の内容を追加してください。
{ "mcpServers": { "localfig": { "command": "npx", "args": ["-y", "localfig"] } } }
Windows では、代わりに "command": "cmd", "args": ["/c", "npx", "-y", "localfig"] を使用してください。ほとんどのクライアントはシェルを介さずにサーバーを起動しますが、Windows では npx は .cmd スクリプトだからです。
次に、プラグインを Figma にインポートします(初回のみ)。
- デスクトップアプリで任意のデザインファイルを開きます。「プラグイン」メニューはファイル内にのみあり、ホーム画面にはありません。
- Figma メニュー(左上のロゴ)→ プラグイン → 開発 → マニフェストからプラグインをインポート… の順に選択します。または、
Ctrl/(Cmd/)を押して、マニフェストからプラグインをインポート と入力します。 ~/.localfig/plugin/manifest.jsonを選択します(セットアップの出力に完全なパスが表示されます)。
マニフェストでは、2 つの権限(ライブラリのコンポーネントとトークン用の teamlibrary、操作しているユーザーの確認用の currentuser)を要求し、再起動ボタンを登録します。
使用(セッションごと)
- 作業するファイルを開きます。
- プラグインを実行します。
Ctrl/→ localfig の順に選択します。または、CtrlAltP(CmdOptP)を押して最後に使ったプラグインを再実行するか、実行したことのあるファイルのプロパティパネルにある localfig に再接続 ボタンを使います。小さなパネルが表示され、MCP サーバーの起動後に localfig に接続しました と表示されます。開いたままにしてください。 - エージェントに Figma の作業を依頼します。すべてのツールはプラグインが実行されているファイルに対して動作します。ファイルキーは存在しないため、クラウドには一切アクセスしません。
パネル(またはファイル)を閉じると接続が切れます。再接続するにはプラグインを再実行してください。これが唯一の手動操作です。Figma には外部からプラグインを起動する方法がありません。
ツール
| ツール | 内容 |
|---|---|
figma_status | プラグインは接続されていますか?ファイル、ページ、選択範囲、最上位フレーム、操作中のユーザー、動的コード実行が利用可能かどうかを確認します |
figma_eval | ファイル内で任意の Plugin API JavaScript を実行します。主力ツールです |
figma_metadata | サブツリーの構造ダンプです。ID、名前、タイプ、ジオメトリ、テキストを表示します。styles: true を指定すると、ノードごとに塗り(16 進数)、グラデーションの停止位置、フォント、エフェクト、オートレイアウト、バインドされた変数、名前付きスタイル、コンポーネント情報が追加されます。css: true を指定すると、ノードごとにFigma が計算した CSSが追加されます |
figma_tokens | すべてのローカル変数コレクションと、そのモードおよびモードごとの値に加え、塗り/テキスト/エフェクトのスタイルを表示します |
figma_find | 現在のページまたはすべてのページを、タイプ、レイヤー名の正規表現、テキストの正規表現で検索します |
figma_changes | 前回の呼び出し以降の変更を表示します。作成、削除、プロパティの変更、ノードごとの概要が含まれます。ツール呼び出しによる編集にはタグが付けられ、デフォルトでは非表示になるため、その間にユーザーが Figma で行った操作を確認できます |
figma_history | snapshot:名前付きバージョン(復元ポイント)を保存します。undo:直前のツール呼び出しを元に戻します。変更を伴う呼び出しはすべて、1 つの取り消しステップとして記録されます |
figma_library | チームライブラリの変数コレクションと変数の一覧表示、キーによるコンポーネント/スタイル/変数のインポート、インスタンスの配置を行います |
figma_export | ノードを PNG/JPG/SVG/PDF/JSONとしてディスクにエクスポートします。PNG/JPG は画像としてインラインで返され、JSON(Figma REST API 形式のサブツリー)と SVG はテキストとしてインラインで返されます |
figma_place_image | ローカル画像をノードの塗りに設定します。ブラウザーがデコードできる形式(PNG、JPG、WebP、GIF、BMP、AVIF)に対応します。1 辺が 4096px を超える画像は自動的に縮小されます(maxSide) |
figma_eval 環境
コードはプラグインのサンドボックス内で非同期関数にラップされて実行されます。トップレベルの await と return の両方を使用できます。
const n = await figma.getNodeByIdAsync('10:59'); // sync getNodeById is unavailable (dynamic-page access)
await helpers.setText(n.findOne(x => x.type === 'TEXT'), 'new copy');
helpers.reveal(n); // put it on the person's screen
return { id: n.id, w: n.width }; // JSON-serialized back to the agent
グローバル変数:figma と helpers。
helpers.createText({characters, font: {family, style}, fontSize, color: '#hex', width, lineHeight, letterSpacing, textCase, textAlign, name, parent, x, y})— フォントを読み込み、resize()をtextAutoResizeより先に実行します。helpers.setText(node, chars)— ノードで実際に使用されているフォントを読み込んでから、文字列を設定します。helpers.loadNodeFonts(node)。helpers.set(node, props)— 一括で割り当てます。layoutModeを最初に設定し、width/heightはresizeで設定してから、サイズ設定モードを設定します。helpers.rgb('#rrggbb')、helpers.rgba('#rrggbbaa')— 16 進数を、塗りで使用する{r, g, b[, a]}に変換します。helpers.reveal(nodes)— 作成したものが表示されるよう、ビューポートをスクロールしてズームします。helpers.notify(msg)— トースト通知を表示します。helpers.collection(name, [modes])、helpers.token(collection, name, type, value | {mode: value})、helpers.bind(node, 'fills' | 'strokes' | prop, variable)— デザイントークンを作成し、プロパティにバインドします。それぞれ 1 行で記述できます。helpers.importComponent(key)、helpers.instance(key, parent, props)— チームライブラリのコンポーネントを扱います。helpers.query(root, sel)— 最小限のセレクターに対応します:TEXT、[name=X]、[name*=X]、A B、a, b。helpers.createAutoLayout(dir, props)。helpers.command(kind, payload)— スクリプト内から任意の型付きコマンド(tokens、metadata、find、changes、exportなど)を実行します:(await helpers.command('tokens', { collection: 'Brand' })).result。
ヘルパーで回避できる Plugin API の注意点
- TEXT ノードで
resize()を呼び出すとtextAutoResizeがNONEにリセットされます。オートレイアウトフレームでは、両方のサイズ設定モードがFIXEDに設定されます。先にリサイズしてから、サイズ設定を行ってください。 figma_evalからはプレーンデータを返してください。実際の Figma ノードは{id, name, type}に折りたたまれるため、ノード参照が誤って結果に大量に含まれることはありません。サブツリーを調べるにはfigma_metadataを使用してください。- テキストを変更する前にフォントを読み込んでください。
- ここでは
figma.notify()が動作します(クラウド MCP ではブロックされます)。
デザインシステムへの対応
figma_tokens は、デザインシステムの考え方に沿ってファイルの変数を返します。
{ "collections": [{ "name": "Brand", "modes": ["Light", "Dark"], "defaultMode": "Light",
"variables": [{ "name": "color/bg", "type": "COLOR", "values": { "Light": "#ffffff", "Dark": "#04060c" } },
{ "name": "space/md", "type": "FLOAT", "values": { "Light": 16, "Dark": 16 } },
{ "name": "color/accent", "type": "COLOR", "values": { "Light": "{color/blue-500}", "Dark": "{color/blue-300}" } }] }],
"styles": { "paint": [...], "text": [...], "effect": [...] } }
続いて、styles: true を指定した figma_metadata は、ノードごとに boundVariables(各プロパティを制御するトークン)、fillStyle/textStyle/effectStyle の名前、インスタンスの場合はメインの component とその componentProperties を報告します。css: true を指定すると、各ノードについて Figma が計算した CSS が追加されます。これらを組み合わせることで、エージェントは値をハードコードせず、デザインシステムに基づいて構築でき、実際のファイルからコードを引き継ぐこともできます。
画像
- 入力:
figma_place_imageはファイルのバイト列をプラグイン UI に送信します。これは完全な Chromium iframe です。ブラウザーが対応する形式をデコードし、maxSide(デフォルトは 4096、Figma の上限値)に合わせて高品質なスムージングで縮小し、ネイティブ形式以外の画像を PNG に変換して、メインスレッドに渡します。ツールの結果では、処理内容(prepared)が報告されます。 - 出力:
figma_exportは~/.localfig/exports/にファイルを書き込み、PNG/JPG(各 2 MB 以下)を画像として結果に添付するため、エージェントは追加の呼び出しなしでレンダリング結果を確認できます。JSONはサブツリーを Figma REST API の形式でエクスポートします。
元に戻す、バージョン、変更の追跡
変更を行う各ツール呼び出しは figma.commitUndo でチェックポイントされるため、ファイルの元に戻す履歴に、人が Ctrl+Z で戻せる 1 つのステップ として記録されます(最後の呼び出しは、完了から 60 秒後、または次の呼び出し時に確定されます)。この時間内であれば、figma_history {action: "undo"} はエージェント側から最後の呼び出しを元に戻し、triggerUndo は最後のチェックポイントまで戻します。また、{action: "snapshot"} はリスクのある編集の前に名前付きバージョンを保存します。プラグインは、認識したすべてのページでノードの変更も記録します(Figma からは変更がまとめて後から届きます)。figma_changes は、指定した seq 以降の変更を返します。ツール呼び出しによる編集には時間枠に基づく判定で byPlugin のタグが付けられ、デフォルトでは非表示になります。これにより、エージェントは変更を上書きすることなく、呼び出しの間に人が Figma で行った変更を把握できます。
複数のセッション
最初に起動した localfig プロセスがブリッジのポートを所有します。後続のプロセスは /health を通じてそれを検出し、クライアントとして実行され、そのプロセス経由で処理を中継します。どちらの場合も同じツールを使用できます。所有者が停止した場合、クライアントで次にツールを呼び出すと、ポートを再バインドして引き継ぎます(ログでは「re-election」と記録されます)。プラグインは再接続時に再登録されます。
ファイルと設定
~/.localfig/
token local secret (generated on first run)
plugin/ manifest.json + code.js + ui.html — import THIS manifest into Figma
exports/ where figma_export writes
| 変数 | デフォルト | 説明 |
|---|---|---|
LOCALFIG_HOME | ~/.localfig | トークン、プラグイン、エクスポートの保存先 |
LOCALFIG_PORT | 8765 | マニフェストの networkAccess も変更し、プラグインを再インポートしてください |
LOCALFIG_OUT | ~/.localfig/exports | figma_export の書き込み先 |
node server.mjs --help でフラグを確認できます。
セキュリティ
ブリッジはループバックアドレス(127.0.0.1 および ::1)のみにバインドします。/health を除くすべてのエンドポイントでは、初回起動時に生成され、~/.localfig/token に保存されて ~/.localfig/plugin/ui.html に埋め込まれる 32 桁の 16 進数のシークレットが必要です。パッケージ内の plugin/ui.template.html を編集してください。生成された ui.html は編集しないでください。サーバーにデータが送信されることはありません。
設計に関するメモ
- なぜプラグインなのですか? 開いている Figma ドキュメントに対して、ローカルから完全な読み書き権限を持つ唯一の手段だからです。REST API はクラウド経由で、トークンが必要なうえ、ノードを書き込めません。
- なぜ WebSocket ではなく HTTP ロングポーリングなのですか? プラグインのメインスレッドにはネットワーク機能がなく、利用できるのは UI iframe だけだからです。ロングポーリングなら依存関係もフレーミング用コードも不要で、
http://localhostは混在コンテンツによるブロックの対象外です。Figma のマニフェストバリデーターはnetworkAccess内の生の IP アドレスを拒否するため、localhostを使用します。また、Windows ではlocalhostが最初に::1に解決されるため、IPv6 ミラーリスナーも使用します。 - プラグインチャネルではバイナリをバイナリのまま扱います。 エクスポートは
POST /blobで送信し、画像はGET /assetでUint8Arrayに取り込みます。コマンドチャネルを通るのは JSON だけです。(レンダーは、プロトコルで必要とされる MCP の結果内でのみ、一度だけ base64 エンコードされます。) - なぜホームディレクトリが必要なのですか? パッケージは npx のキャッシュ内や読み取り専用のグローバルインストール先に置かれる場合があります。インポートするプラグインフォルダーはパッケージの更新後も移動してはならず、ユーザーごとの状態をパッケージ内に置いてはなりません。
プラットフォームに関するメモ
Figma デスクトップアプリを使用し、Windows 11 で開発およびテストしました。Node の組み込み機能のみを使用し、ネイティブコードはないため、macOS と Linux でも変更なしで動作するはずですが、まだテストされていません。報告や修正を歓迎します。
テスト
node test-e2e.mjs
サーバーを分離されたホームディレクトリで起動し、stdio 経由で MCP と通信し、HTTP 経由でプラグインを装います。ハンドシェイク、10 個すべてのツール、ファイルの往復、インライン画像、オーナーの再選出、サンドボックス化された MCP クライアント設定でのセットアップを、Figma を起動せずに網羅します。アサーションは 55 件です。
構成
server.mjs MCP (stdio) + bridge (http), single process; --setup, --help
plugin/manifest.json copied to ~/.localfig/plugin on start
plugin/code.js main thread: executes commands against the Plugin API
plugin/ui.template.html UI source; token/port get baked into ~/.localfig/plugin/ui.html
test-e2e.mjs end-to-end test without Figma
ライセンス
MIT — LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。