3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FigmaでAIを強化する | 第4章:バージョン管理AIの強化:リアルタイム連携

Posted at

はじめに

第3章では、Figmaのデザインデータを活用してUI分析エージェントを構築し、色のコントラストやフォントサイズの整合性を評価しました。これにより、AIがUIの品質を自動チェックし、改善提案を生成できるようになりました。今回は、Figmaのバージョン管理機能を強化するバージョン管理AIを構築します。このAIは、デザインの変更履歴を追跡し、変更点をリアルタイムで捕捉してコメントとして記録します。

この第4章では、FigmaのWebhook機能とMCPサーバーを統合し、ファイルの更新(例:新しいバージョンやノード変更)をリアルタイムで検知します。AIはこれを利用して、変更の概要をコメントしたり、重要な変更をチームに通知したりできます。コード例とステップごとのガイドで、バージョン管理AIの構築を体験しましょう。さあ、始めましょう!

バージョン管理AIとは?

バージョン管理AIは、Figmaファイルの変更履歴を監視し、デザインの進化を効率的に管理するエージェントです。MCPサーバーとFigmaのWebhookを組み合わせることで、以下のような機能を実現できます:

  • 変更検知:新しいバージョンやノードの変更をリアルタイムで捕捉。
  • コメント生成:変更内容を要約し、Figmaにコメントとして投稿。
  • 通知:重要な変更をチームに通知(例:Slackやメール)。

ユースケース

  • デザイン管理:変更履歴を自動記録し、デザインレビューの効率を向上。
  • チームコラボレーション:リモートチームに変更点を即座に共有。
  • 品質管理:意図しない変更(例:ブランドカラーからの逸脱)を検出。

開発環境の準備

第3章の環境を基に、以下の追加準備を行います:

  • Python 3.8以降mcpライブラリrequestsライブラリClaude Desktop:これまでと同じ。
  • webcolorsライブラリ:第3章から再利用。
  • ngrok:ローカルサーバーを公開し、Webhookを受信。
  • Figmaファイル:バージョン管理用のテストデータ。

インストールコマンド(必要に応じて):

pip install webcolors

