FigmaMCP+Cursorで直感的にUIを作成してみる🎨
はじめに
初めまして!未経験でiOSエンジニアにジョブチェンジして約半年の五十嵐です🦑
元々はバナー制作や動画制作などクリエイティブ業務を主に担当していたため、それらの経験をエンジニアとして活かせないかと模索した結果、今回のFigmaMCP+Cursorで直感的にUIを作成してみる🎨に辿り着きました!
弊社ではAIを活用したプログラミングが活発に行われているため、iOS開発にはXcodeと一部Cursorを使用しています👀
CusorでSwiftプロジェクト開発を行う場合はSweetPadという拡張機能を使用します。
参考記事
こんな人におすすめです
- デザインからコーディングまでを一貫して行う
- ロジックよりも直感的にデザインを決めたい
- PhotoshopやIllustratorなどAdobeソフトの操作に親しみがある
- 0-1で新しいViewを作ることが多い
FigmaMCP+Cursorを使うメリット
従来はFigmaなどで作ったデザインを目視でコーディングするという流れが主流だったようですが、
FigmaMCPを連携することで、デザインからコードへの橋渡しの自動化が実現しました!
(Figmaのノード情報をそのままCursorに渡して、SwiftUIなどのコンポーネントを自動生成してくれる)
前提
- Figma(Dev Mode推奨)、個人アクセストークンの用意
- Node.js 18+ / npx
- MCP対応エディタ(今回はCursorを使用した例で説明)
セットアップ
- Figmaにログイン
- Webブラウザ(アプリ版でも可)で Figma.com にアクセスしてアカウントにログイン
- Figmaで個人アクセストークンを取得
- [設定]→[アカウント]から[Personal access tokens]を探し、新しいトークンを取得する - CursorのMCP設定
- ルートディレクトリに.cursor/mcp.jsonを作成し、APIキーを指定して連携を有効化
{
"mcpServers": {
"figma-mcp": {
"type": "command",
"command": "npx",
"args": ["-y", "figma-developer-mcp", "--", "--figma-api-key", "${FIGMA_API_KEY}", "--stdio"]
}
}
}
FigmaからUIを取り出す
今回はLINE風のトーク一覧画面を作ってみようと思います!✉️
FigmaでこんなUIを作成
Figma上ではセル部分のみを作成し、リスト表示はAIエージェントに任せます。
情報を渡したい範囲を選択し、「コピー/貼り付けオプション」→「選択範囲へのリンクをコピー」を選択するとFigmaデザインのURLを生成できます!
Figmaで取得したデザインのURLをCursorに渡し、実装指示を行う。
プロンプトはこんな感じ
たった1つのプロンプトでも、ある程度のクオリティのコードを生成してくれます!
実際に生成されたViewがこちら✏️
struct TestMessage: Identifiable, Hashable {
let id = UUID()
let userName: String
let lastMessage: String
let timeStamp: String
}
struct TestMessageListView: View {
private let messages: [TestMessage] = [
TestMessage(userName: "五十嵐ちゃん", lastMessage: "こんにちは!\n今何してる??", timeStamp: "08/19/00:00"),
TestMessage(userName: "あやか", lastMessage: "お疲れさま!今日配信ある?", timeStamp: "08/18/23:41"),
TestMessage(userName: "りさ", lastMessage: "昨日はありがとう〜また話そう!", timeStamp: "08/18/21:10"),
TestMessage(userName: "みき", lastMessage: "スタンプ送りました!", timeStamp: "08/18/20:05"),
TestMessage(userName: "はるか", lastMessage: "いま家?ちょっと通話できる?", timeStamp: "08/18/19:58"),
]
var body: some View {
ScrollView {
LazyVStack(spacing: 0) {
ForEach(messages) { message in
TestMessageRowView(message: message)
Divider()
}
}
}
}
}
private struct TestMessageRowView: View {
let message: TestMessage
var body: some View {
ZStack(alignment: .topTrailing) {
HStack(alignment: .center, spacing: 10) {
Circle()
.fill(Color.gray.opacity(0.2))
.frame(width: 70, height: 70)
.overlay(
Image(systemName: "person.fill")
.resizable()
.scaledToFit()
.foregroundStyle(.gray)
.padding(18)
)
VStack(alignment: .leading, spacing: 6) {
Text(message.userName)
.font(.system(size: 12, weight: .bold))
.foregroundStyle(.primary)
Text(message.lastMessage)
.font(.system(size: 12))
.foregroundStyle(.secondary)
.lineLimit(2)
.multilineTextAlignment(.leading)
}
Spacer(minLength: 0)
}
.padding(.leading, 21)
.padding(.trailing, 14)
Text(message.timeStamp)
.font(.system(size: 10, weight: .medium))
.foregroundStyle(.gray)
.padding(.top, 8)
.padding(.trailing, 7)
}
.frame(maxWidth: .infinity)
.frame(height: 92)
.contentShape(Rectangle())
.background(Color.clear)
}
}
今回はテストViewを作成したのでText情報など決め打ちで表示されていますが、すでに内部ロジックが実装済みの場合は、「◯◯ViewModelから情報を取得して!」などのプロンプトを追加することで、いい感じに情報を取得して表示してくれます💡
しかし、UIの出来上がりの質にはムラがあるので注意が必要です。
※生成されたUIのコード修正は、直接エディターで行うか、Figma側を修正するかは好みによりますが、個人的には微調整であればエディターで修正した方が早い気がします。
コンテキスト設計のコツ
- 一度にたくさんの情報を投げない
- ボタンやセルなどコンポーネントごとに情報を絞り込むことで精度が向上
- 事前にノード変換のルール(Cursor Rules)を設計しておく(Cursorにおけるコンポーネント生成のルール設定)
こちらの記事を参考にさせていただきました
まとめ
弊社の場合はデザイナーというポジションのスタッフがいないので、デザインからコーディングまでを一貫して行うことが多いですが、FigmaMCP+CursorでUIの実装が格段に早くなったと感じています🎉
(後から『やっぱりこうしたい』という修正も少なくなった)
まだまだ改善の余地はありますが、伸び代も大きいので今後の進化が楽しみです!

株式会社ジャンボの公式テックブログです! ジャンボはスマートフォンアプリを中心に、100%自社で開発を手掛ける企業です。 【積極採用について】 Jamboでは、チームを拡大し、さらなる成長を目指して積極的に新しいメンバーを積極的に採用しています。→ jambo-inc.io/
Discussion