Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MCP で繋ぐ Figma とデザインシステム〜LLM を使った UI 実装のリアル〜

MCP で繋ぐ Figma とデザインシステム〜LLM を使った UI 実装のリアル〜

2025年5月28日開催のレバテックLABさん主催の「開発チームでどう活かす? MCPでできたこと・できなかったこと」イベントの登壇資料です。

イベントURL:
https://levtechlab.connpass.com/event/354309/

MCP を活用してデザインシステムを用いた UI 実装をLLMで支援する取り組みと、期待するアウトプットを出しやすくするためにしている工夫などについて紹介しています。

Avatar for きむそん

きむそん

May 27, 2025
Tweet

More Decks by きむそん

Other Decks in Technology

Transcript

  1. MCP とは The Model Context Protocol (MCP) is an open

    protocol that enables seamless integration between LLM applications and external data sources and tools. (https://github.com/modelcontextprotocol より抜粋) LLMアプリケーションにデータソースやツールを統合するためのオープンプロトコル 「ツール」を標準化し、任意の LLM Client に組み込める 既存の LLM Client (Ex. Cursor, Roo Code, …etc) に 「必要な自律性を拡張」 → それぞれのチームが「LLM に実施させたいタスクに必要な自律性」を探し、組 み込んでいくフェーズ 4
  2. GLips/Figma-Context-MCP GLips/Figma-Context-MCP Give Cursor and other AI-powered coding tools access

    to your Figma files with this Model Context Protocol server ★ 7.1k+ TypeScript OSS で人気の Figma MCP 実装 弊社では利用せず、内製化した Figma 公式 MCP ではなく個人提供の MCP であること MCP はセキュリティ面を懸念する話題も多く、やや慎重 9
  3. Figma MCP のみではデザインシステムを活用できない Figma MCP で Figma を再現はできるようになった 一方、デザインシステムを使って UI

    実装をすることは難しい <button style="font-size: 20px"> 登録する</button> はできるが <Button textStyle="primary"> 登録</Button> はできない → ここを埋めるのがデザインシステムの MCP 10
  4. 提供するツール ツール 説明 list_components() 利用できるコンポーネントの一覧 get_multiple_component_info (names: string[]) コメント・Props定義(平文)・コンポーネント の

    theme get_multiple_component_info_detail (names: string[]) Props 型定義を展開した詳細な型情報と実装 get_design_tokens (targets: string[]) デザイントークン 12
  5. デザインシステム + Figma MCP のワークフロー Figma MCP デザインシステム MCP LLM

    エージェント ユーザー Figma MCP デザインシステム MCP LLM エージェント ユーザー UI 実装の依頼 list_components コンポーネント一覧 Figma デザイン情報の取得 デザイン情報(AST ) get_design_tokens( 必要なトークン種類) デザイントークン get_multiple_component_info( 使うコンポーネント) コメント・Props 定義など デザインシステムを活用したUI コードを提案 13
  6. どうやって実現する? 情報ソース Pros Cons ファイルシステ ム 実装が楽 Parseしていないので分解不 可 ランタイム

    - 取得できない 型情報 (Compiler API) 自由度が高い 実装が大変 / Compiler API 廃止後にどうするか問題 Storybook Storybook 側で効果的な粒度でメタデ ータが取り出されているので実装が楽 Storybook の内部 API に依 存 14
  7. 実装例: 関数コンポーネントの取り出し const componentsFile = project.getSourceFile(componentsFilePath) const exportedDeclarations = componentsFile.getExportedDeclarations()

    /** 取り出したコンポーネントのメタデータ */ const declarations = Array.from(exportedDeclarations.entries()).map( ([declarationName, declarations]) => { const [declaration, ...others] = declarations if ( !Node.isFunctionDeclaration(declaration) && // function !Node.isVariableDeclaration(declaration) // const Comp: FC ) { // 関数コンポーネント以外はスキップ return { declarationName, propType: undefined, } } // コメントや Props 型定義を抜き出す }) 16
  8. 実装例: コメントを抜き出す 関数の場合は getJsDocs で取るだけ 変数宣言の場合は、コメントになりうる箇所まで探索し、コメントがあれば取得 const sourceCode = declaration.getSourceFile().getFullText()

    const type = typeChecker.getTypeAtLocation(declaration) const comments = Node.isFunctionDeclaration(declaration) ? declaration.getJsDocs().map((doc) => doc.getInnerText()) : (declaration // value = ComponentWithAs .getParent() // const value = ComponentWithAs ?.getParent() // export const value = ComponentWithAs ?.getLeadingCommentRanges() ?.map((comment) => { return comment.getText() }) ?? []) 17
  9. 実装例: Props の型定義の抽出 const typeToDeclarationText = (type: Type): string |

    undefined => { // type alias const aliasSymbol = type.getAliasSymbol() const symbol = type.getSymbol() if (aliasSymbol !== undefined) { return aliasSymbol .getDeclarations() .at(0) ?.getChildren() // [export, type, <name>, =, <type declaration>] ?.find( (child) => Node.isTypeReference(child) /* OtherType */ || Node.isTypeQuery(child) /* typeof schema */ || Node.isTypeLiteral(child) /* { value: string } */ || Node.isIntersectionTypeNode(child) /* A & B */ || Node.isUnionTypeNode(child) /* A | B */ || Node.isMappedTypeNode(child) /* { [K in keyof T]: T[K] } */ || Node.isConditionalTypeNode(child) /* a extends b ? c : d */ ?.getText() } else if (symbol !== undefined) { // interface return symbol .getDeclarations() // declaration merge .map((declare) => declare.getText()) .join('\n\n') } 18
  10. MCP によるモデル性能の引き上げ MCP は外部 SaaS と繋ぐなど 「できることを増やす」 ことに注目されがちだが アクセスできる情報が同じでも、自律性に取得できる利点も大きい 必要な情報だけに絞って取得できる

    → セッションごとに必要な情報のみ取得 → 大量の情報で濃度を薄めず、情報を効果的に利用できる 分割して段階的に 取得できる 同じ情報でも「古い応答」と「新しい応答」では情報の濃淡がある →実施しているステップにとって重要な情報を新しい履歴における →指示追従性能や「意味のあるコンテキストサイズ」を引き上げ 24
  11. Figma のコンテキストサイズの壁 Figma AST の情報が非常に大きい 生データで10万行とかのオーダー Figma の Component は

    React と違いカプセル化されておらず上書きが可能 「Button」コンポーネントを利用したという情報だけでは不足するので、コンポー ネントの中身もすべて取得する必要がある → 削れる情報も少ない GLips/Figma-Context-MCP や弊社の実装では繰り返し出現するパターンを変数化す ることで情報量を1%以内に圧縮している。が、それでも1000行程度にはなってしま う 27
  12. 最小限の情報だけ取得するための MCP 設計 figma & list_components → get_multiple_component_info の流れで呼ばせる →

    必要最低限のコンポーネント情報のみ取得 get_multiple_component_info では「コメントと Props の実装」のみに留める ほとんどのパターンは使い方のコメントと Props のみあれば十分活用できる 一部のより詳細な情報が必要な場合のみ get_multiple_component_info_detail を 叩かせる 29
  13. プロンプトの分解 コンテキストサイズ以上に厳しいのが 「追従できる指示の量」 Figma to React は難易度が高い 「Figma の情報を読み取り、デザインシステムを活用した実装を考え、実装する」 という長いステップ

    利用するコンポーネントの実装を含む Figma のツリー構造と含まない React コン ポーネントの非対称さ プロンプトを分解し UI の実装タスクだけに集中させる! 型エラー・Lint の修正・テストの実行・汎用的なコーディング指示は含めない Cursor なら Custom Mode, VSCode Agent Mode なら promptFiles 31
  14. UI 実装のプロンプト(1/3) - Icon を利用するには chakra-ui ではなく デザインシステム の Icon

    コンポーネントを利用し、 `<Icon name="add" />` のように指定してください ## タスク デザインシステムを活用し、UI のコーディングを行ってください。 ## デザインシステムの活用 このプロジェクトでは Chakra UI をラップしたデザインシステムを構築しています。 提供されるコンポーネントを利用することで効果的に UI を構築することができます。 デザインシステム を利用する場合は以下のガイドラインに準拠してください: - デザインシステム は Chakra UI をベースに構築されており、基本的にすべてのコンポーネントでデザイントークンの Props を利用します。 - 例: sizes => `<Box size={...}>` - デザインシステム は `< デザインシステム>` から import して利用する - @chakra-ui の直接利用は禁止です。デザインシステム のコンポーネントを利用してください。 - **list_components に存在しないコンポーネントは利用できないことに留意してください。** - 例えば Figma では「type: TEXT 」という Node が使われていますが、** 「Text 」コンポーネントは存在しません。 デザインシステム では Paragraph コンポーネントあるいは Box 等の他のコンポーネントを利用** します。 34
  15. UI 実装のプロンプト(2/3) 3. get_multiple_component_info, get_design_tokens を用いたコンポーネント情報の取得 ## Figma に準拠した実装 UI

    実装時は Figma に準拠し、以下の情報をすべてそろえて正確な実装を行います。 1. get_figma_data ツールを利用して Figma のデザイン情報を取得 - depth は指定せずにすべての Node を取得します。 - サイズが大きすぎて取得できない場合は depth=5 を指定し、実装を進めながら分割して取得してください。 2. list_components を呼び出し、利用可能な デザインシステム のコンポーネント一覧を取得 - **list_components で取得したコンポーネント以外は利用できません** - get_multiple_component_info で利用したいコンポーネントをまとめて指定し コンポーネントの Props 型定義・説明・theme 情報を取得できます。 - get_design_tokens で利用するデザイントークンをまとめて指定し、スタイリングに利用するデザイントークンをまとめて取得します。 - Figma を正確に再現するため、以下のガイドラインに従います: - **styles の指定がある場合は同じデザイントークンを必ず明示的に指定すること** 。 - variables のスタイル情報を参照し、** 適切なデザイントークンに変換して指定** すること。 width 等の一部を除き px 指定は基本的に禁止です。 これらすべての情報を集めてから実装を行うことで、デザインシステムを用いた効率的な UI 実装ができます。 35
  16. UI 実装のプロンプト(3/3) 実装が完了後、get_multiple_component_info_detail を呼び出し、コンポーネントの利用方法を最終調整します。 React Component と Figma Component は対応関係が異なり、重複実装になってしまうことがよくあります。

    利用しているコンポーネントの実装を確認し、修正点を洗い出します。 例: Figma 通りに `<Step><Box> ステップN タイトル</Box></Step>` で実装した。 しかし、React Component では `<Step index={N}> タイトル</Step>` が正しい使い方だった。 Figma Component から React Component への変換は機械的には行えない難しい作業でありほとんどの場合ミスがあるので 最終確認は非常に重要なステップです。丁寧に確認し、修正を行います。 ## 品質条件 **Figma を正確な再現は最も重要な要件です。 上記のルールを絶対に守り、不足なく get_figma_data で UI 情報を取得し、正確な実装を行ってください。** ## 実装後の最終調整 36
  17. まとめ: MCP でできたこと Figma MCP とデザインシステム MCPで 「デザインシステムを活用して Figma の

    UI を組む」 ができる! プロンプトや MCP ツール設計で限界を引き上げることで活用幅が広げよう MCP だけでは「ワークフロー」が揺れて成果物が揺らぐのでプロンプト大事 ありがちなミスもプロンプトで潰しておく MCP の 「必要な情報に絞って取得」・「取得する情報に濃淡をつけられる」 側面 を活用して性能を引き上げる 包括的なプロンプトではなく、タスクごとにプロンプトを使い分けよう 37
  18. 今後の展望 「デザイン」と「成果物である React コード」の中間データとしての Figma はコスパ が悪いと感じている 複雑な Figma を翻訳することが、対応できる複雑性の限界を下げている

    Figma To React のクオリティ向上に LLM を活かすより、デザイナーがデザイン自体 を React Code で組めるような世界を目指すほうが筋が良いのではないか Figma MCP を使わない デザインシステム MCPとコーディングエージェントを使って、デザイナーが自然 言語で Storybook にデザインをアウトプットする世界 既存のフローを LLM で支援する現実的な方向性と、LLM に優しいワークフローに対 応していく両輪で Try していきたい 38