본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 27. 20:04

AI가 당신의 Figma를 읽을 수 있습니다. Figwright를 통해 그곳에서 직접 구축할 수도 있습니다.

요약

Figwright는 AI 에이전트가 Figma 디자인을 읽고 쓸 수 있게 해주는 오픈 소스 MCP 서버이자 플러그인입니다. 기존 AI 도구의 한계인 디자인-코드 간 불일치를 해결하며, 프로젝트의 컴포넌트와 토큰을 인식하여 정확한 코드를 생성하도록 돕습니다.

핵심 포인트

  • Figma 디자인을 읽고 코드로 변환하거나 캔버스에 다시 쓰는 양방향 기능 제공
  • MCP(Model Context Protocol)를 지원하여 Claude Code, Cursor 등과 연동 가능
  • 프로젝트의 기존 컴포넌트와 Tailwind 토큰 등을 인식하는 그라운딩 기능 지원
  • 유료 Dev Mode 없이도 사용할 수 있는 무료 오픈 소스 도구

요약 (TL;DR)Figwright는 모든 AI 에이전트에게 Figma로 향하는 **양방향 통로 (two-way door)**를 제공하는 무료 오픈 소스 MCP 서버이자 Figma 플러그인입니다. 디자인을 읽어 들여 사용자의 컴포넌트(components)와 토큰(tokens)을 재사용하는 코드로 변환하며, 프레임(frames), 텍스트(text), 오토 레이아웃(auto-layout), 스타일(styles), 변수(variables), 전체 화면(whole screens) 등을 캔버스에 다시 작성할 수도 있습니다. 92개의 도구. 모든 MCP 클라이언트 지원. Dev Mode 유료 시트 불필요.
npx -y @figwright/mcp@latest

여기는 제가 원치 않을 만큼 자주 겪어온 화요일의 모습입니다.

오후 3시입니다. 디자이너가 Slack에 Figma 링크를 던집니다 — "이 화면 좀 만들어 줄 수 있어요? 금방 될 거예요 🙏" — 그리고 저는 "금방 될 거예요"라는 말을 믿는 실수를 저지릅니다. 저는 AI 에이전트에게 해당 프레임(frame)을 가리키며 코드를 요청합니다. 30초 후, 저는 #2563EB가 여섯 군데에 하드코딩된, 사실상 <div style={{ ... }}>의 벽에 불과한 180줄짜리 컴포넌트를 멍하니 바라보고 있습니다. 그 파란색은 우리 설정에서 말 그대로 bg-primary인데, AI는 그것을 알 방법이 전혀 없습니다. 제가 지난달에 배포한 Button은요? 처음부터 다시 만들어졌습니다. 제 Tailwind 토큰은요? 들어본 적도 없나 봅니다. 그래서 저는 다음 한 시간 동안 2015년으로 돌아간 것처럼 헥스 코드(hex codes)를 찾아 바꾸고, AI가 만든 일반적인 마크업(markup)을 우리가 이미 가지고 있는 컴포넌트로 교체하는 데 시간을 보냅니다. 이 도구는 저에게 숙제를 던져줌으로써 "시간을 아껴준" 셈입니다.

그러고 나서 디자이너는 평소처럼 가볍게 후속 요청을 합니다: "아, 제가 간격을 조정할 수 있게 Figma 파일에 가격 섹션도 좀 넣어줄 수 있어요?" 그러면 제 AI는 그냥... 어깨만 으쓱합니다. 하루 종일 캔버스를 설명해 줄 수는 있겠지만, 프레임 하나를 다시 캔버스에 올려놓지는 못합니다.

그리고 읽기 기능의 절반을 담당하는 공식 Figma Dev Mode MCP는요? 유료 Dev Mode 시트를 요구합니다. 사이드 프로젝트를 하는 입장에서는 거기서 조용히 대화가 끝납니다.

저는 그 화요일의 모든 과정에 지쳤고, 그래서 Figwright를 만들었습니다. Claude Code, Cursor 등 MCP를 지원하는 어떤 AI 에이전트에게든 Figma로 향하는 **양방향 통로 (two-way door)**를 제공하는 무료 오픈 소스 MCP 서버(및 Figma 플러그인)입니다. 이것이 정확히 그 화요일의 문제를 어떻게 해결하는지 설명해 드리겠습니다.

