Figma MCP + Claude Code로 토스 인앱 디자인 구현하기: 디자이너 없이 코드만으로 완성하는 법

프론트엔드 개발자에게 디자인 구현은 늘 병목이었습니다. 디자이너가 Figma에 그려둔 화면을 보고, 색상 코드를 하나하나 확인하고, 간격을 픽셀 단위로 맞추고, "이거 좌우 패딩이 16인가요 20인가요?" 같은 슬랙 메시지를 주고받는 일 말이죠. 이런 과정에 쏟는 시간이 실제 개발 시간보다 길어질 때도 있습니다.
2025년 6월, Figma가 MCP(Model Context Protocol) 서버를 공식 출시했습니다. 그리고 2026년 2월 17일, Anthropic과 Figma가 파트너십을 발표하면서 Claude Code와 Figma 사이에 양방향 워크플로가 열렸습니다. Claude Code가 Figma 디자인을 직접 읽어서 React 코드를 생성하고, 반대로 코드로 구현한 UI를 Figma의 편집 가능한 프레임으로 되돌리는 기능도 지원합니다.
이 글에서는 앱인토스(Apps in Toss) 디자인을 Figma MCP와 Claude Code만으로 React/Next.js 프로젝트에 구현하는 과정을 다룹니다. 색상 코드를 복사 붙여넣기 하거나 레이아웃을 눈대중으로 맞추는 과정 없이, Claude Code가 Figma에서 디자인 정보를 직접 읽고 코드를 생성하는 워크플로입니다.
토스 디자인 시스템(TDS), 먼저 이해해야 할 것들
앱인토스 개발을 시작하기 전에 TDS(Toss Design System)를 이해해야 합니다. TDS는 UI 컴포넌트 라이브러리 그 이상이거든요. 토스 테크 블로그에서 Frontend UX Engineer가 직접 밝혔듯, TDS는 Flat API와 Compound API를 모두 제공하는 하이브리드 아키텍처를 채택했습니다. 단순한 경우에는 Props 하나로 끝나는 Flat API를, 복잡한 커스터마이징이 필요하면 Compound API를 쓸 수 있도록 설계한 것이죠.
앱인토스 개발자센터 공식 문서에 따르면, TDS가 제공하는 핵심 컴포넌트는 11개입니다. Badge, Border, Button, BottomCTA, Asset, ListRow, ListHeader, Navigation, Paragraph, Tab, Top. 이 컴포넌트에는 시각적 요소뿐 아니라 텍스트 길이 정책, 접근성(보이스오버 5가지 규칙과 큰 텍스트 모드), 블러 효과, 투명도, 터치 인터랙션의 속도와 가속도까지 세밀하게 정의되어 있습니다. 다크모드는 아직 지원하지 않아서 라이트 모드 기준으로만 디자인해야 합니다. 토스 테크 블로그에 따르면 TDS 적용 시 개발 생산성이 3~5배 향상된다고 하고요.
TDS의 Figma UI Kit은 앱인토스 개발자센터에서 공개적으로 다운로드할 수 있습니다. TDS_Mobile_for_Apps_in_Toss zip 파일을 받아서 Figma에 import하면 됩니다. Figma 커뮤니티에서 "Toss Design System"을 검색하면 팬 메이드 파일만 나오는데, 공식 UI Kit은 커뮤니티가 아니라 앱인토스 개발자센터의 디자인 준비 페이지에 있습니다. 설정 과정은 4단계입니다. 먼저 .fig 파일을 다운로드하고, Figma에서 Import 버튼으로 파일을 가져오고, Assets 탭의 Manage libraries에서 Publish 버튼을 눌러 라이브러리로 연결하고, 이후 Asset 탭에서 필요한 컴포넌트를 드래그해서 사용합니다. 한 가지 주의할 점은 자동 업데이트가 안 된다는 것입니다. 토스에서 새 버전의 UI Kit을 출시하면 파일을 다시 다운로드해야 하고요. 또한 UI Kit에 적용된 Semantic Color는 현재 버전의 코드와 일치하지 않을 수 있다고 공식 문서에서 명시하고 있습니다.
다만 라이선스 제약이 있습니다. 이 UI Kit은 앱인토스 서비스 개발 범위 내에서만 사용할 수 있고, 다른 프로젝트에 활용하거나 재배포하는 것은 금지됩니다. 모든 브랜드 자산의 권리는 Viva Republica Inc.에 귀속되고요.
토스 미니앱 브랜딩 가이드에도 주의할 규칙이 있습니다. 브랜드 컬러는 6자리 hex 코드로 지정하되 색 대비가 기준에 못 미치면 자동으로 보정하고요. 내비게이션 바는 앱인토스 전용 컴포넌트를 반드시 사용해야 합니다. 탭바는 필수가 아니라 선택 컴포넌트인데, 사용한다면 토스가 제공하는 플로팅 형태를 반드시 써야 합니다. 토스 메인 하단 탭과 형태가 겹치면 사용자가 혼동할 수 있기 때문이죠. 탭 개수는 최소 2개에서 최대 5개까지 허용됩니다. Claude Code가 올바른 코드를 생성하려면 이런 제약 사항을 알아야 합니다.
Figma UI Kit을 사용할 때 알아두면 좋은 실전 규칙도 있습니다. 앱인토스 디자인은 가로 375px을 기준으로 작업합니다. 컴포넌트 속성은 반드시 Figma의 오른쪽 패널에서만 조작해야 하고, 캔버스에서 직접 수정하면 안 됩니다. 그리고 대부분의 TDS 컴포넌트에는 기본 패딩이 포함되어 있어서 gap 없이 붙여서 사용하면 됩니다. 폰트는 각 컴포넌트에 이미 적용되어 있어서 별도 설치 없이 사용할 수 있고요.
Figma MCP란 무엇인가
Figma MCP 서버는 AI 코딩 도구가 Figma 디자인 파일의 정보를 직접 읽을 수 있게 해주는 다리입니다. MCP(Model Context Protocol)는 Anthropic이 제안한 표준 프로토콜로, AI 에이전트가 외부 도구와 데이터에 접근하는 방식을 통일했습니다. Figma가 이 프로토콜을 채택하면서 Claude Code, Cursor, VS Code Copilot, Windsurf 같은 AI 코딩 도구들이 Figma 파일을 직접 읽을 수 있게 되었고요.
실제로 중요한 건 Figma MCP 서버가 제공하는 도구입니다. Figma 공식 개발자 문서에 따르면 총 13개 도구가 있는데, 앱인토스 디자인 구현에 쓸 만한 도구는 다음과 같습니다.
get_design_context는 선택한 Figma 프레임의 구조를 React + Tailwind CSS 코드로 변환해서 반환합니다. 레이아웃 구조, 컴포넌트 계층, 스타일 정보가 모두 포함되고요. 다른 프레임워크로 변환하도록 지시할 수도 있습니다.
get_variable_defs는 Figma 파일에 정의된 디자인 변수를 추출합니다. 색상, 간격, 타이포그래피, 그림자 등의 디자인 토큰이 여기에 해당하죠. TDS의 컬러 팔레트와 간격 체계를 코드로 가져올 때 이 도구를 씁니다.
get_screenshot은 선택 영역의 스크린샷을 캡처합니다. 구조 데이터만으로는 놓칠 수 있는 시각적 뉘앙스, 예를 들어 그라데이션의 방향이나 요소 간의 시각적 균형을 AI가 참고할 수 있게 해줍니다.
get_code_connect_map은 Figma 디자인 컴포넌트와 실제 코드 컴포넌트 사이의 매핑 정보를 제공합니다. "이 Figma의 Button 컴포넌트는 코드에서 @toss/button을 사용하라"는 식의 연결 정보죠.
generate_figma_design은 2026년 2월에 추가된 도구로, 브라우저에서 실행 중인 UI를 캡처해서 Figma의 편집 가능한 프레임으로 변환합니다. localhost, 스테이징, 프로덕션 URL 모두 가능하고요.
이 도구들이 조합되면 "Figma에서 디자인 읽기 → 코드 생성 → 시각적 검증 → 필요시 Figma로 역변환"이라는 양방향 워크플로가 만들어집니다.
다음 그림은 Figma MCP의 5개 도구가 Figma와 Claude Code 사이에서 어떻게 연결되는지를 보여줍니다. 왼쪽의 Figma에서 디자인 정보가 5개 도구를 거쳐 오른쪽의 Claude Code로 전달되고, 반대 방향으로는 코드가 다시 Figma 프레임으로 변환됩니다.

