Figma MCP를 활용하여 디자인 시스템 컴포넌트 제작 (반)자동화하기

jh·2025년 4월 28일

디자인 시스템

목록 보기
14/14

혼자서 디자인 시스템을 만들면서 가장 어려운 점은 '디자인'이다.
그래서 Figma에서 잘 만들어진 디자인 시안을 참고해서 코드로 구현하는 방식을 활용하는데, 이 과정에서 디자인 시안을 실제 React 컴포넌트 코드로 정확하고 일관성 있게 구현하는 것이 생각보다 어려웠다.

1. 스타일 코드 동기화

Figma Dev Mode나 플러그인을 통해 CSS, 라이브러리 문법에 맞는 스타일 코드를 추출할 수 있지만, 이것만으로는 충분하지 않다.
복잡한 컴포넌트 구조를 반영하거나, Figma에 적용된 디자인 토큰을 실제 코드에서 사용하는 디자인 토큰으로 변환하는 등 수작업이 많이 필요하다.

2. Component Set Variant 스타일 분리의 복잡성:

Figma의 Component Set은 Variant별로 스타일을 적용한 컴포넌트를 관리할 수 있는 기능이다
figma-component-set-example

코드에서는 cva 같은 유틸리티로 공통 스타일(base)과 Variant별 스타일을 분리하여 정의하는 것이 일반적인데,

// 예시: tailwind+cva를 사용한 shadcn 코드
const buttonVariants = cva(
  "inline-flex items-center justify-center ...", // 공통 Base 스타일
  {
    variants: { /* ... Variant 스타일 정의 ... */ },
    // ...
  }
);

Figma에서 정의한 Variant를 기반으로 이런 base + variant 형태의 코드를 자동으로 생성할 수 있다면 시간을 매우 단축할 수 있을 것 같아 여러 방법을 찾아보았지만,
Figma에서는 아직 이러한 기능을 자체적으로 제공하고 있지 않다(plugin도 딱히 없는 것 같다)

  • Figma에서 추출한 스타일은 각 Variant가 적용된 결과물일 뿐, Base 스타일과 Variant별 스타일이 분리되어 있지 않다. 이를 코드에서 재사용 가능한 base + variant 구조로 만들려면, 각 Variant 스타일을 추출하고, 비교 분석하여 수동으로 분리해야 하는 복잡함이 있다.

  • 컴포넌트 구조가 복잡하거나(합성 컴포넌트) Figma 파일마다 컴포넌트를 작성하는 방식이 다르기 때문에, 일관된 로직 적용이 어렵다.

  • 어떤 스타일을 공통(Base) 으로 정의할지에 대한 주관적인 판단 문제도 있다.

AI를 활용한 스타일 분류 자동화 접근

사실 이 Base/Variant 스타일 분리 문제는 복잡한 로직이 필요하다기보다는, 여러 스타일 속성들을 보고 '공통적인 것'과 '개별적인 것'을 구분하는 '판단' 이 필요한 부분이다. 그렇다면 이를 AI한테 맡기면 어떨까? 라는 생각을 했다.
따라서, AI를 활용하여 이 분류 작업을 자동화하는 접근법을 구상했다.

Figma Plugin API 활용

  1. Figma에서 각 Component Set Variant의 스타일 정보를 추출한다.
  2. AI(Cursor Rule 활용) 기반 판단: 추출된 스타일 데이터를 AI에게 전달하여, 여러 Variant에 걸쳐 공통적으로 나타나는 스타일(Base 가능성)과 특정 Variant에서만 나타나는 스타일(Variant별 스타일 가능성)을 AI가 판단하고 분류하도록 한다.
  3. 판단 기준 제공 (Cursor Rule): AI의 판단 정확도를 높이기 위해 Cursor Rule 등을 통해 구체적인 분류 기준이나 가이드라인을 제공한다.

Figma MCP를 활용한 생산성 증가

