#
tokens: 6831/50000 11/11 files
lines: on (toggle) GitHub
raw markdown copy reset
# Directory Structure

```
├── .DS_Store
├── .gitignore
├── .prettierrc
├── Dockerfile
├── eslint.config.js
├── package-lock.json
├── package.json
├── README.md
├── smithery.yaml
├── src
│   ├── helpers
│   │   ├── extractComponent.ts
│   │   └── index.ts
│   └── index.ts
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
1 | node_modules/
2 | build/
3 | .env
```

--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------

```
1 | {
2 |   "semi": false,
3 |   "singleQuote": true,
4 |   "tabWidth": 2,
5 |   "trailingComma": "es5"
6 | }
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Figma to React Native MCP
  2 | 
  3 | Convert Figma designs to React Native components using Cursor's MCP. This tool extracts components from your Figma designs and generates corresponding React Native components with proper typing and styling.
  4 | 
  5 | ## Installation
  6 | 
  7 | ### For Development
  8 | 
  9 | Add to your `eas.json`:
 10 | 
 11 | ```json
 12 | {
 13 |   "mcpServers": {
 14 |     "figma-to-code": {
 15 |       "command": "node",
 16 |       "args": ["PATH_TO_REPO/build/index.js"],
 17 |       "env": {
 18 |         "FIGMA_TOKEN": "your_figma_token",
 19 |         "FIGMA_FILE": "your_figma_file_id",
 20 |         "PROJECT_DIR": "your_project_directory"
 21 |       }
 22 |     }
 23 |   }
 24 | }
 25 | ```
 26 | 
 27 | ### For End Users
 28 | 
 29 | Install the MCP server in your Cursor IDE:
 30 | 
 31 | ```bash
 32 | npx -y @smithery/cli@latest install @kailashg101/mcp-figma-to-code --client claude --config "{
 33 |   \"figmaToken\": \"YOUR_FIGMA_TOKEN\",
 34 |   \"figmaFile\": \"YOUR_FIGMA_FILE_ID\",
 35 |   \"projectDir\": \"YOUR_PROJECT_DIRECTORY\"
 36 | }"
 37 | ```
 38 | 
 39 | ## Usage
 40 | 
 41 | After installation, you can use the following prompts in Cursor:
 42 | 
 43 | ### Extract All Components
 44 | 
 45 | ```
 46 | using the extract_components mcp tool get all components from figma and generate their corresponding react native components in components folder
 47 | ```
 48 | 
 49 | ### Extract Specific Component
 50 | 
 51 | ```
 52 | using the extract_components mcp tool get the [ComponentName] component from figma and generate its corresponding react native component in components folder
 53 | ```
 54 | 
 55 | ## Configuration
 56 | 
 57 | The config object accepts the following parameters:
 58 | 
 59 | ```typescript
 60 | {
 61 |   "figmaToken": string,    // Your Figma access token
 62 |   "figmaFile": string,     // Your Figma file ID (from the URL)
 63 |   "projectDir": string     // Where to generate the components
 64 | }
 65 | ```
 66 | 
 67 | ## Features
 68 | 
 69 | Current:
 70 | 
 71 | - ✅ Extract components from Figma
 72 | - ✅ Generate React Native components
 73 | - ✅ Maintain component hierarchy
 74 | - ✅ Handle component props and types
 75 | - ✅ Support nested components
 76 | 
 77 | Coming Soon:
 78 | 
 79 | - 🚧 GraphQL schema generation
 80 | 
 81 | ## Development
 82 | 
 83 | To contribute or modify:
 84 | 
 85 | 1. Clone the repository
 86 | 2. Install dependencies:
 87 | 
 88 | ```bash
 89 | npm install
 90 | ```
 91 | 
 92 | 3. Build:
 93 | 
 94 | ```bash
 95 | npm run build
 96 | ```
 97 | 
 98 | 4. Run locally:
 99 | 
100 | ```bash
101 | npm start
102 | ```
103 | 
104 | ## Environment Variables
105 | 
106 | When running locally, you'll need these in your `.env`:
107 | 
108 | ```bash
109 | FIGMA_TOKEN=your_figma_token
110 | FIGMA_FILE=your_figma_file_id
111 | PROJECT_DIR=your_project_directory
112 | ```
113 | 
114 | ## Error Handling
115 | 
116 | Common errors and solutions:
117 | 
118 | - **"Failed to create client"**: Check if all environment variables are properly set
119 | - **"Components page not found"**: Ensure your Figma file has a page named "Components"
120 | - **"Failed to fetch Figma file"**: Verify your Figma token and file ID
121 | 
122 | ## License
123 | 
124 | MIT
125 | 
126 | ---
127 | 
128 | For issues and feature requests, please open an issue on GitHub.
129 | 
```

