loading…
Search for a command to run...
loading…
This server enables AI to match Figma design nodes with React components from Storybook and generate usage code examples, facilitating design-to-code workflows.
This server enables AI to match Figma design nodes with React components from Storybook and generate usage code examples, facilitating design-to-code workflows.
원격 MCP 서버를 만든다. Figma 디자인 노드를 입력받아 우리 팀의 React 컴포넌트(Storybook에 등록된)와 매칭시키고, 사용 코드 예시까지 생성하는 게 목적.
LLM(Claude)이 이 MCP를 통해 다음 같은 요청을 처리할 수 있어야 함:
@modelcontextprotocol/sdk + agents 패키지 사용/mcpAuthorization: Bearer <token> 필요env.MCP_AUTH_TOKEN과 비교, 불일치 시 401 반환{"error": "invalid_token"})FIGMA_TOKEN: Figma Personal Access Token (서버가 보관)STORYBOOK_URL: Storybook 베이스 URL (예: https://storybook.example.com)MCP_AUTH_TOKEN: 클라이언트 인증용 토큰COMPONENT_IMPORT_PREFIX: 코드 생성 시 import 경로 (기본 @/components)로컬 개발용은 .dev.vars, 프로덕션은 wrangler secret put으로 관리. wrangler.toml에는 더미 placeholder만 두기.
get_figma_node설명: Figma URL을 받아서 노드의 핵심 정보를 정제된 형태로 반환
입력 (zod):
{
url: string // Figma 노드 URL (예: https://www.figma.com/file/XXX/...?node-id=1%3A2)
}
동작:
fileKey와 nodeId 파싱 (?node-id=1%3A2 → 1:2로 디코드)GET https://api.figma.com/v1/files/{fileKey}/nodes?ids={nodeId}X-Figma-Token: {env.FIGMA_TOKEN}name)type: FRAME, INSTANCE, TEXT, ...)componentId → componentName)characters와 폰트 정보출력: 위 정보를 담은 정제된 JSON 객체
에러: URL 파싱 실패, Figma API 4xx/5xx, 토큰 만료 등 구분해서 에러 메시지
get_figma_subtree설명: 노드의 전체 트리를 재귀적으로 가져옴 (전체 페이지/프레임 분석용)
입력:
{
url: string,
maxDepth?: number // 기본 3, 너무 깊으면 토큰 폭발
}
동작: get_figma_node와 비슷하지만 자식을 maxDepth까지 재귀. 각 자식도 정제된 형식.
list_stories설명: 우리 Storybook의 컴포넌트 목록을 반환
입력: 없음 (또는 { filter?: string } 검색용)
동작:
${env.STORYBOOK_URL}/index.json fetch${env.STORYBOOK_URL}/stories.json 시도entries 객체에서 type: "story"인 것만 추출 (docs 페이지 제외){
id: string,
componentName: string, // title에서 마지막 "/" 뒤 부분 (예: "Forms/Button" → "Button")
storyName: string, // name 필드
fullTitle: string, // 원본 title
tags: string[]
}[]
캐싱: 응답을 5분간 in-memory 캐싱 (KV 안 써도 됨, 단순 변수로). Workers는 인스턴스가 짧게 살아있으니 너무 길게 잡지 말 것.
get_story_details설명: 특정 스토리의 상세 정보 (props, args)
입력:
{ storyId: string }
동작:
index.json에서 해당 ID 찾음${STORYBOOK_URL}/stories.json 또는 ID 기반 메타에서 argTypes 추출{
id: string,
componentName: string,
description?: string,
props: {
name: string,
type: string,
required: boolean,
description?: string,
defaultValue?: any
}[]
}
argTypes 못 가져오면 props는 빈 배열로, 대신 note: "argTypes unavailable" 추가.
match_figma_to_components설명: Figma 노드 데이터와 매칭되는 컴포넌트 후보를 점수와 함께 반환 (핵심 도구)
입력:
{
figmaNode: <get_figma_node 출력 형식>,
topK?: number // 기본 3
}
동작:
list_stories로 전체 컴포넌트 가져옴componentName{
storyId: string,
componentName: string,
score: number, // 0~1
reasons: string[] // 왜 매칭됐는지 사람이 읽을 수 있게
}[]
매칭 점수 0.3 미만은 제외 (의미 없는 매칭 거름).
generate_component_usage설명: 매칭된 컴포넌트 + Figma 노드 정보로 React JSX 코드 예시 생성
입력:
{
storyId: string,
figmaNode: <get_figma_node 출력 형식>
}
동작:
get_story_details로 props 시그니처 가져옴children 또는 label prop출력:
{
code: string, // <Button variant="primary">Click me</Button>
importStatement: string, // import { Button } from "@/components/Button"
notes: string[] // 매핑 추측이나 빠진 정보 안내
}
import path는 환경변수 env.COMPONENT_IMPORT_PREFIX(기본값 "@/components") 기준.
figma-storybook-mcp/
├── src/
│ ├── index.ts # Worker 진입점, 인증 미들웨어, MCP 라우팅
│ ├── mcp.ts # MyMCP 클래스 (도구 등록)
│ ├── auth.ts # Bearer 토큰 검증
│ ├── figma/
│ │ ├── client.ts # Figma REST API 호출
│ │ ├── url-parser.ts # URL → fileKey + nodeId
│ │ └── normalizer.ts # Figma 응답 → 정제된 형식
│ ├── storybook/
│ │ ├── client.ts # index.json fetch + 캐싱
│ │ └── types.ts
│ ├── matching/
│ │ ├── scorer.ts # 매칭 점수 계산
│ │ └── name-similarity.ts # Levenshtein 등
│ ├── codegen/
│ │ └── react.ts # JSX 코드 생성
│ └── types.ts # 공통 타입
├── tests/
│ ├── url-parser.test.ts
│ ├── normalizer.test.ts
│ └── scorer.test.ts
├── wrangler.toml
├── .dev.vars.example # 실제 .dev.vars는 gitignore
├── package.json
├── tsconfig.json
├── vitest.config.ts
└── README.md
console.log로 도구 호출 시작/끝, 에러는 console.error. Workers 대시보드에서 보임npm run dev)npm run deploy)wrangler.toml, tsconfig.json 작성/mcp에서 응답하는지 확인 (도구 0개여도 OK)figma/url-parser.ts + 단위 테스트figma/client.ts (실제 API 호출)figma/normalizer.ts (응답 정제)get_figma_node 도구 등록storybook/client.ts (index.json fetch + 캐싱)list_stories, get_story_details 등록matching/scorer.ts + 단위 테스트match_figma_to_components 등록codegen/react.tsgenerate_component_usage 등록get_figma_subtree 추가.dev.vars.example 제공각 Phase 끝나면 짧게 "이거 했고 다음 이거 할게" 보고하고 진행.
@modelcontextprotocol/sdk 최신 안정 버전 사용agents 패키지의 최신 패턴 따를 것Phase 1부터 시작해줘.
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"figma-storybook-component-matching-mcp-server": {
"command": "npx",
"args": []
}
}
}