Playwright가 브라우저를 제어하듯, Figwright는 Figma를 제어합니다.

문제 1: "AI가 제가 이미 만들어 놓은 것들을 모두 무시합니다"

일반적인 도구들이 실패하는 이유는 한 가지입니다. 모델에게 디자인의 _평면화된 이미지 (flattened picture)_만을 전달하고, 사용자의 저장소 (repo)에 대한 지식은 전혀 제공하지 않기 때문입니다. 당연히 AI는 버튼을 새로 만들어냅니다. 당신에게 이미 버튼이 있다는 사실을 모르기 때문입니다.

Figwright는 그 반대로 동작합니다. 코드를 한 줄 쓰기 전에, 제가 **그라운딩 (grounding)**이라고 부르는 작업을 수행합니다. 즉, 실제 스택 (React / Vue / Svelte / Next… + Tailwind / CSS / CSS-in-JS)을 읽어 들인 다음, 프로젝트의 핵심인 세 가지 도구를 통해 Figma 디자인을 코드베이스 (codebase)와 연결합니다:

  • component_map — 디자인에서 카드를 발견하면, 당신이 이미 <Card>를 배포하고 있다는 것을 인지합니다.
  • token_map — 브랜드 블루 색상을 발견하면, #2563EB가 아닌 bg-primary를 출력합니다.
  • icon_map — 아이콘을 발견하면, 형태를 새로 그리는 대신 저장소에 있는 실제 SVG를 재사용합니다 (올바른 currentColor / fixed-fill 규약을 준수하며).

이 모든 과정은 get_design_context를 기반으로 이루어지며, 이는 모델에게 추측해야 하는 스크린샷 대신 레이아웃, 타이포그래피 (typography), 변수 (variables), 컴포넌트 (components) 등 충실하고 중복이 제거된 (de-duplicated) 컨텍스트를 제공합니다.

따라서 예전에는 <div angle 지옥을 뱉어냈던 동일한 요청이:

// ❌ 일반적인 도구: 하드코딩된 값, 디자인 시스템의 흔적을 찾을 수 없음
<div style={{ display: 'flex', padding: 16, borderRadius: 8, background: '#2563EB' }}>
  <span style={{ color: '#fff', fontSize: 14, fontWeight: 600 }}>Get started</span
...

…이제는 실제로 머지 (merge)할 수 있는 코드로 돌아옵니다:

// ✅ Figwright: 이미 보유한 컴포넌트와 토큰을 재사용
<Button variant="primary" size="md">
  Get started
...

오후 내내 코드를 정리할 필요가 없습니다. 이것이 핵심입니다: 디자인을 평면화하는 컴파일러가 되지 마세요. 정직한 컨텍스트를 드러내어 모델이 자신이 속한 저장소에 적합한 코드를 작성하게 만드세요.

문제 2: "보기만 할 뿐, 만질 수는 없습니다"

이것은 다른 누구도 하지 않는 절반의 영역입니다. 디자이너가 저에게 특정 섹션을 Figma 안으로 밀어 넣어달라고 요청할 때, 저는 이제 그냥… 그렇게 합니다:

이 명세(spec)를 바탕으로 Figma에 3단계 가격 섹션을 구축해줘.

Figwright는 캔버스에 직접 내용을 작성하며, 단순히 평면적인 사각형을 배치하는 대신 파일의 디자인 시스템 (design system)을 재사용합니다. 실제 오토 레이아웃 (auto-layout), 사용자의 텍스트 및 컬러 스타일, 적절한 노드 (node)에 연결된 (bound) 변수 (variables), 그리고 인스턴스화된 컴포넌트 (components)가 적용됩니다. 내부적으로는 단 하나의 프롬프트가 다음과 같은 실제 도구 호출 (tool calls)로 확장됩니다:

create_frame → set_auto_layout → create_text → apply_style_to_node
→ bind_variable_to_node → create_instance → resize_nodes → ...

프롬프트나 코드 조각을 통해 전체 화면의 구조를 잡거나 (scaffold), 컴포넌트 하나를 수정하거나, 디자인 시스템 에셋 (design-system assets)을 생성할 수 있습니다. React 컴포넌트를 Figma 컴포넌트로 변환하거나, 캔버스 위에 랜딩 페이지를 재현할 수도 있습니다. 이 대칭성이 바로 마법의 핵심입니다: 당신의 디자인을 구현하는 바로 그 에이전트 (agent)가 디자인을 직접 구축할 수도 있다는 점입니다.