디자인 컨텍스트 가져오기, 디자인 변수 추출, 스크린샷 캡처, Code Connect 매핑까지 4개 도구가 Figma → Claude Code 방향으로 디자인 정보를 전달하고, Figma 디자인 생성 도구가 반대 방향으로 코드를 Figma 프레임으로 되돌립니다.
Claude Code에 Figma MCP 설정하기
설정 방법은 세 가지입니다. 각각 장단점이 있으니 상황에 맞게 선택하면 됩니다.
방법 1: 공식 플러그인 설치 (권장)
가장 간단한 방법입니다. 터미널에서 한 줄이면 끝나거든요.
claude plugin install figma@claude-plugins-official
명령 한 줄이면 MCP 서버가 연결되면서 "Implement Design" 스킬도 함께 설치됩니다. 스킬은 Claude Code가 디자인을 코드로 변환할 때 따르는 워크플로를 정의한 것으로, 디자인 컨텍스트 가져오기, 스크린샷으로 시각적 참조 확보, 기존 코드베이스에 맞는 컴포넌트 생성이라는 단계적 절차가 포함되어 있습니다.
설치 후 OAuth 인증이 필요합니다.
claude /mcp
이 명령을 실행하면 브라우저에서 Figma 로그인 화면이 열리고, 접근 권한을 승인하면 됩니다.
방법 2: 원격 서버 직접 연결
플러그인 없이 MCP 서버만 연결하고 싶다면 이 방법을 씁니다.
claude mcp add --transport http figma-remote-mcp https://mcp.figma.com/mcp
원격 서버는 Figma 데스크톱 앱 없이도 동작합니다. 웹 브라우저에서 Figma를 쓰는 환경에서도 괜찮고요.
프로젝트 전체가 아닌 개인 설정으로 추가하려면 --scope user 플래그를 붙입니다.
claude mcp add --scope user --transport http figma https://mcp.figma.com/mcp
방법 3: 로컬 데스크톱 서버 연결
Figma 데스크톱 앱을 사용한다면 로컬 서버를 연결할 수 있습니다.
먼저 Figma 데스크톱 앱에서 Dev Mode MCP 서버를 활성화합니다. Settings에서 "Enable Dev Mode MCP Server" 옵션을 켜면 http://127.0.0.1:3845/sse에서 로컬 MCP 서버가 실행됩니다.
claude mcp add --transport sse figma-dev-mode-mcp-server http://127.0.0.1:3845/sse
로컬 서버의 장점은 Figma 데스크톱 앱에서 현재 선택한 프레임을 Claude Code가 바로 인식한다는 겁니다. "지금 내가 보고 있는 이 화면을 구현해줘"라는 식의 직관적인 워크플로가 가능하죠. 단점은 Figma 데스크톱 앱이 실행 중이어야만 동작한다는 것이고요.
어떤 방법을 선택할까
앱인토스 디자인처럼 특정 디자인 시스템을 일관되게 구현해야 하는 프로젝트에서는 방법 1(공식 플러그인)을 권장합니다. Implement Design 스킬이 포함되어 있어서 Claude Code가 디자인 시스템의 맥락을 이해한 채로 코드를 생성하거든요.
토스 Figma 파일을 MCP에 최적화하기
Figma MCP의 코드 생성 품질은 Figma 파일 구조에 크게 좌우됩니다. Figma 공식 문서에서 제시하는 파일 구조화 가이드를 앱인토스 디자인에 적용하면 다음과 같습니다.
레이어 이름을 의도가 드러나게 바꾸기
Figma에서 자동 생성되는 "Frame 1268"이나 "Group 5" 같은 이름은 Claude Code에게 아무 정보도 주지 않습니다. AI가 컴포넌트의 기능을 이해하려면 레이어 이름이 의도를 담아야 하거든요.
나쁜 예: Frame 1268 > Group 5 > Rectangle 12 > Text 3 좋은 예: TransactionList > TransactionItem > AmountBadge > AmountText
토스 TDS 컴포넌트를 사용하는 경우라면, TDS 컴포넌트 이름을 그대로 쓰는 게 좋습니다. ListRow, ListHeader, BottomCTA 같은 이름을 레이어에 반영하면 Claude Code가 "이건 TDS의 ListRow 컴포넌트구나"라고 인식할 수 있습니다.
슬래시 구분 네이밍 적용하기
Figma의 컴포넌트 변형(Variant)은 슬래시로 구분하는 게 좋습니다.
Button/Primary/Default Button/Primary/Pressed Button/Secondary/Default Tab/Active Tab/Inactive
이렇게 하면 Claude Code가 컴포넌트의 상태(State)와 변형(Variant)을 자동으로 구분해서 React의 Props로 변환할 수 있습니다.
Auto Layout 필수 적용
Figma의 Auto Layout은 CSS의 Flexbox와 직접 대응됩니다. Auto Layout이 적용되어 있으면 Claude Code가 flex, gap, padding 같은 CSS 속성을 정확하게 추출할 수 있고요. 반대로 절대 좌표(Absolute Position)로 배치된 요소는 반응형 코드 생성이 어렵습니다.
토스 TDS의 ListRow 같은 컴포넌트는 내부적으로 Flexbox 기반입니다. Figma에서도 Auto Layout으로 구성되어 있어야 Claude Code가 올바른 레이아웃 코드를 생성하고요.
Variables(디자인 변수) 활용하기
Figma의 Variables 기능으로 색상, 간격, 타이포그래피를 정의해두면 get_variable_defs 도구가 이를 추출해서 CSS 변수나 Tailwind 설정으로 변환할 수 있습니다. 토스의 브랜드 컬러, TDS의 색상 체계를 Variables로 관리하면 Claude Code가 하드코딩된 hex 값 대신 의미 있는 변수명을 쓴 코드를 생성하고요.
/* Claude Code가 Variables를 참조해서 생성한 코드 예시 */ :root { --toss-blue-500: #3182F6; --toss-gray-900: #191F28; --toss-gray-100: #F2F4F6; --spacing-sm: 8px; --spacing-md: 16px; --spacing-lg: 24px; }
실전 워크플로: Figma에서 React/Next.js 코드까지
이제 실제로 앱인토스 디자인을 Claude Code로 구현하는 과정을 단계별로 살펴보겠습니다.
1단계: 디자인 토큰 먼저 추출하기
프로젝트를 시작하면 개별 화면을 구현하기 전에 디자인 토큰부터 추출하는 게 좋습니다. Claude Code에 다음과 같이 요청합니다.
토스 TDS Figma 파일에서 디자인 변수를 모두 추출해서 tailwind.config.ts에 반영해줘. 색상, 간격, 타이포그래피, 그림자를 모두 포함해줘.
Claude Code는 get_variable_defs 도구로 Figma 파일의 디자인 변수를 읽고, Tailwind CSS 설정 파일로 변환합니다.
// tailwind.config.ts - Claude Code가 Figma Variables에서 추출한 설정 import type { Config } from 'tailwindcss'; const config: Config = { content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'], theme: { extend: { colors: { toss: { blue: { 50: '#E8F3FF', 100: '#C9E2FF', 500: '#3182F6', 600: '#1B64DA', }, gray: { 50: '#F9FAFB', 100: '#F2F4F6', 200: '#E5E8EB', 300: '#D1D6DB', 400: '#B0B8C1', 500: '#8B95A1', 600: '#6B7684', 700: '#4E5968', 800: '#333D4B', 900: '#191F28', }, }, }, spacing: { 'toss-xs': '4px', 'toss-sm': '8px', 'toss-md': '16px', 'toss-lg': '24px', 'toss-xl': '32px', }, fontSize: { 'toss-caption': ['12px', { lineHeight: '18px', fontWeight: '400' }], 'toss-body': ['14px', { lineHeight: '22px', fontWeight: '400' }], 'toss-subtitle': ['16px', { lineHeight: '24px', fontWeight: '600' }], 'toss-title': ['20px', { lineHeight: '28px', fontWeight: '700' }], 'toss-heading': ['24px', { lineHeight: '32px', fontWeight: '700' }], }, borderRadius: { 'toss-sm': '8px', 'toss-md': '12px', 'toss-lg': '16px', }, }, }, plugins: [], }; export default config;
이 단계에서 추출한 디자인 토큰이 이후 모든 컴포넌트 생성의 기초가 됩니다. Claude Code가 이후 화면을 구현할 때 bg-toss-blue-500이나 p-toss-md 같은 일관된 유틸리티 클래스를 쓰게 되거든요.
2단계: TDS 컴포넌트 규칙을 CLAUDE.md에 정의하기
Claude Code가 토스 디자인을 정확하게 구현하려면 TDS의 규칙을 알아야 합니다. 프로젝트 루트의 CLAUDE.md 파일에 디자인 시스템 규칙을 명시하면 되고요.
# 앱인토스 디자인 규칙 ## 기본 원칙 - 가로 375px 기준으로 작업 - 라이트 모드만 지원 (다크모드 미지원) - TDS 컴포넌트에 기본 패딩이 포함되어 있으므로 gap 없이 붙여서 사용 ## TDS 컴포넌트 사용 원칙 - Navigation 컴포넌트는 모든 화면 상단에 반드시 배치 - 탭바는 선택 사항이지만, 사용 시 토스 플로팅 형태 필수 (최소 2개, 최대 5개) - BottomCTA는 Single(버튼 1개) / Double(버튼 2개) 중 선택, Safe Area 대응 필수 - ListRow는 left + contents + right 3영역 구조 - verticalPadding: small(8px), medium(12px), large(16px), xlarge(24px) - horizontalPadding: small(20px), medium(24px) ## 브랜딩 규칙 - 브랜드 컬러: granite.config.ts의 brand.primaryColor에 6자리 hex 코드 지정 - 색 대비 미충족 시 자동 보정됨 - 로고: 600x600px 각진 정사각형 (모서리 둥근 형태 불가) ## 접근성 - 보이스오버 5가지 규칙 준수 - 큰 텍스트 모드 대응 - 터치 타겟 최소 44x44px ## 주의사항 - Semantic Color가 현재 코드 버전과 불일치할 수 있음 - 컴포넌트 속성은 Figma 오른쪽 패널에서만 조작 (캔버스 직접 수정 금지) ## 코드 컨벤션 - Tailwind CSS 사용, 인라인 스타일 금지 - 컴포넌트 파일은 src/components/tds/ 디렉토리에 배치 - 페이지는 src/app/ 디렉토리에 Next.js App Router 구조로 배치
이 파일이 있으면 Claude Code가 매번 "토스 스타일로 해줘"라고 말하지 않아도 자동으로 TDS 규칙을 따릅니다. Figma MCP에서 읽어온 디자인 정보와 CLAUDE.md의 규칙이 합쳐져서 토스 디자인에 맞는 코드가 나옵니다.
3단계: 화면 단위로 구현하기
디자인 토큰과 규칙이 준비되었으면, 이제 Figma의 각 화면을 구현합니다. 두 가지 접근 방식이 있습니다.
선택 방식: Figma 데스크톱 앱에서 구현할 프레임을 선택한 뒤 Claude Code에 요청합니다.
현재 Figma에서 선택한 화면을 React 컴포넌트로 구현해줘. TDS 컴포넌트를 최대한 활용하고, Tailwind CSS로 스타일링해줘.
이 방식은 로컬 데스크톱 서버(방법 3)를 사용할 때 편리합니다. Figma에서 프레임을 클릭하고 바로 Claude Code에 요청하면 되거든요.
링크 전달 방식: Figma URL을 직접 프롬프트에 붙여넣는 방식입니다.
이 Figma 디자인을 React 컴포넌트로 구현해줘: https://www.figma.com/design/파일ID/파일명?node-id=노드ID TDS ListRow, Button, BottomCTA 컴포넌트를 사용하고, Next.js App Router 구조에 맞게 만들어줘.
이 방식은 원격 서버(방법 1, 2)에서 씁니다. Figma 웹에서 프레임의 링크를 복사해서 붙여넣으면 됩니다.
Claude Code는 내부적으로 다음 순서로 동작합니다. 먼저 get_design_context로 프레임의 구조를 읽고, get_screenshot으로 시각적 참조를 확보한 뒤, get_variable_defs로 사용된 디자인 토큰을 확인하고, 이 정보를 종합해서 React 컴포넌트를 생성하죠.
한 가지 미리 밝힐 게 있습니다. 아래 코드 예제는 TDS Figma UI Kit의 컴포넌트 명세와 Figma MCP의 동작 방식을 기반으로 구성한 것입니다. 실제 Figma MCP 출력은 Figma 파일의 레이어 구조와 Variables 설정 상태에 따라 달라질 수 있고, 생성된 코드를 그대로 쓰기보다 프로젝트 컨벤션에 맞게 다듬는 과정이 필요합니다. 특히 UI Kit에 적용된 Semantic Color가 현재 코드 버전과 일치하지 않을 수 있다는 점도 감안해야 합니다.
앱인토스의 금융 상품 목록 화면을 구현한다면, Claude Code는 다음과 같은 구조의 코드를 생성합니다.
// src/components/tds/ListRow.tsx // TDS ListRow는 left, contents, right 3영역 구조입니다. // verticalPadding(small|medium|large|xlarge), horizontalPadding(small|medium)으로 여백을 제어합니다. interface ListRowProps { left?: React.ReactNode; contents: React.ReactNode; right?: React.ReactNode; verticalPadding?: 'small' | 'medium' | 'large' | 'xlarge'; horizontalPadding?: 'small' | 'medium'; border?: 'indented' | 'none'; withArrow?: boolean; withTouchEffect?: boolean; onClick?: () => void; } const verticalPaddingMap = { small: '8px', medium: '12px', large: '16px', xlarge: '24px' }; const horizontalPaddingMap = { small: '20px', medium: '24px' }; export function ListRow({ left, contents, right, verticalPadding = 'medium', horizontalPadding = 'medium', border = 'indented', withArrow = false, withTouchEffect = false, onClick, }: ListRowProps) { return ( <div role={onClick ? 'button' : undefined} onClick={onClick} className={`flex w-full items-center min-h-[44px] ${withTouchEffect ? 'active:bg-toss-gray-100 transition-colors cursor-pointer' : ''}`} style={{ padding: `${verticalPaddingMap[verticalPadding]} ${horizontalPaddingMap[horizontalPadding]}`, }} > {left && <div className="shrink-0 mr-toss-md">{left}</div>} <div className="flex-1 min-w-0">{contents}</div> {right && <div className="shrink-0 ml-toss-md">{right}</div>} {withArrow && <span className="ml-toss-sm text-toss-gray-400">›</span>} </div> ); }
// src/components/tds/BottomCTA.tsx // TDS BottomCTA는 Single(버튼 1개)과 Double(버튼 2개) 변형을 지원합니다. // FixedBottomCTA로 화면 하단에 고정할 수 있고, 버튼 위에 그라데이션 오버레이가 포함됩니다. interface BottomCTASingleProps { children: React.ReactNode; fixed?: boolean; } interface BottomCTADoubleProps { leftButton: React.ReactNode; rightButton: React.ReactNode; fixed?: boolean; } export function BottomCTA({ children, fixed = true }: BottomCTASingleProps) { return ( <div className={`${fixed ? 'fixed bottom-0' : ''} left-0 right-0 bg-white px-toss-lg pb-[calc(env(safe-area-inset-bottom)+16px)] pt-toss-sm`}> <div className="pointer-events-none absolute inset-x-0 -top-12 h-12 bg-gradient-to-t from-white to-transparent" /> {children} </div> ); } export function BottomCTADouble({ leftButton, rightButton, fixed = true }: BottomCTADoubleProps) { return ( <div className={`${fixed ? 'fixed bottom-0' : ''} left-0 right-0 bg-white px-toss-lg pb-[calc(env(safe-area-inset-bottom)+16px)] pt-toss-sm`}> <div className="flex gap-toss-sm"> {leftButton} {rightButton} </div> </div> ); }
// src/app/products/page.tsx import { ListRow } from '@/components/tds/ListRow'; import { BottomCTA } from '@/components/tds/BottomCTA'; import { Navigation } from '@/components/tds/Navigation'; export default function ProductListPage() { const products = [ { id: 1, title: '토스뱅크 통장', subtitle: '연 2.0%', amount: '1,234,567원' }, { id: 2, title: '토스 적금', subtitle: '연 3.5%', amount: '500,000원' }, { id: 3, title: '토스 주식', subtitle: '내 보유 주식', amount: '2,340,000원' }, ]; return ( <div className="flex min-h-screen flex-col bg-white"> <Navigation title="내 자산" /> <main className="flex-1 pb-[100px]"> <div className="px-toss-lg py-toss-md"> <h2 className="text-toss-heading text-toss-gray-900"> 총 자산 </h2> <p className="mt-toss-xs text-toss-title text-toss-blue-500"> 4,074,567원 </p> </div> <div className="mt-toss-md"> {products.map((product) => ( <ListRow key={product.id} left={ <div className="flex h-11 w-11 items-center justify-center rounded-toss-sm bg-toss-gray-100"> <span className="text-toss-body">💰</span> </div> } contents={ <div className="flex flex-col"> <span className="text-toss-body text-toss-gray-900">{product.title}</span> <span className="text-toss-caption text-toss-gray-500">{product.subtitle}</span> </div> } right={<span className="text-toss-subtitle text-toss-gray-900">{product.amount}</span>} verticalPadding="large" withTouchEffect /> ))} </div> </main> <BottomCTA label="자산 추가하기" onClick={() => {}} /> </div> ); }
코드에서 눈여겨볼 부분이 있습니다. ListRow 컴포넌트의 Props 구조가 TDS 공식 명세를 따르고 있다는 점입니다. TDS의 ListRow는 left, contents, right 세 영역으로 나뉘고, verticalPadding(small: 8px, medium: 12px, large: 16px, xlarge: 24px)과 horizontalPadding(small: 20px, medium: 24px)으로 여백을 제어합니다. border, withArrow, withTouchEffect 같은 속성도 TDS 명세 그대로이고요. Claude Code가 Figma UI Kit의 컴포넌트 구조를 읽어서 이런 Props 체계를 반영한 결과입니다.
BottomCTA도 TDS 명세에 따라 Single(버튼 1개)과 Double(버튼 2개) 변형을 구분했습니다. 버튼 위에 그라데이션 오버레이를 넣어서 스크롤 시 콘텐츠와 자연스럽게 분리되는 처리도 포함되어 있고요.
다만 이건 시각적 골격 수준의 구현입니다. TDS가 내부적으로 제공하는 보이스오버 5가지 규칙이나 큰 텍스트 모드 대응, shine()이나 blink() 같은 시각 효과는 Figma 디자인 파일에 담기지 않는 정보이므로 별도 구현이 필요합니다.
4단계: 시각적 검증과 반복
코드를 생성한 뒤에는 검증이 필요합니다. Claude Code에 다음과 같이 요청합니다.
방금 만든 ProductListPage를 localhost:3000에서 실행하고, Figma 원본 디자인과 비교해서 차이점을 알려줘.
Claude Code는 get_screenshot으로 Figma 원본의 스크린샷을 가져오고, 로컬에서 실행 중인 페이지와 비교합니다. 간격이 다르거나, 폰트 크기가 맞지 않거나, 색상이 미세하게 다른 부분을 찾아서 수정하죠.
사람의 개입 없이 이 반복 과정을 자동으로 수행한다는 게 핵심입니다. 디자이너에게 "이거 맞나요?" 하고 물어볼 필요 없이, Claude Code가 Figma 원본을 직접 참조해서 스스로 검증하고 수정합니다.
Code Connect: 디자인 컴포넌트와 코드 컴포넌트 연결하기
여기까지의 워크플로만으로도 꽤 정확한 코드를 생성할 수 있지만, 한 단계 더 정밀도를 높이는 방법이 있습니다. Figma의 Code Connect 기능이죠.
Code Connect는 Figma의 디자인 컴포넌트와 코드 저장소의 실제 컴포넌트를 명시적으로 연결합니다. React, Storybook, HTML, SwiftUI, Jetpack Compose를 지원하고요. MCP 서버와 연동하면 get_code_connect_map 도구가 이 매핑 정보를 Claude Code에 전달합니다.
예를 들어, Figma의 "Button/Primary" 컴포넌트가 코드의 @/components/tds/Button 컴포넌트와 연결되어 있으면, Claude Code는 새로운 화면을 구현할 때 버튼이 필요한 위치에 자동으로 기존 Button 컴포넌트를 import해서 씁니다. 새로 만들지 않습니다.
Code Connect 설정은 프로젝트에 .figma 디렉토리를 만들고 매핑 파일을 작성하는 방식으로 진행합니다.
// .figma/Button.figma.tsx import figma from '@figma/code-connect'; import { Button } from '@/components/tds/Button'; figma.connect(Button, 'Figma 컴포넌트 URL', { props: { label: figma.string('Label'), variant: figma.enum('Variant', { Primary: 'primary', Secondary: 'secondary', }), disabled: figma.boolean('Disabled'), }, example: (props) => ( <Button variant={props.variant} disabled={props.disabled} > {props.label} </Button> ), });
앱인토스 디자인에 Code Connect를 적용하면, TDS의 11개 핵심 컴포넌트 각각에 대해 Figma 컴포넌트와 React 컴포넌트의 매핑을 정의할 수 있습니다. 그러면 Claude Code가 Figma에서 TDS 컴포넌트를 인식했을 때 이미 만들어진 코드 컴포넌트를 가져다 쓰죠.
Code Connect는 Figma Organization 또는 Enterprise 플랜에서 사용할 수 있습니다. 최근에는 AI가 코드 스니펫을 자동 생성하고 컴포넌트 매핑을 제안하는 기능도 추가되었고요.
코드에서 Figma로: 양방향 워크플로
2026년 2월 Figma와 Anthropic의 파트너십으로 가능해진 기능이 하나 더 있습니다. Claude Code가 생성한 UI를 다시 Figma로 보내는 거죠.
generate_figma_design 도구는 브라우저에서 렌더링된 화면을 캡처해서 Figma의 편집 가능한 프레임으로 변환합니다. 단순 스크린샷이 아닙니다. 레이어, 텍스트, 버튼, 오토레이아웃이 모두 분리된 상태로 Figma에 들어갑니다.
다만 변환 정확도에는 한계가 있습니다. 단순한 Flexbox 기반 레이아웃은 오토레이아웃으로 잘 변환되지만, CSS Grid의 복잡한 트랙 설정이나 겹쳐진 요소(z-index), SVG 아이콘의 세밀한 패스 데이터는 변환 과정에서 누락되거나 단순화될 수 있거든요. 변환 결과를 받은 뒤 Figma에서 레이어 정리와 수동 조정이 필요한 경우가 있다는 점은 감안해야 합니다.
이 기능이 앱인토스 개발에서 유용한 시나리오가 있습니다.
디자인 파일에 없는 화면을 개발 중에 추가해야 할 때가 있죠. 에러 화면, 로딩 상태, 빈 상태 같은 것들입니다. Claude Code로 이런 화면을 먼저 코드로 만들고, generate_figma_design으로 Figma에 보내면 디자이너가 이를 기반으로 다듬을 수 있습니다.
ProductListPage의 빈 상태(상품이 없을 때) 화면을 만들고, localhost:3000/products에서 렌더링된 결과를 Figma에 보내줘.
Claude Code는 빈 상태 UI를 코드로 만들고, 로컬에서 렌더링한 뒤, generate_figma_design으로 Figma 파일에 편집 가능한 프레임을 추가합니다. 디자이너는 이 프레임을 받아서 텍스트를 수정하거나 일러스트레이션을 추가하면 되고요.
효과적인 프롬프트 전략
Figma MCP에서 결과물 품질을 좌우하는 건 프롬프트입니다. Figma 공식 GitHub 저장소(figma/mcp-server-guide)에서 제시하는 전략과 실전 경험을 종합하면 다음과 같습니다.
명시적 기술 스택 지정
이 Figma 디자인을 Next.js 15 App Router + Tailwind CSS로 구현해줘. 서버 컴포넌트를 기본으로 사용하고, 인터랙션이 필요한 부분만 'use client'를 선언해줘.
기술 스택을 명시하지 않으면 Claude Code가 기본값(React + Tailwind)으로 생성하는데, 프로젝트의 실제 설정과 맞지 않을 수 있거든요.
TDS 컴포넌트 우선 사용 지시
이 화면에서 ListRow, Button, Navigation은 src/components/tds/에 있는 기존 컴포넌트를 import해서 사용해줘. 새 컴포넌트를 만들지 말고 기존 것을 재사용해줘.
이 지시가 없으면 Claude Code가 Figma에서 읽은 디자인을 기반으로 새 컴포넌트를 처음부터 만들 수 있습니다. 기존 TDS 컴포넌트가 있다면 재사용하도록 명시해야 하고요.
디자인 시스템 문서를 마크다운으로 제공
Figma 공식 가이드에서 권장하는 방법입니다. 디자인 시스템의 규칙을 마크다운 파일로 정리해서 프로젝트에 포함하면, Claude Code가 CLAUDE.md와 함께 이 파일도 참조하거든요.
# docs/tds-guide.md ## 색상 사용 규칙 - 주요 액션: toss-blue-500 - 텍스트(기본): toss-gray-900 - 텍스트(보조): toss-gray-500 - 배경(기본): white - 배경(구분): toss-gray-50 - 비활성: toss-gray-200 (배경) + toss-gray-400 (텍스트) ## 간격 규칙 - 화면 좌우 패딩: toss-lg (24px) - 섹션 간 간격: toss-xl (32px) - 리스트 아이템 간: toss-md (16px) - 아이콘과 텍스트 간: toss-md (16px) ## 컴포넌트 사용 규칙 - 화면 상단: Navigation 컴포넌트 필수 - 하단 주요 액션: BottomCTA 컴포넌트 사용 - 목록: ListRow + ListHeader 조합 - 상태 표시: Badge 컴포넌트
한 번에 한 화면씩
Builder.io 블로그의 실전 리뷰에서 나온 주의사항입니다. Figma MCP는 복잡한 다중 프레임 흐름을 한 번에 처리하기 어렵습니다. "전체 앱을 변환해줘" 대신 "이 화면을 구현해줘"로 요청하는 편이 결과물 품질이 좋고요. 기존 앱에 새 컴포넌트를 하나씩 추가하는 방식이 Figma MCP에 가장 적합합니다.
현실적인 한계와 주의사항
Figma MCP + Claude Code 조합이 모든 걸 해결하지는 않습니다. Builder.io의 실전 리뷰와 Locofy의 비교 분석에서 나온 제한 사항을 정리합니다.
기존 코드 업데이트의 한계
Figma에서 디자인이 변경되었을 때, Claude Code가 기존 코드를 "업데이트"하는 건 아직 매끄럽지 않습니다. 디자인이 바뀌면 해당 컴포넌트를 다시 생성해야 하는 경우가 많고요. "버튼 색상만 바꿔줘" 같은 단순 변경은 되지만, "리스트의 레이아웃 구조를 완전히 바꿔줘" 같은 대규모 변경은 컴포넌트를 새로 만드는 편이 낫습니다.
TDS Figma UI Kit과 실제 코드의 간극
TDS Figma UI Kit은 공개적으로 다운로드할 수 있지만, Figma 파일과 실제 코드 사이에 간극이 존재합니다. 공식 문서에서도 UI Kit에 적용된 Semantic Color가 현재 코드 버전과 일치하지 않을 수 있다고 명시했고요. Claude Code가 Figma에서 TDS 디자인을 읽어서 시각적으로 동일한 React 컴포넌트를 만들 수는 있지만, TDS 내부의 접근성 처리, 인터랙션 세부사항까지 재현하기는 어렵습니다. 토스 테크 블로그에서 언급한 "보이스오버 5가지 규칙"이나 "터치 인터랙션의 속도와 가속도", ListRow의 shine()이나 blink() 같은 시각 효과는 Figma 디자인 파일에 담기지 않는 정보이거든요. 다크모드도 아직 미지원이라 라이트 모드 기준으로만 작업해야 하고요.
그래서 Claude Code가 생성한 코드는 시각적 골격으로 활용하고, TDS 고유의 인터랙션과 접근성 로직은 별도로 구현하거나 앱인토스 SDK를 통해 처리해야 합니다. 또한 UI Kit의 새 버전이 나오면 자동 업데이트가 되지 않으므로 수동으로 파일을 다시 다운로드해야 한다는 점도 운영상 고려가 필요합니다.
복잡한 인터랙션
모달, 바텀시트, 스와이프 제스처, 트랜지션 같은 복잡한 인터랙션은 Figma의 정적 디자인만으로 코드를 정확하게 생성하기 어렵습니다. Figma의 프로토타입 모드에서 정의한 인터랙션을 MCP가 읽지는 못하거든요. 인터랙션은 프롬프트로 별도 지시해야 합니다.
전체 앱 변환 vs 컴포넌트 단위
Locofy의 비교 분석에 따르면, 새 프로젝트 전체를 디자인에서 코드로 변환하는 작업은 Builder.io나 Locofy 같은 전용 도구가 더 적합합니다. Figma MCP + Claude Code는 기존 앱에 새 컴포넌트를 추가하거나, 특정 화면을 구현하는 데 강점이 있고요. 20개 화면짜리 앱을 처음부터 끝까지 한 번에 변환하려면 화면별로 나눠서 접근해야 합니다.
전체 워크플로 정리
앱인토스 디자인을 Figma MCP + Claude Code로 구현하는 전체 흐름을 정리하겠습니다. 다음 그림은 7단계 파이프라인을 한눈에 보여줍니다.

환경 준비부터 Figma로 공유까지, 각 단계가 이전 단계의 결과물을 입력으로 받아 순차적으로 진행됩니다. 각 단계를 하나씩 살펴보겠습니다.
먼저 환경을 준비합니다. Claude Code에 Figma MCP 플러그인을 설치하고, Next.js + Tailwind CSS 프로젝트를 생성합니다. 앱인토스 개발자센터에서 TDS Figma UI Kit을 다운로드하고, Figma에 import한 뒤 라이브러리로 Publish해두고요.
다음으로 디자인 토큰을 추출합니다. Claude Code에 Figma 파일의 디자인 변수를 읽어서 tailwind.config.ts에 반영하도록 요청하면, 색상, 간격, 타이포그래피, 그림자가 Tailwind 유틸리티 클래스로 변환됩니다.
프로젝트의 CLAUDE.md에 TDS 규칙을 정의합니다. 컴포넌트 사용 원칙, 브랜딩 규칙, 접근성 요구사항, 코드 컨벤션을 명시하면 되고요.
가능하다면 Code Connect를 설정합니다. TDS의 핵심 컴포넌트(ListRow, Button, BottomCTA 등)에 대해 Figma 컴포넌트와 코드 컴포넌트를 연결합니다.
이제 화면을 하나씩 구현합니다. Figma에서 프레임을 선택하거나 URL을 전달해서 Claude Code에 구현을 요청하면, get_design_context, get_screenshot, get_variable_defs를 조합해서 React 컴포넌트를 생성합니다.
생성된 코드를 로컬에서 실행하고, Figma 원본과 비교하며 차이를 수정합니다. 이 검증-수정 루프도 Claude Code가 자동으로 수행하고요.
필요하면 generate_figma_design으로 코드를 다시 Figma에 보내서 디자이너와 공유합니다.
마무리
토스의 디자인팀이 Figma 대신 Framer를 주요 도구로 도입한 배경이 흥미롭습니다. 토스피드 블로그에 따르면, 개발 컴포넌트를 디자인 도구에 직접 가져와서 디자이너와 개발자가 같은 언어로 소통하는 게 핵심 목표였고요. NPS 점수가 60점에서 85점으로 올랐다고 합니다.
"그렇다면 토스 내부가 Framer를 쓰는데 Figma MCP가 의미 있는가?"라는 질문이 나올 수 있습니다. 토스 내부 디자인팀의 도구 선택과 앱인토스 파트너의 상황은 다릅니다. 토스는 TDS Figma UI Kit을 개발자센터에서 공개 배포하고 있고, 앱인토스 개발자센터의 디자인 가이드도 Figma 기반이거든요. 앱인토스 개발자 입장에서는 Figma MCP가 여전히 가장 직접적인 연동 도구입니다.
Figma MCP + Claude Code가 지향하는 방향도 토스가 Framer를 도입한 이유와 같습니다. 디자이너가 그린 것을 개발자가 눈으로 보고 따라 만드는 게 아니라, AI가 디자인 파일의 구조를 직접 읽고 코드를 생성하는 거죠. 중간에 "이 간격이 16인가요 20인가요?" 같은 커뮤니케이션이 사라집니다.
물론 완벽하지는 않습니다. TDS의 접근성 로직이나 복잡한 인터랙션은 별도 구현이 필요하고, 전체 앱을 한 번에 변환하기보다는 컴포넌트 단위로 접근해야 하고요. 하지만 디자인 토큰 추출, 레이아웃 구조 변환, 시각적 검증이라는 반복 작업에서 사람의 개입을 줄인 것만으로도 생산성 향상은 체감할 수 있습니다.
직접 설정해보고 한 화면이라도 구현해보면 느낌이 올 겁니다. "아, 이 정도면 쓸 만하다"는 것과 "여기까지는 아직 내가 해야 한다"는 것의 경계를 직접 확인하는 게 가장 빠른 판단 방법입니다.
참고 자료
- Guide to the Figma MCP server - Figma Learn
- Figma MCP Server - Developer Docs
- Tools and Prompts - Figma MCP Server
- Remote Server Setup - Figma Developer Docs
- Desktop Server Setup - Figma Developer Docs
- Introducing our Dev Mode MCP server - Figma Blog
- From Claude Code to Figma - Figma Blog
- Figma Claude Code Skill: Implement Design
- Structure Your Figma File for Better Code
- Code Connect Integration - Figma Developer Docs
- Claude Code + Figma MCP Server - Builder.io Blog
- Figma MCP + Claude Code Tutorial - DEV Community
- 앱인토스 TDS 컴포넌트 문서
- 앱인토스 Figma UI Kit 다운로드 및 설정
- 앱인토스 Figma UI Kit 라이선스
- TDS ListRow 컴포넌트 상세
- TDS BottomCTA 컴포넌트 상세
- 앱인토스 해상도 가이드
- 미니앱 브랜딩 가이드 - 앱인토스
- 디자인 시스템 다시 생각해보기 - 토스 테크
- 토스 디자이너가 제품에만 집중할 수 있는 방법 - 토스 테크
- 토스 Framer 도입 사례 - 토스피드
- Design Systems and AI: MCP Servers - Figma Blog






댓글
댓글을 작성하려면 이 필요합니다.