--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |     "compilerOptions": {
 3 |       "target": "ES2022",
 4 |       "module": "Node16",
 5 |       "moduleResolution": "Node16",
 6 |       "outDir": "build",
 7 |       "rootDir": "src",
 8 |       "strict": true,
 9 |       "esModuleInterop": true,
10 |       "skipLibCheck": true,
11 |       "forceConsistentCasingInFileNames": true,
12 |       "declaration": true
13 |     },
14 |     "include": ["src/**/*"],
15 |     "exclude": ["node_modules", "build"]
16 |   }
```

--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | # Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile
 2 | FROM node:lts-alpine
 3 | 
 4 | # Create app directory
 5 | WORKDIR /app
 6 | 
 7 | # Copy package files
 8 | COPY package.json package-lock.json ./
 9 | 
10 | # Install dependencies
11 | RUN npm install --ignore-scripts
12 | 
13 | # Copy source files
14 | COPY tsconfig.json ./
15 | COPY src ./src
16 | 
17 | # Build the project
18 | RUN npm run build
19 | 
20 | # Expose port if needed (not used by MCP over stdio)
21 | 
22 | # Start the MCP server
23 | CMD [ "npm", "start" ]
24 | 
```

--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------

```javascript
 1 | import pluginJs from "@eslint/js";
 2 | import prettier from "eslint-config-prettier";
 3 | import prettierPlugin from "eslint-plugin-prettier";
 4 | 
 5 | export default [
 6 |   pluginJs.configs.recommended,
 7 |   prettier, // Disables conflicting ESLint rules
 8 |   {
 9 |     plugins: {
10 |       prettier: prettierPlugin,
11 |     },
12 |     rules: {
13 |       "prettier/prettier": "error", // Shows Prettier issues as ESLint errors
14 |       "no-unused-vars": "warn",
15 |       "no-undef": "warn",
16 |       "@typescript-eslint/no-unused-vars": ["error"],
17 |     },
18 |   },
19 | ];
20 | 
```

--------------------------------------------------------------------------------
/smithery.yaml:
--------------------------------------------------------------------------------