문제 3: "내 파일을 읽기 위해 왜 유료 시트 (seat) 비용을 지불해야 하나요?"

Figwright는 **플러그인 (plugin)**을 통해 Figma와 통신하므로, 무료 티어(free tier)만으로도 충분합니다. 즉, Dev Mode 시트나 유료 티어가 필요 없습니다. 또한 특정 에디터에 종속되지 않습니다. MCP 기능이 있는 클라이언트라면 무엇이든 동일한 방식으로 작동합니다.

공식 옵션과의 솔직한 비교는 다음과 같습니다:

공식 Dev Mode MCPFigwright
디자인 읽기 → 코드 변환
...

공식 Dev Mode MCP는 진정으로 훌륭하지만, 읽기 전용 (read-only)이며 유료 시트가 필요합니다. 반면 Figwright는 **다시 써넣기 (writes back)**가 가능하며, 사용자의 코드베이스를 재사용하고, 무료로 실행됩니다.

실제의 복잡하고 지저분한 파일들을 통해서만 배울 수 있는 것들

데모는 쉽습니다. 2,000개의 레이어가 있는 클라이언트 파일을 대상으로 도구를 신뢰하는 것이 진짜 실전입니다. 그리고 몇 가지 시행착오의 흔적들이 Figwright의 작동 방식을 형성했습니다:

  • 두 개의 에이전트를 동시에 실행하기. 저는 Claude Code와 Cursor를 모두 열어둡니다. 이전에는 이들이 플러그인 소켓(plugin socket)을 두고 충돌하곤 했기에, Figwright는 리더/팔로워 선출 (leader/follower election) 방식을 실행합니다. 하나가 연결을 소유하고 나머지는 HTTP를 통해 전달하며, 만약 리더가 종료되면 팔로워가 즉시 인계받습니다. 1초 미만의 속도로 수동 재연결 없이 이루어집니다.
  • "바쁨 ≠ 죽음(Busy ≠ dead)." 대규모 내보내기(export) 작업은 연결이 끊긴 것처럼 보일 수 있었습니다. 무거운 동기식(synchronous) 단계가 하트비트(heartbeat)를 방해하여 릴레이가 연결을 끊어버렸기 때문입니다. 타임아웃(timeout)을 늘리는 것은 도움이 되지 않았습니다. 하트비트가 작업 중에도 살아남아야 합니다. 이제는 그렇게 작동합니다.
  • 스크린샷이 절대 빈 화면으로 돌아오지 않습니다. 한 번은 로고를 내보냈는데, 로고가 클리핑된 캐러셀(clipped carousel) 안에 있어서 1×1 투명 픽셀만 받은 적이 있습니다. Figwright는 조상 클리핑(ancestor clipping)을 우회하므로, 스크린샷이 빈 화면이 아닌 실제 결과물을 반환합니다.
  • 네트워크상의 바이너리. 플러그인↔서버 프로토콜은 JSON이 아닌 msgpack을 사용합니다. 이는 디자인 데이터가 던지는 덩어리가 큰 페이로드(payload)에 대해 더 빠르고 작습니다.

이 중 화려한 것은 하나도 없습니다. 하지만 이 모든 것이 데모와 마감 기한에 실제로 손이 가는 도구 사이의 차이를 만듭니다.

92개의 도구, 세 그룹

중요한 것은 개수가 아니라 커버리지(coverage)입니다:

  • 읽기 (Read) — 선택, 문서/노드 검사, 스타일(styles), 변수(variables), 컴포넌트(components), 폰트(fonts), 반응(reactions), 스크린샷, 심지어 PDF 내보내기까지.
  • 쓰기 (Write) — 프레임, 텍스트, 도형, 오토 레이아웃(auto-layout), 효과(effects), 스타일, 변수, 컴포넌트, 페이지, 반응 생성 및 편집... 여기에 여러 편집을 한 번에 적용하는 batch 도구가 추가됩니다.
  • 그라운딩 (Grounding)get_design_context, component_map, token_map, icon_map — Figma를 여러분의 코드와 연결하는 결합 계층(join layer)입니다.

여러분의 MCP 클라이언트는 연결 시점에 모든 도구 목록을 나열하므로, 그것이 항상 신뢰할 수 있는 원천(source of truth)이 됩니다.

