Figma 퍼블리싱 파이프라인 01. 자동화 전략과 기술 선택
"Figma 링크 공유드렸어요. 이번 주 안에 퍼블리싱 부탁드립니다."
이 말을 듣고 나면 Figma를 열고, 색상을 눈으로 확인하고, 폰트 사이즈를 하나씩 읽고, 아이콘을 export하고, 이미지를 받는다. 지금 하는 외주 프로젝트는 관리자 대시보드 페이지만 수십 개인데 매번 같은 수작업을 반복하고 있었다. 자동화하기로 하고 Claude와 Python 스크립트, Figma API를 조합해 Figma URL 하나를 넣으면 코드가 나오는 파이프라인을 짰다.
AI는 코드 생성 단계에만 쓰기로 했다
AI는 PHASE 2에서만 부른다. 나머지는 Python이 처리해서 비용과 시간을 줄였다.
MCP와 REST API는 같은 데이터를 주지 않았다
Figma에서 데이터를 뽑는 방법이 두 가지였다. Claude Code에서 get_design_context를 호출하는 MCP 방식과 Figma REST API를 직접 호출하는 방식이다. 둘 다 Figma 데이터를 가져온다고 하는데, 돌려보니 성격이 완전히 달랐다.
MCP가 반환하는 건 Tailwind 클래스로 표현된 근사값이다. 실제 Figma 값이 12px여도 Tailwind의 4px 그리드로 반올림돼서 p-3이 아니라 p-4로 나오는 경우가 있다. REST API의 paddingTop, paddingLeft는 픽셀 단위 그대로다.
수치보다 심각한 게 세 가지 더 있었다.
첫째, 토큰 바인딩 정보가 없다. 디자인 시스템에서 중요한 건 색상값 자체가 아니라 그 색이 어떤 시맨틱 토큰에 연결돼 있는가다. #3B82F6을 하드코딩하면 안 되고 color.primary.500으로 써야 한다. REST API 응답에는 boundVariables 필드가 있어서 이 노드의 이 fill이 어떤 변수에 묶여 있는지 정확히 알 수 있다. MCP의 get_variable_defs는 변수 이름과 값의 매핑은 조회되지만 노드별 바인딩은 안 나온다.
둘째, 숨겨진 상태가 빠진다. 컴포넌트에는 기본, 호버, 비활성 같은 여러 상태가 있고 Figma에서는 visible: false 레이어나 componentProperties로 표현된다. get_design_context는 현재 보이는 상태 하나만 준다. REST API로 전체 노드 트리를 받으면 모든 상태가 다 들어 있다. 조건부 렌더링을 구현할 때 이 차이가 결정적이었다.
셋째, 복잡한 컴포넌트에서 get_design_context 응답이 잘리는 경우가 있었다. REST API는 depth 파라미터로 조회 깊이를 조절하고, 잘린 노드를 감지해 추가 요청으로 채울 수 있다.
토큰을 계산해보니 예상과 반대였다
MCP가 전처리된 결과를 주니까 토큰이 덜 들 것 같았는데, 어디서 파싱하느냐에 따라 뒤집혔다.
| 방식 | 노드당 추정 토큰 |
|---|---|
| MCP 호출 + 전처리된 결과 수신 | 6K~16K |
| REST API 원본 JSON을 Claude가 직접 파싱 | 35K~85K |
| REST API를 Python이 파싱하고 구조화된 스펙만 전달 | 3K~8K |
REST API를 Claude에게 그대로 던지면 최악이지만, Python이 밖에서 파싱하면 Claude에게는 정리된 스펙만 넘어간다. 파싱 비용이 0 토큰이 된다.
Python + REST API로 정했다
| MCP | REST API | |
|---|---|---|
| 수치 정확도 | 근사값 | 픽셀 단위 정확 |
| 토큰 역추적 | 변수 정의 조회 가능, 노드별 바인딩 미제공 | boundVariables로 노드별 바인딩 |
| 숨겨진 레이어 | 미포함 | 전체 포함 |
| 조건부 UI 상태 | 현재 상태만 | 모든 상태 |
| 스크린샷 | 있음 | 없음 |
| 응답 잘림 가능성 | 있음 | 제어 가능 |
| 토큰 비용 | 응답 크기만큼 소모 | Python 전처리 시 0 |
정확한 스펙 수집은 REST API로 하고, 시각적 확인과 코드 생성 보조에만 MCP를 쓰기로 했다. MCP는 스크린샷을 주는데 REST API는 안 주기 때문에, 결과물이 시안과 맞는지 눈으로 대조하는 용도로는 여전히 필요했다.