```yaml
 1 | # Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml
 2 | 
 3 | startCommand:
 4 |   type: stdio
 5 |   configSchema:
 6 |     # JSON Schema defining the configuration options for the MCP.
 7 |     type: object
 8 |     required:
 9 |       - figmaToken
10 |       - figmaFile
11 |       - projectDir
12 |     properties:
13 |       figmaToken:
14 |         type: string
15 |         description: Figma API token required to fetch Figma file data
16 |       figmaFile:
17 |         type: string
18 |         description: ID of the Figma file to be analyzed
19 |       projectDir:
20 |         type: string
21 |         description: Directory path for project files where output or assets will be stored
22 |   commandFunction:
23 |     # A JS function that produces the CLI command based on the given config to start the MCP on stdio.
24 |     |-
25 |     (config) => ({
26 |       command: 'node',
27 |       args: ['build/index.js'],
28 |       env: {
29 |         FIGMA_TOKEN: config.figmaToken,
30 |         FIGMA_FILE: config.figmaFile,
31 |         PROJECT_DIR: config.projectDir
32 |       }
33 |     })
34 |   exampleConfig:
35 |     figmaToken: dummy-figma-token
36 |     figmaFile: dummy-figma-file-id
37 |     projectDir: /path/to/project
38 | 
```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "@kailashg101/mcp-figma-to-code",
 3 |   "version": "1.0.1",
 4 |   "description": "MCP server for converting Figma designs to React Native components",
 5 |   "main": "build/index.js",
 6 |   "type": "module",
 7 |   "keywords": [
 8 |     "mcp",
 9 |     "figma",
10 |     "react-native",
11 |     "cursor",
12 |     "components",
13 |     "design-to-code"
14 |   ],
15 |   "author": "Kailash G",
16 |   "license": "MIT",
17 |   "bin": {
18 |     "mcp-figma": "./build/index.js"
19 |   },
20 |   "scripts": {
21 |     "build": "tsc && chmod 755 build/index.js",
22 |     "start": "node build/index.js",
23 |     "dev": "ts-node-esm src/index.ts",
24 |     "prepublishOnly": "npm run build"
25 |   },
26 |   "files": [
27 |     "build",
28 |     "README.md"
29 |   ],
30 |   "publishConfig": {
31 |     "access": "public"
32 |   },
33 |   "dependencies": {
34 |     "@modelcontextprotocol/sdk": "^1.7.0",
35 |     "dotenv": "^16.4.5",
36 |     "fs-extra": "^11.2.0",
37 |     "lodash": "^4.17.21",
38 |     "node-fetch": "^3.3.2",
39 |     "ws": "^8.16.0",
40 |     "zod": "^3.22.4"
41 |   },
42 |   "devDependencies": {
43 |     "@eslint/js": "^9.22.0",
44 |     "@types/dotenv": "^8.2.0",
45 |     "@types/node": "^20.11.24",
46 |     "eslint": "^9.22.0",
47 |     "eslint-config-prettier": "^10.1.1",
48 |     "eslint-plugin-prettier": "^5.2.3",
49 |     "globals": "^16.0.0",
50 |     "prettier": "^3.5.3",
51 |     "ts-node": "^10.9.2",
52 |     "typescript": "^5.3.3",
53 |     "typescript-eslint": "^8.26.1"
54 |   }
55 | }
56 | 
```

--------------------------------------------------------------------------------
/src/helpers/index.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import fs from 'node:fs'
  2 | 
  3 | // Get environment variables
  4 | const FIGMA_TOKEN = process.env.FIGMA_TOKEN || ''
  5 | const FIGMA_FILE = process.env.FIGMA_FILE || ''
  6 | 
  7 | export function camelCaseToDash(string: string) {
  8 |   return string.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()
  9 | }
 10 | 
 11 | export async function createFolder(path: string) {
 12 |   try {
 13 |     await fs.promises.access(path, fs.constants.F_OK)
 14 |   } catch (err) {
 15 |     await fs.promises.mkdir(path)
 16 |   }
 17 | }
 18 | 
 19 | export async function fetchSVGURL(id: string) {
 20 |   const url = `https://api.figma.com/v1/images/${FIGMA_FILE}/?ids=${id}&format=svg`
 21 |   const headers = { 'X-Figma-Token': FIGMA_TOKEN || '' }
 22 | 
 23 |   const response = await fetch(url, { headers })
 24 | 
 25 |   if (!response.ok) {
 26 |     throw new Error(`Failed to fetch svg url: ${response.statusText}`)
 27 |   }
 28 | 
 29 |   const data = await response.json()
 30 |   return data
 31 | }
 32 | 
 33 | export async function writeToFile(filename: string, data: string) {
 34 |   try {
 35 |     await fs.promises.access(filename, fs.constants.F_OK)
 36 |     console.log(`File ${filename} already exists. Skipping write.`)
 37 |     // eslint-disable-next-line no-unused-vars
 38 |   } catch (error) {
 39 |     return fs.writeFile(filename, data, (error) => {
 40 |       if (error) {
 41 |         console.error(`Error writing file ${filename}: ${error}`)
 42 |         throw error
 43 |       }
 44 |     })
 45 |   }
 46 | }
 47 | 
 48 | interface FigmaNode {
 49 |   id: string
 50 |   name: string
 51 | }
 52 | 
 53 | export function findAllByValue(obj: any, valueToFind: string): FigmaNode[] {
 54 |   return Object.entries(obj).reduce<FigmaNode[]>(
 55 |     (acc, [key, value]) =>
 56 |       value === valueToFind
 57 |         ? acc.concat({
 58 |             id: Object.values(obj.id).join(''),
 59 |             name: Object.values(obj.name).join(''),
 60 |           })
 61 |         : typeof value === 'object' && value !== null
 62 |           ? acc.concat(findAllByValue(value, valueToFind))
 63 |           : acc,
 64 |     []
 65 |   )
 66 | }
 67 | 
 68 | // Helper functions for component generation
 69 | export function toPascalCase(str: string): string {
 70 |   return str
 71 |     .split(/[^a-zA-Z0-9]/g)
 72 |     .filter(Boolean)
 73 |     .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
 74 |     .join('')
 75 | }
 76 | 
 77 | export const normalizeName = (name: string) =>
 78 |   name.toLowerCase().replace(/[^a-z0-9]/g, '')
 79 | 
 80 | export function toCamelCase(str: string): string {
 81 |   const pascal = toPascalCase(str)
 82 |   return pascal.charAt(0).toLowerCase() + pascal.slice(1)
 83 | }
 84 | 
 85 | export async function fetchFigmaData() {
 86 |   const response = await fetch(`https://api.figma.com/v1/files/${FIGMA_FILE}`, {
 87 |     headers: {
 88 |       'X-Figma-Token': FIGMA_TOKEN,
 89 |     },
 90 |   })
 91 | 
 92 |   if (!response.ok) {
 93 |     const errorText = await response.text()
 94 |     return {
 95 |       isError: true,
 96 |       content: [
 97 |         {
 98 |           type: 'text' as const,
 99 |           text: `Failed to fetch Figma file: ${response.status} ${response.statusText} - ${errorText}`,
100 |         },
101 |       ],
102 |     }
103 |   }
104 | 
105 |   return await response.json()
106 | }
107 | 
```

--------------------------------------------------------------------------------
/src/helpers/extractComponent.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { existsSync } from 'node:fs'
  2 | import { normalizeName, toCamelCase, toPascalCase } from './index.js'
  3 | import { join } from 'node:path'
  4 | 
  5 | const PROJECT_DIR = process.env.PROJECT_DIR || '/'
  6 | const componentDir = join(PROJECT_DIR, 'components')
  7 | interface ComponentChild {
  8 |   name: string
  9 |   type: string
 10 |   style?: any
 11 |   fills?: any
 12 |   children: ComponentChild[]
 13 | }
 14 | 
 15 | interface ProcessedComponent {
 16 |   name: string
 17 |   props: Array<{
 18 |     name: string
 19 |     type: string
 20 |   }>
 21 |   children: ComponentChild[]
 22 | }
 23 | 
 24 | const areSameComponent = (name1: string, name2: string): boolean => {
 25 |   return normalizeName(name1) === normalizeName(name2)
 26 | }
 27 | 
 28 | function extractComponentChildren(children: any[]): ComponentChild[] {
 29 |   if (!Array.isArray(children)) return []
 30 | 
 31 |   return children.map(({ name, children, type, style, fills }) => ({
 32 |     name,
 33 |     type,
 34 |     style,
 35 |     fills,
 36 |     children: extractComponentChildren(children || []),
 37 |   }))
 38 | }
 39 | 
 40 | function extractComponentProps(children: any[]) {
 41 |   return children
 42 |     .flatMap((c: any) => {
 43 |       const parts = c.name.split(', ')
 44 |       return parts.map((prop: string) => {
 45 |         const [key, value] = prop.split('=')
 46 |         return {
 47 |           name: toCamelCase(key),
 48 |           type: value === 'True' || value === 'False' ? 'boolean' : value,
 49 |         }
 50 |       })
 51 |     })
 52 |     .reduce((acc: Record<string, any>, prop) => {
 53 |       if (!acc[prop.name]) acc[prop.name] = { ...prop }
 54 |       else if (!acc[prop.name].type.includes(prop.type))
 55 |         acc[prop.name].type = `${acc[prop.name].type} | ${prop.type}`
 56 |       return acc
 57 |     }, {})
 58 | }
 59 | 
 60 | export async function generateComponent(
 61 |   component: any,
 62 |   validation: boolean = false,
 63 |   componentToExtract: string = ''
 64 | ) {
 65 |   try {
 66 |     const { document } = component
 67 |     const componentsPage = document.children.find(
 68 |       (c: any) => c.name === 'Components'
 69 |     )
 70 | 
 71 |     if (!componentsPage) {
 72 |       console.log('No Components page found in document')
 73 |       throw new Error('Components page not found in Figma file')
 74 |     }
 75 | 
 76 |     const page = componentsPage.children
 77 |     let componentSets = []
 78 |     let processedCount = 0
 79 |     const checkExisting = (componentName: string) =>
 80 |       validation ? !existsSync(`${componentDir}/${componentName}`) : true
 81 | 
 82 |     const specificComponent = (
 83 |       componentName: string,
 84 |       componentToExtract: string
 85 |     ) =>
 86 |       componentToExtract
 87 |         ? areSameComponent(componentName, componentToExtract)
 88 |         : true
 89 | 
 90 |     for (const section of page) {
 91 |       const { children } = section
 92 |       if (!children) continue
 93 | 
 94 |       for (const item of children) {
 95 |         const { type, name } = item
 96 |         const componentName = toPascalCase(name)
 97 | 
 98 |         if (
 99 |           type === 'COMPONENT_SET' &&
100 |           checkExisting(componentName) &&
101 |           specificComponent(componentName, componentToExtract)
102 |         ) {
103 |           processedCount++
104 | 
105 |           try {
106 |             const props = extractComponentProps(item.children)
107 | 
108 |             const minified = {
109 |               name: componentName,
110 |               props,
111 |               children: extractComponentChildren(item.children),
112 |             }
113 |             componentSets.push(minified)
114 |           } catch (processError) {
115 |             return {
116 |               message: `Error processing component ${name}: ${processError}`,
117 |               componentSets: [],
118 |             }
119 |           }
120 |         }
121 |       }
122 |     }
123 | 
124 |     // Create a formatted result for the user
125 |     const message = `Successfully processed ${processedCount} components.\n\nComponent sets: ${componentSets.length}\nComponent paths:\n${componentSets.map((cs) => `- ${cs.name}`).join('\n')}`
126 | 
127 |     // Return both the result message and the component data
128 |     return {
129 |       message,
130 |       componentSets,
131 |     }
132 |   } catch (error) {
133 |     console.error(`Error generating component: ${error}`)
134 |     throw error
135 |   }
136 | }
137 | 
```