Figmaのセットアップ

  1. テストファイルの準備
    • 第3章のFigmaファイル(例:MCP-Design)を使用。
    • 新しいバージョンを作成:Figmaの「Version History」パネルで「Save as new version」をクリックし、名前を付ける(例:v1.1)。
    • ノードを変更(例:ボタンの色を#007BFFから#FF5733に変更)。
  2. Webhookの設定
    • Figmaの「Team Settings」でWebhookを作成(有料プランが必要)。
    • イベント:FILE_VERSION_UPDATEを選択。
    • Webhook URL:後でngrokから取得(例:https://abc123.ngrok.io)。
    • Webhook Secretを記録(セキュリティ用)。
  3. ngrokの設定
    • ngrokをインストール(brew install ngrokまたは公式サイト)。
    • ローカルサーバーを公開:
      ngrok http 8108
      
    • 生成されたURLをFigmaのWebhook設定に登録。
  4. 環境変数
    第3章の.envファイルに以下を追加:
    FIGMA_TOKEN=your_figma_token
    FIGMA_FILE_ID=your_file_id
    FIGMA_WEBHOOK_SECRET=your_webhook_secret
    

コード例:バージョン管理用MCPサーバー

以下のMCPサーバーは、FigmaのWebhookを介してバージョン更新を捕捉し、変更内容を分析してコメントとして投稿します。

from mcp import MCPServer
import os
from dotenv import load_dotenv
import requests
from http.server import BaseHTTPRequestHandler, HTTPServer
import json
import hmac
import hashlib
import threading

class FigmaVersionServer(MCPServer):
    def __init__(self, host, port, figma_token, file_id, webhook_secret):
        super().__init__(host, port)
        self.figma_token = figma_token
        self.file_id = file_id
        self.webhook_secret = webhook_secret
        self.headers = {"X-Figma-Token": figma_token}
        self.latest_version = None
        self.register_resource("get_latest_version", self.get_latest_version)
        self.register_tool("add_comment", self.add_comment)
        self.start_webhook_server()

    def get_latest_version(self, params):
        try:
            if self.latest_version:
                version_id = self.latest_version["version_id"]
                url = f"https://api.figma.com/v1/files/{self.file_id}/versions/{version_id}"
                response = requests.get(url, headers=self.headers)
                response.raise_for_status()
                data = response.json()
                version_info = {
                    "version_id": data["id"],
                    "description": data.get("description", ""),
                    "created_at": data["created_at"],
                    "user": data["user"]["handle"]
                }
                return {"status": "success", "version_info": version_info}
            return {"status": "success", "version_info": None, "message": "バージョン更新なし"}
        except Exception as e:
            return {"status": "error", "message": str(e)}

    def add_comment(self, params):
        try:
            message = params.get("message", "")
            node_id = params.get("node_id", "")
            if not message:
                return {"status": "error", "message": "コメントが必要です"}
            
            url = f"https://api.figma.com/v1/files/{self.file_id}/comments"
            payload = {
                "message": message,
                "client_meta": {"node_id": node_id} if node_id else None
            }
            response = requests.post(url, headers=self.headers, json=payload)
            response.raise_for_status()
            comment = response.json()
            return {"status": "success", "comment_id": comment["id"]}
        except Exception as e:
            return {"status": "error", "message": str(e)}

    def start_webhook_server(self):
        class WebhookHandler(BaseHTTPRequestHandler):
            def do_POST(self):
                content_length = int(self.headers["Content-Length"])
                post_data = self.rfile.read(content_length)
                signature = self.headers.get("X-Figma-Signature", "")
                expected_signature = hmac.new(
                    self.server.parent.webhook_secret.encode(),
                    post_data,
                    hashlib.sha256
                ).hexdigest()

                if hmac.compare_digest(signature, expected_signature):
                    self.server.parent.latest_version = json.loads(post_data.decode("utf-8"))
                    self.send_response(200)
                    self.end_headers()
                    self.wfile.write(b"Webhook received")
                else:
                    self.send_response(403)
                    self.end_headers()
                    self.wfile.write(b"Invalid signature")

        server = HTTPServer(("localhost", 8109), WebhookHandler)
        server.parent = self
        threading.Thread(target=server.serve_forever, daemon=True).start()
        print("Webhookサーバーを起動中: http://localhost:8109")

if __name__ == "__main__":
    load_dotenv()
    server = FigmaVersionServer(
        host="localhost",
        port=8108,
        figma_token=os.getenv("FIGMA_TOKEN"),
        file_id=os.getenv("FIGMA_FILE_ID"),
        webhook_secret=os.getenv("FIGMA_WEBHOOK_SECRET")
    )
    print("FigmaバージョンMCPサーバーを起動中: http://localhost:8108")
    server.start()

コードの説明

  • get_latest_version:Webhookで捕捉した最新のバージョン更新情報を取得し、バージョンID、説明、作成日、ユーザーを返す。
  • add_comment:第3章から再利用し、変更内容をコメントとして投稿。
  • start_webhook_server:ローカルWebhookサーバーを起動し、Figmaからの更新を受信。
  • WebhookHandler:Webhookリクエストを処理。X-Figma-Signatureで署名を検証し、正当性を確認。

前提条件

  • Figmaファイルにバージョン履歴が存在。
  • FigmaのWebhookが設定済みで、ngrok URLが正しく登録。
  • .envファイルに正しいFIGMA_TOKENFIGMA_FILE_IDFIGMA_WEBHOOK_SECRETが設定済み。

サーバーのテスト

サーバーが正しく動作するか確認します:

  1. ngrok起動

    ngrok http 8109
    

    ngrok URL(例:https://abc123.ngrok.io)をFigmaのWebhook設定に登録。

  2. サーバー起動

    python figma_version_server.py
    

    コンソールに「FigmaバージョンMCPサーバーを起動中: http://localhost:8108」と「Webhookサーバーを起動中: http://localhost:8109」が表示。

  3. Webhookのテスト

    • FigmaのUIで新しいバージョンを保存(例:v1.2)。
    • サーバーのコンソールにWebhook受信ログが表示。
  4. 最新バージョン取得のテスト
    Pythonでリクエストを送信:

    import requests
    import json
    
    url = "http://localhost:8108"
    payload = {
        "jsonrpc": "2.0",
        "method": "get_latest_version",
        "params": {},
        "id": 1
    }
    response = requests.post(url, json=payload)
    print(json.dumps(response.json(), indent=2, ensure_ascii=False))
    

    期待されるレスポンス:

    {
      "jsonrpc": "2.0",
      "result": {
        "status": "success",
        "version_info": {
          "version_id": "789",
          "description": "v1.2: ボタンの色を変更",
          "created_at": "2025-04-20T10:00:00Z",
          "user": "DesignerA"
        }
      },
      "id": 1
    }
    
  5. コメント追加のテスト

    payload = {
        "jsonrpc": "2.0",
        "method": "add_comment",
        "params": {
            "message": "ボタンの色が変更されました(#FF5733)",
            "node_id": "1:2"
        },
        "id": 2
    }
    response = requests.post(url, json=payload)
    print(json.dumps(response.json(), indent=2, ensure_ascii=False))
    

Claude Desktopとの接続

サーバーをClaude Desktopに接続します:

  1. 設定ファイルの編集
    Claude Desktopの設定ファイル(例:claude_desktop_config.json)に以下を追加:

    {
      "mcp_servers": [
        {
          "name": "FigmaVersionServer",
          "url": "http://localhost:8108",
          "auth": "none"
        }
      ]
    }
    
  2. Claudeでテスト
    Claude Desktopを起動し、プロンプトを入力:

    最新のバージョン変更を教えてください。
    

    レスポンス例:

    最新のバージョン変更:
    - バージョン:v1.2
    - 説明:ボタンの色を変更
    - ユーザー:DesignerA
    - 日時:2025-04-20 10:00
    

    別のプロンプト:

    ボタンの色変更をコメントしてください。
    

    レスポンス例:

    ボタンに「ボタンの色が変更されました(#FF5733)」をコメントしました。
    

実装のコツと注意点

  • Webhookの安定性:ngrokの無料枠ではセッションが切れる場合がある。本番環境では固定URL(例:AWS Lambda)を使用。
  • レートリミティング:Figma APIの制限(通常30リクエスト/分)に注意。
  • セキュリティ:Webhook署名を必ず検証し、不正アクセスを防止。
  • テスト:テスト用ファイルを作成し、本番データに影響を与えない。
  • 拡張性:大量のバージョンを処理する場合、キャッシュやキュー(例:Redis)を検討。

試してみよう:挑戦課題

以下の機能を追加して、エージェントを強化してみてください:

  • 変更されたノードの詳細(例:色やサイズ)を分析し、コメントに含める。
  • バージョン間の差分を可視化する機能(例:変更されたノードをリスト)。
  • Webhookでキャプチャした変更をSlackに通知するツール。

まとめと次のステップ

この第4章では、FigmaのWebhookを活用してバージョン管理AIを構築しました。デザインの変更をリアルタイムで捕捉し、AIが変更内容をコメントや通知として記録できるようになりました。

次の第5章では、MCPサーバーの最適化とコミュニティへの貢献に焦点を当てます。サーバーのパフォーマンス向上、セキュリティ強化、そしてFigma用MCPサーバーをオープンソースとして共有する方法を学びます。コミュニティAIの未来に興味がある方は、ぜひお楽しみに!


役に立ったと思ったら、「いいね」や「ストック」をしていただけると嬉しいです!次の章でまたお会いしましょう!

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?