기술(Skills)이 오케스트레이션을 수행합니다

가공되지 않은 도구들은 저수준(low-level)입니다. Figwright는 그라운딩된 워크플로우를 인코딩하는, 모델이 호출하는 두 가지 **기술 (skills)**을 함께 제공하므로, 여러분의 에이전트가 적절한 순간에 적절한 도구를 사용할 수 있게 합니다.

기술 (Skill)기능
figma-codegen여러분의 스택과 컴포넌트를 기반으로, Figma 선택 영역을 프레임워크를 인식하는 코드 (framework-aware code)로 변환합니다.
figma-build코드나 설명을 바탕으로 Figma 디자인을 구축하며, 파일의 기존 시스템을 재사용합니다.
npx skills add awdr74100/figwright/skills

빠른 시작 (Quick start)

1. 서버 추가: MCP 클라이언트에 서버를 추가합니다 (Claude Code의 경우 .mcp.json; 다른 클라이언트도 동일한 형식을 사용합니다):

{
  "mcpServers": {
    "figwright": {
...

2. 플러그인 설치: 최신 GitHub 릴리스에서 플러그인을 다운로드합니다. 압축을 푼 다음, Figma 데스크톱 앱 (desktop app) → **Plugins → Development → Import plugin from manifest…**를 선택하고 manifest.json을 고릅니다.

3. 연결: Figma에서 플러그인을 엽니다. 자동으로 연결되며 Connected라고 표시됩니다. 에이전트에게 ping을 실행하도록 요청하여 확인하세요.

4. 시도해 보기: 프레임을 선택한 상태에서: "이 Figma 선택 영역을 React 컴포넌트로 코딩해줘." …또는 반대로: _"이 명세(spec)를 바탕으로 Figma에 가격 섹션을 만들어줘."_라고 요청해 보세요.

자주 묻는 질문 (FAQ)

Figma Dev Mode나 유료 플랜이 필요한가요?
아니요. 플러그인이므로 무료 티어로도 충분합니다. Dev Mode 라이선스나 유료 티어는 필요하지 않습니다.

어떤 에이전트가 작동하나요?
MCP를 지원하는 것이라면 무엇이든 가능합니다. Claude Code, Cursor 및 기타 MCP 클라이언트 모두 동일한 방식으로 작동합니다.

여러 에이전트가 동일한 플러그인을 사용할 수 있나요?
네. 리더/팔로워 선출 (leader/follower election) 방식을 통해 하나의 플러그인을 여러 서버가 공유하며, 원활한 핸드오프 (handoff)가 이루어집니다.

실제로 로컬에서 작동하나요?
네. 릴레이(relay)는 127.0.0.1로만 제한되며, 어떤 데이터도 사용자의 기기를 벗어나지 않습니다.

왜 "Figwright"인가요?

figwright는 제작자 또는 장인을 뜻하는 오래된 -wright 전통을 따릅니다. playwright는 희곡을 쓰고, shipwright는 배를 만들며, wheelwright는 바퀴를 만듭니다. 이는 브라우저를 자동화하는 Playwright에 대한 경의이기도 합니다. Playwright가 브라우저를 제어한다면, Figwright는 Figma를 제어합니다. 즉, 캔버스를 읽는 동시에 그 위에 다시 작업을 만들어내는 디자인 제작자입니다.

직접 사용해 보시고, 무엇이 잘못되는지 알려주세요.

이 프로젝트는 MIT 라이선스이며, 기여에 열려 있습니다. 또한 Glama에서 이미 A 등급의 품질 점수를 기록하고 있습니다.

제가 Figwright를 만든 이유는 제 디자인을 그저 바라보기만 하고, 그럴 때마다 저에게 숙제를 떠넘기는 AI 도구들에 지쳤기 때문입니다. 만약 여러분도 똑같은 한계를 느끼셨다면, 실제 파일에서 직접 사용해 보시고 양방향 루프 (two-way loop)가 어떻게 작동하는지 알려주세요. 유용했다면 저장소 (repo)에 스타 (Star)를 눌러주시고, 그렇지 않다면 이슈 (issue)를 열어주세요. 여러분이 무엇을 만들어내는지(혹은 무엇을 망가뜨리는지) 진심으로 보고 싶습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0