--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
  2 | import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
  3 | import { z } from 'zod'
  4 | import { generateComponent } from './helpers/extractComponent.js'
  5 | import { fetchFigmaData } from './helpers/index.js'
  6 | 
  7 | // Load environment variables
  8 | 
  9 | const logger = {
 10 |   info: (message: string, meta?: Record<string, any>) => {
 11 |     console.error(`[INFO] ${message}`, meta ? JSON.stringify(meta) : '')
 12 |   },
 13 |   error: (message: string, error?: any) => {
 14 |     console.error(
 15 |       `[ERROR] ${message}`,
 16 |       error instanceof Error ? error.stack : error
 17 |     )
 18 |   },
 19 |   warn: (message: string, meta?: Record<string, any>) => {
 20 |     console.error(`[WARN] ${message}`, meta ? JSON.stringify(meta) : '')
 21 |   },
 22 | }
 23 | // Get environment variables
 24 | const FIGMA_TOKEN = process.env.FIGMA_TOKEN
 25 | const FIGMA_FILE = process.env.FIGMA_FILE
 26 | const PROJECT_DIR = process.env.PROJECT_DIR
 27 | 
 28 | if (!FIGMA_TOKEN || !FIGMA_FILE || !PROJECT_DIR) {
 29 |   console.error(
 30 |     'Missing required environment variables FIGMA_TOKEN or FIGMA_FILE or PROJECT_DIR'
 31 |   )
 32 |   process.exit(1)
 33 | }
 34 | 
 35 | // Create MCP server with explicit capabilities
 36 | const server = new McpServer(
 37 |   {
 38 |     name: 'Figma Component Extractor',
 39 |     version: '1.0.0',
 40 |   },
 41 |   {
 42 |     capabilities: {
 43 |       tools: {},
 44 |     },
 45 |   }
 46 | )
 47 | 
 48 | // Tool to extract components from Figma file
 49 | server.tool(
 50 |   'extract-components',
 51 |   'Extract all components from Figma file and get all graphql queries and mutations',
 52 |   async (extra) => {
 53 |     try {
 54 |       // Fetch Figma file data
 55 |       logger.info('Fetching Figma file data...')
 56 |       const response = await fetch(
 57 |         `https://api.figma.com/v1/files/${FIGMA_FILE}`,
 58 |         {
 59 |           headers: {
 60 |             'X-Figma-Token': FIGMA_TOKEN,
 61 |           },
 62 |         }
 63 |       )
 64 | 
 65 |       if (!response.ok) {
 66 |         const errorText = await response.text()
 67 |         throw new Error(
 68 |           `Failed to fetch Figma file: ${response.status} ${response.statusText} - ${errorText}`
 69 |         )
 70 |       }
 71 | 
 72 |       const data = await response.json()
 73 |       logger.info('Successfully fetched Figma file data')
 74 | 
 75 |       // Process the component data
 76 |       const result = await generateComponent(data)
 77 |       logger.info('Component extraction successful')
 78 | 
 79 |       // Return the result to the client
 80 |       return {
 81 |         // componentsData: result.componentSets, // Pass the structured component data
 82 |         content: [
 83 |           {
 84 |             type: 'text' as const,
 85 |             text: result.message,
 86 |           },
 87 |         ],
 88 |       }
 89 |     } catch (error: any) {
 90 |       logger.error('Error extracting components:', error)
 91 |       return {
 92 |         isError: true,
 93 |         content: [
 94 |           {
 95 |             type: 'text' as const,
 96 |             text: `Error extracting components: ${error.message}`,
 97 |           },
 98 |         ],
 99 |       }
100 |     }
101 |   }
102 | )
103 | 
104 | server.tool(
105 |   'extract-latest-components',
106 |   'Extract newly added components from Figma file',
107 |   async (extra) => {
108 |     try {
109 |       // Fetch Figma file data
110 |       logger.info('Fetching Figma file data...')
111 | 
112 |       // const data = await response.json()
113 |       const data = await fetchFigmaData()
114 |       logger.info('Successfully fetched Figma file data')
115 | 
116 |       // Process the component data
117 |       const result = await generateComponent(data, true)
118 |       logger.info('Component extraction successful')
119 | 
120 |       // Return the result to the client
121 |       return {
122 |         // componentsData: result.componentSets, // Pass the structured component data
123 |         content: [
124 |           {
125 |             type: 'text' as const,
126 |             text: result.message,
127 |           },
128 |         ],
129 |       }
130 |     } catch (error: any) {
131 |       logger.error('Error extracting components:', error)
132 |       return {
133 |         isError: true,
134 |         content: [
135 |           {
136 |             type: 'text' as const,
137 |             text: `Error extracting components: ${error.message}`,
138 |           },
139 |         ],
140 |       }
141 |     }
142 |   }
143 | )
144 | 
145 | server.tool(
146 |   'extract-one-component',
147 |   'Extract a single component from Figma file',
148 |   {
149 |     parameters: z.object({
150 |       componentName: z.string(),
151 |     }),
152 |   },
153 |   async ({ parameters: { componentName } }, extra) => {
154 |     try {
155 |       // Fetch Figma file data
156 |       logger.info('Fetching Figma file data...')
157 | 
158 |       // const data = await response.json()
159 |       const data = await fetchFigmaData()
160 |       logger.info('Successfully fetched Figma file data')
161 | 
162 |       // Process the component data
163 |       const result = await generateComponent(data, true, componentName)
164 |       logger.info('Component extraction successful')
165 | 
166 |       // Return the result to the client
167 |       return {
168 |         componentsData: result.componentSets, // Pass the structured component data
169 |         content: [
170 |           {
171 |             type: 'text' as const,
172 |             text: result.message,
173 |           },
174 |         ],
175 |       }
176 |     } catch (error: any) {
177 |       logger.error(`Error extracting component ${componentName}:`, error)
178 |       return {
179 |         isError: true,
180 |         content: [
181 |           {
182 |             type: 'text' as const,
183 |             text: `Error extracting component ${componentName}: ${error.message}`,
184 |           },
185 |         ],
186 |       }
187 |     }
188 |   }
189 | )
190 | 
191 | async function runServer() {
192 |   // Start the server with stdio transport
193 |   const transport = new StdioServerTransport()
194 |   await server.connect(transport)
195 | }
196 | 
197 | runServer().catch(console.error)
198 | 
```