はじめに
第2章では、Figmaのコメントを読み書きするMCPサーバーを構築し、フィードバックを自動化するエージェントを実現しました。これにより、AIがデザインコメントを処理・生成できるようになり、デザインプロセスの効率が向上しました。今回は、この基盤を活用して、Figmaのデザインデータを分析し、UIの品質や一貫性に関するインサイトを生成するUI分析エージェントを構築します。
この第3章では、Figmaのファイルからノードデータ(例:色、フォント、レイアウト)を抽出し、アクセシビリティやデザインの整合性を評価するMCPサーバーを実装します。たとえば、AIが色のコントラスト不足を検出したり、フォントサイズのばらつきを指摘したりできます。コード例とステップごとのガイドで、UI分析AIの構築を体験しましょう。さあ、始めましょう!
UI分析エージェントとは?
UI分析エージェントは、Figmaのデザインデータを解析し、UIの品質やユーザー体験に関するインサイトを提供するAIです。MCPサーバーを介して、以下のような機能を実現できます:
- アクセシビリティチェック:色のコントラスト比やフォントサイズを評価。
- 一貫性分析:デザイン全体での色やフォントのばらつきを検出。
- 提案生成:分析結果に基づいて改善案をコメントとして投稿。
ユースケース
- デザインレビュー:AIがアクセシビリティの問題を自動検出し、修正案を提案。
- 品質管理:デザインシステムの一貫性を維持し、ブランドガイドラインを遵守。
- チームコラボレーション:分析結果をチームと共有し、フィードバックを効率化。
開発環境の準備
第2章の環境を基に、以下の追加準備を行います:
- Python 3.8以降、mcpライブラリ、requestsライブラリ、Claude Desktop:これまでと同じ。
- webcolorsライブラリ:色の分析用。
- Figmaファイル:分析用のデザインデータを準備。
インストールコマンド:
pip install webcolors
Figmaファイルの準備
-
テストデザインの作成:
- 第2章のFigmaファイル(例:
MCP-Design
)を使用。 - 以下の要素を含むデザインを追加:
- ボタン(背景色:青
#007BFF
、テキスト色:白#FFFFFF
) - テキスト(フォントサイズ:16px、色:黒
#000000
) - 別のテキスト(フォントサイズ:14px、色:グレー
#666666
)
- ボタン(背景色:青
- コメントでノードID(例:
1:2
)を確認し、記録。
- 第2章のFigmaファイル(例:
-
APIトークンの確認:
- 第2章のPersonal Access Tokenを再利用(ファイルデータとコメントの読み書きに必要)。
-
環境変数:
第2章の.env
ファイル(FIGMA_TOKEN
、FIGMA_FILE_ID
)を再利用。
コード例:UI分析用MCPサーバー
以下のMCPサーバーは、Figmaのノードデータから色やフォント情報を抽出し、アクセシビリティと一貫性を分析します。さらに、分析結果をコメントとして投稿します。
from mcp import MCPServer
import os
from dotenv import load_dotenv
import requests
import webcolors
from math import sqrt
class FigmaAnalysisServer(MCPServer):
def __init__(self, host, port, figma_token, file_id):
super().__init__(host, port)
self.figma_token = figma_token
self.file_id = file_id
self.headers = {"X-Figma-Token": figma_token}
self.register_resource("analyze_ui", self.analyze_ui)
self.register_tool("add_comment", self.add_comment)
def calculate_contrast(self, color1, color2):
# 簡易的なコントラスト比計算(WCAG基準の近似)
def luminance(rgb):
r, g, b = [c / 255.0 for c in rgb]
for c in (r, g, b):
c = c / 12.92 if c <= 0.03928 else ((c + 0.055) / 1.055) ** 2.4
return 0.2126 * r + 0.7152 * g + 0.0722 * b
rgb1 = webcolors.hex_to_rgb(color1)
rgb2 = webcolors.hex_to_rgb(color2)
l1, l2 = luminance(rgb1), luminance(rgb2)
if l1 < l2:
l1, l2 = l2, l1
return (l1 + 0.05) / (l2 + 0.05)
def analyze_ui(self, params):
try:
url = f"https://api.figma.com/v1/files/{self.file_id}"
response = requests.get(url, headers=self.headers)
response.raise_for_status()
data = response.json()
nodes = data.get("document", {}).get("children", [])
issues = []
colors = []
font_sizes = []
for node in nodes:
if "fills" in node and node["fills"]:
color = node["fills"][0].get("color", {})
if color:
hex_color = webcolors.rgb_to_hex((
int(color["r"] * 255),
int(color["g"] * 255),
int(color["b"] * 255)
))
colors.append(hex_color)
if "style" in node and "fontSize" in node["style"]:
font_sizes.append(node["style"]["fontSize"])
# コントラストチェック(例:背景とテキスト)
if "fills" in node and "characters" in node:
bg_color = node["fills"][0].get("color", {})
text_color = node.get("style", {}).get("fill", {}).get("color", {})
if bg_color and text_color:
bg_hex = webcolors.rgb_to_hex((
int(bg_color["r"] * 255),
int(bg_color["g"] * 255),
int(bg_color["b"] * 255)
))
text_hex = webcolors.rgb_to_hex((
int(text_color["r"] * 255),
int(text_color["g"] * 255),
int(text_color["b"] * 255)
))
contrast = self.calculate_contrast(bg_hex, text_hex)
if contrast < 4.5: # WCAG AA基準
issues.append({
"node_id": node["id"],
"issue": f"コントラスト比が低すぎます({contrast:.2f})。WCAG基準の4.5以上が必要です。"
})
# フォントサイズの一貫性チェック
if font_sizes:
avg_font_size = sum(font_sizes) / len(font_sizes)
for size in font_sizes:
if abs(size - avg_font_size) > 2:
issues.append({
"node_id": "",
"issue": f"フォントサイズ({size}px)が平均({avg_font_size:.1f}px)から大きく乖離しています。"
})
return {"status": "success", "issues": issues}
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)}
if __name__ == "__main__":
load_dotenv()
server = FigmaAnalysisServer(
host="localhost",
port=8107,
figma_token=os.getenv("FIGMA_TOKEN"),
file_id=os.getenv("FIGMA_FILE_ID")
)
print("Figma分析MCPサーバーを起動中: http://localhost:8107")
server.start()
コードの説明
- analyze_ui:Figmaファイルのノードを解析し、色やフォントサイズを抽出。コントラスト比(WCAG基準)とフォントサイズの一貫性を評価。
- calculate_contrast:簡易的なコントラスト比を計算し、WCAG AA基準(4.5以上)をチェック。
- add_comment:第2章から再利用し、分析結果をコメントとして投稿可能。
- register_resource/tool:UI分析をリソース、コメント追加をツールとして登録。
前提条件
- Figmaファイルに色やフォントを含むノードが存在。
-
.env
ファイルに正しいFIGMA_TOKEN
とFIGMA_FILE_ID
が設定済み。 - APIトークンにファイルデータとコメントの読み書き権限がある。
サーバーのテスト
サーバーが正しく動作するか確認します:
-
サーバー起動:
python figma_analysis_server.py
コンソールに「Figma分析MCPサーバーを起動中: http://localhost:8107」と表示。
-
UI分析のテスト:
Pythonでリクエストを送信:import requests import json url = "http://localhost:8107" payload = { "jsonrpc": "2.0", "method": "analyze_ui", "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", "issues": [ { "node_id": "1:2", "issue": "コントラスト比が低すぎます(3.50)。WCAG基準の4.5以上が必要です。" }, { "node_id": "", "issue": "フォントサイズ(14px)が平均(15px)から大きく乖離しています。" } ] }, "id": 1 }
-
コメント追加のテスト:
payload = { "jsonrpc": "2.0", "method": "add_comment", "params": { "message": "コントラスト比を改善してください", "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に接続します:
-
設定ファイルの編集:
Claude Desktopの設定ファイル(例:claude_desktop_config.json
)に以下を追加:{ "mcp_servers": [ { "name": "FigmaAnalysisServer", "url": "http://localhost:8107", "auth": "none" } ] }
-
Claudeでテスト:
Claude Desktopを起動し、プロンプトを入力:デザインのUI問題を教えてください。
レスポンス例:
デザインのUI問題: - ボタン(ノード1:2):コントラスト比が3.50で、WCAG基準の4.5未満です。 - フォントサイズ:14pxが平均15pxから乖離しています。
別のプロンプト:
ボタンのコントラスト問題をコメントしてください。
レスポンス例:
ボタンに「コントラスト比を改善してください」をコメントしました。
実装のコツと注意点
- パフォーマンス:大量のノードを処理する場合、Figma APIのリクエストを最適化(例:特定ノードのみ取得)。
- エラーハンドリング:ノードに色やフォント情報がない場合に対応。
- レートリミティング:Figma APIの制限(通常30リクエスト/分)に注意。
- セキュリティ:本番環境では、HTTPSとトークン認証を導入。
- 拡張性:複雑な分析の場合、デザインシステムのルールを事前定義。
試してみよう:挑戦課題
以下の機能を追加して、エージェントを強化してみてください:
- 色の多様性を分析し、ブランドカラーからの逸脱を検出。
- レイアウトの整列(例:マージンやパディング)をチェック。
- 分析結果を新しいFigmaファイルにエクスポートするツール。
まとめと次のステップ
この第3章では、Figmaのデザインデータを活用してUI分析エージェントを構築しました。色のコントラストやフォントサイズの分析により、AIがUIの品質を評価し、改善提案を生成できるようになりました。
次の第4章では、Figmaのバージョン管理を強化するバージョン管理AIを構築します。たとえば、AIがデザインの変更履歴を追跡し、変更点をコメントとして記録します。バージョン管理AIに興味がある方は、ぜひお楽しみに!
役に立ったと思ったら、「いいね」や「ストック」をしていただけると嬉しいです!次の章でまたお会いしましょう!