はじめに
Figma の Dev Mode を開けば、色やフォントのコードスニペットはすでに見える。SwiftUI 向けの値も出る。じゃあ何が足りないのか。
足りないのは文脈だ。
Dev Mode は「この要素は #f97316 です」と教えてくれる。でもそれをプロジェクトのどのファイルに、どんな名前で、どういう設計で置くかは開発者の判断になる。色が30個あって、画面が7つあると、この判断だけで結構な時間を食う。
自分のケースでは、製品の販促用ゲーム(SwiftUI + SpriteKit のタワーディフェンス)で全画面の UI を Figma デザインに合わせてリデザインすることになった。ここで試したのが Figma Dev Mode MCP と Antigravity(AI コーディングエージェント)の組み合わせだった。
Figma Dev Mode MCP とは
MCP(Model Context Protocol)は、AI にツールを使わせるための標準規格。Figma が Dev Mode 内で提供している デスクトップ MCP サーバー を有効にすると、AI エージェントが Figma のデザインデータをプログラム的に読み取れるようになる。
セットアップは簡単で、Figma デスクトップアプリの Dev Mode を開いて、インスペクトパネルの「デスクトップ MCP サーバーを有効化」を押すだけ。ローカルに http://127.0.0.1:3845/mcp でサーバーが立ち上がるので、あとはエディタ側の MCP 設定でこのアドレスを指定すれば接続できる。
Dev Mode の画面を人間が見るのと違い、AI は取得した値をそのままコード生成に使える。人間が Dev Mode で値を確認 → コードに反映、という手順を踏むのに対して、AI は確認と生成を同時にやる。ここが決定的に違う。
AI が使えるツールはこのあたり:
| ツール | 用途 |
|---|---|
get_design_context |
指定ノードの色・フォント・レイアウト値を一括取得 |
get_screenshot |
ノードのスクリーンショット取得 |
get_metadata |
ページ構造(node ID・レイヤー名・座標)を XML で取得 |
get_variable_defs |
デザイン変数の定義を取得 |
Figma で選択して「これ実装して」と言うだけ
実際の開発フローを書く。
1. Figma で対象の要素を選択する
デスクトップ MCP サーバーにはセレクションベースという使い方がある。Figma デスクトップアプリで実装したいフレームやレイヤーを選択した状態で、AI に「これを実装して」と指示するだけでいい。AI が選択中のノードを自動的に認識してくれる。
URL を貼ってノード ID を伝える方法(リンクベース)もあるが、デスクトップサーバーならセレクションベースのほうが手軽。
2. AI がデザインデータを丸ごと取得する
AI は get_design_context で、選択中のノード配下のすべての値を取得する。たとえばアップグレード HUD を選択していた場合、こういう情報が返ってくる:
- パネル背景:
rgba(18,18,30,0.95)/ 角丸 24px - Power ロールカラー:
#f97316 - Speed ロールカラー:
#22d3ee - Range ロールカラー:
#a78bfa - Utility ロールカラー:
#4ade80 - 撤去ボタン:
#ff6467/ 背景rgba(239,68,68,0.15) - フォント: Inter Medium 17px / 13px / 12px
ここまでは Dev Mode のインスペクトパネルでも見える情報と同じ。違いは次のステップにある。
3. AI がプロジェクトの設計に沿ってコードを生成する
AI はこの値を、プロジェクト内の DesignTokens.swift に合わせた形で落とし込む。既存のトークンとの重複チェックもやるし、node ID をコメントに残してトレーサビリティも確保する:
enum DesignTokens {
// MARK: Role Colors (Figma node 16:332)
/// Power: #f97316 (orange)
static let rolePower = Color(red: 0.976, green: 0.451, blue: 0.086)
/// Speed: #22d3ee (cyan)
static let roleSpeed = Color(red: 0.133, green: 0.827, blue: 0.933)
/// Range: #a78bfa (violet)
static let roleRange = Color(red: 0.655, green: 0.545, blue: 0.980)
/// Utility: #4ade80 (green)
static let roleUtility = Color(red: 0.290, green: 0.871, blue: 0.502)
// MARK: Sell Button (Figma node 16:438)
/// #ff6467
static let sellRed = Color(red: 1.0, green: 0.393, blue: 0.416)
}
Dev Mode だと「#f97316 です」で止まる。MCP 経由だと「#f97316 → DesignTokens.rolePower として定義、コメントに Figma node 16:332 を記録、既存の themeAmber とは別トークンとして管理」まで一息で進む。
4. トークンを使って SwiftUI ビューを実装する
デザイントークンができたら、AI はそれを参照して SwiftUI のビューコードを書く。色のリテラルは使わず、必ず DesignTokens.rolePower のようにトークン経由。
この挙動は勝手にそうなるわけではなく、AGENTS.md というファイルでルールとして定義してある:
### WF-15 Figma Design Workflow
- Figma デザインがある画面の実装時は、MCP 経由でデザインデータを必ず取得する
- 取得したテーマカラー・テキスト・レイアウト値は推測で書かず Figma 実データを使用する
### DG-06 Design Token Centralization
- UI のカラー・フォント・スペーシング等のデザイントークンは画面横断で再利用可能にする
- 複数画面で同じ値を使う場合は専用ファイルに集約する
7画面に適用した結果
このフローでリデザインした画面の一覧:
| 画面 | Figma node | 主な変更 |
|---|---|---|
| TitleView | — | グリッドオーバーレイ、ラジアルグロー、浮遊ループアニメーション |
| TutorialView | — | 4ページ構成、テーマカラー別レイアウト |
| HUD 上部 | 13:97 |
Money / Wave / Lives の3セクション再構築 |
| HUD 下部 | — | タワー別テーマカラーの縦型カード |
| HUD アップグレード | 16:308 |
ボトムシート型パネル、ロール別6セグメントバー |
| ResultView | 16:503 |
敗北シールド、スター評価、統計カード |
| WaveAnnouncementView | 17:774 |
L字コーナーブラケット、段階的フェードイン/アウト |
最終的に DesignTokens.swift は 110 行、30 以上のトークンを持つファイルになった。全部に Figma の node ID コメントが付いているので、デザイン変更が入ったときに「どこを触ればいいか」がすぐわかる。
ルールがないと AI は最短距離を走る
MCP が使える状態でも、AI は必ずしも使ってくれるわけじゃない。
初期にあったのは、AI が MCP を呼ばずにスクリーンショットから色を推測して Color.cyan みたいな汎用色で済ませるパターン。見た目は似ていても、Figma の値とは違う。画面を並べると微妙にズレている。
WF-15 を AGENTS.md に足したのはこれがきっかけ。「Figma デザインがある画面では MCP を必ず使え」と書いたら、それ以降は毎回 get_design_context を呼ぶようになった。
DG-06 も同じ経緯で、各ビューファイルに色定数が散らばり始めたので「DesignTokens.swift に寄せろ」と定めた。
AI は与えられた道具を合理的に使う。でも「合理的」は「こちらの意図通り」とは限らない。ルールでその合理性の方向を揃えてやる、というのが AGENTS.md の役割だった。
よかったことと限界
よかったこと:
- Figma の値とコードの間に人間の転記作業が入らないので、ズレが構造的に起きない
- node ID のトレーサビリティで「この色は Figma のどのノードから来たか」がコードから辿れる
- 7画面すべてが同じトークンセットを参照するので、一貫性が勝手に維持される
- 1画面あたりのリデザインが会話1セッション(30分〜1時間)で終わる
限界:
-
アニメーションのイージングやタイミングは Figma に情報がないので、人間が指示する必要がある
- しれっと、これかなり大変です。色々考え、試行錯誤しました。本運用にするにはまだ洗練が足りませんが、別記事で紹介予定です。
- Figma 側のレイヤー構造が雑だと、取得データも雑になる。MCP は Figma の設計品質をそのまま反映する
- ノードが大きすぎるとレスポンスがメタデータだけに削減される場合がある。子ノードを個別に指定すれば対処できるが、手間は増える
振り返り
やってみて思ったのは、MCP 自体は「AI に目を与えるインフラ」でしかないということ。Dev Mode で人間が見ていた情報を AI が見られるようになった、それだけ。
価値が出たのは、その情報をプロジェクトの設計ルール(AGENTS.md)と組み合わせたとき。「Figma の値を読め」「トークンに集約しろ」「推測で書くな」——この3つのルールがあって初めて、Figma → DesignTokens.swift → View コードというパイプラインが安定した。
ツールだけ入れても変わらない、ルールと合わせて初めて回る。AI 駆動開発で繰り返し感じることだけど、今回もそれを確認する結果になった。