사실 이 AI 기반 분류 작업은 MCP가 활성화되기 전부터 시도해오던 작업이었다. 당시에는 자체 제작한 Figma 플러그인을 로컬에서 실행해서 콘솔로 결과물을 출력하고, 이 결과물을 복사해서 Claude 같은 LLM에게 전달하는 방식으로 진행했다. 이 과정에서 수작업이 너무 많았다.

이후 MCP(Model Context Protocol)와 Figma MCP 구현체에 대한 소개를 보고, 이 번거로운 작업 과정을 개선하는 데 MCP를 이용할 수 있지 않을까 생각했다.

사용한 MCP 구현체는 cursor-talk-to-figma-mcp이다. 이 방식은 Figma 플러그인을 실행해야 MCP 서버와 통신이 가능한 약간의 불편함은 있지만, Figma 노드 정보 접근 등 다양한 API를 제공하고 있어 활용하기로 했다.

MCP의 상세한 동작 원리까지는 모르지만, cursor-talk-to-figma의 server.ts 코드를 보면 다음과 같은 구조로 동작한다.

server.tool(
  "get_nodes_info", // 도구(명령어) 이름
  "Get detailed information about multiple nodes in Figma", // 설명
  { /* 입력 스키마 정의 */ },
  async ({ nodeIds }) => { // 실제 로직
    // ... nodeIds를 받아 Figma에 명령 전달 ...
    const result = await sendCommandToFigma("get_node_info", { nodeId });
    // ... 결과 반환 ...
  }
);

Cursor Agent가 get_nodes_info 같은 명령을 받으면(혹은 유사한 요청 시 자체 판단), sendCommandToFigma 함수를 호출하고, 이 함수는 Figma 플러그인 내부에 정의된 로직을 실행시킨다.

// Figma 플러그인 코드 예시 (plugin.ts)
async function handleCommand(command, params) {
  switch (command) {
    case "get_node_info":
      // ... params에서 nodeId 추출 ...
      return await getNodeInfo(params.nodeId); // 플러그인 내부 함수 호출
    // ...
  }
}

async function getNodeInfo(nodeId) {
  // ... figma.getNodeByIdAsync(nodeId) 등 figma plugin API를 활용
  return extractedInfo;
}

이 구조를 보고, AI에게 스타일 분류를 요청하는 로직을 MCP의 커스텀 명령어로 만들 수 있지 않을까 생각했다.
(기존 cursor-talk-to-figma에 있던 명령어들이 Component Set의 Variant와 관련된 정보를 잘 못가져오는 것 같아서 직접 만들기로 했다.)

그래서 기존 플러그인에서 사용하던 로직을 옮겨와 MCP 서버에 새로운 Command를 추가하는 방식으로 구현을 시도했다.

  • 하지만 Cursor에서 새로 추가한 Command를 제대로 인식하지 못하는 문제가 발생했다.
  • 결국 차선책으로, 기존에 있던 get_nodes_info 같은 Command의 내부 로직을 만든 스타일 분류 로직으로 교체하여 사용하는 방식으로 구현했다.

결과물과, 개선 사항은 다음 포스트에서...
그전에 느낀 점

  1. rule이 정말 중요하다. 잘 작성된 rule일수록 퍼포먼스가 좋아지는게 느껴진다
  • rule은 길다고 좋은게 아니다. awesome-cursor-rule이나 figma 관련 rule등을 참고해서 핵심만 명확히 적는게 좋다
  • 가끔 Cursor가 rule을 까먹는다. 정신 못차리는 것 같으면 @rule 참고하라고 한번 알려주는게 좋다
  • /generate cursor rules를 이용하면 대화한 내용을 기반으로 룰을 생성해준다
  1. 개발자와 디자이너가 합의하여 figma 파일 작성법을 좀더 개발 친화적으로 통일할 수 있다면 효과는 매우 좋을 것 같다(그렇게 된다면 난 뭐하지..)

0개의 댓글