UNPKG

@mseep/mcp-figma-to-code

Version:

MCP server for converting Figma designs to React Native components

156 lines (155 loc) 5.48 kB
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { z } from 'zod'; import { generateComponent } from './helpers/extractComponent.js'; import { fetchFigmaData } from './helpers/index.js'; // Load environment variables const logger = { info: (message, meta) => { console.error(`[INFO] ${message}`, meta ? JSON.stringify(meta) : ''); }, error: (message, error) => { console.error(`[ERROR] ${message}`, error instanceof Error ? error.stack : error); }, warn: (message, meta) => { console.error(`[WARN] ${message}`, meta ? JSON.stringify(meta) : ''); }, }; // Get environment variables const FIGMA_TOKEN = process.env.FIGMA_TOKEN; const FIGMA_FILE = process.env.FIGMA_FILE; const PROJECT_DIR = process.env.PROJECT_DIR; if (!FIGMA_TOKEN || !FIGMA_FILE || !PROJECT_DIR) { console.error('Missing required environment variables FIGMA_TOKEN or FIGMA_FILE or PROJECT_DIR'); process.exit(1); } // Create MCP server with explicit capabilities const server = new McpServer({ name: 'Figma Component Extractor', version: '1.0.0', }, { capabilities: { tools: {}, }, }); // Tool to extract components from Figma file server.tool('extract-components', 'Extract all components from Figma file and get all graphql queries and mutations', async (extra) => { try { // Fetch Figma file data logger.info('Fetching Figma file data...'); const response = await fetch(`https://api.figma.com/v1/files/${FIGMA_FILE}`, { headers: { 'X-Figma-Token': FIGMA_TOKEN, }, }); if (!response.ok) { const errorText = await response.text(); throw new Error(`Failed to fetch Figma file: ${response.status} ${response.statusText} - ${errorText}`); } const data = await response.json(); logger.info('Successfully fetched Figma file data'); // Process the component data const result = await generateComponent(data); logger.info('Component extraction successful'); // Return the result to the client return { // componentsData: result.componentSets, // Pass the structured component data content: [ { type: 'text', text: result.message, }, ], }; } catch (error) { logger.error('Error extracting components:', error); return { isError: true, content: [ { type: 'text', text: `Error extracting components: ${error.message}`, }, ], }; } }); server.tool('extract-latest-components', 'Extract newly added components from Figma file', async (extra) => { try { // Fetch Figma file data logger.info('Fetching Figma file data...'); // const data = await response.json() const data = await fetchFigmaData(); logger.info('Successfully fetched Figma file data'); // Process the component data const result = await generateComponent(data, true); logger.info('Component extraction successful'); // Return the result to the client return { // componentsData: result.componentSets, // Pass the structured component data content: [ { type: 'text', text: result.message, }, ], }; } catch (error) { logger.error('Error extracting components:', error); return { isError: true, content: [ { type: 'text', text: `Error extracting components: ${error.message}`, }, ], }; } }); server.tool('extract-one-component', 'Extract a single component from Figma file', { parameters: z.object({ componentName: z.string(), }), }, async ({ parameters: { componentName } }, extra) => { try { // Fetch Figma file data logger.info('Fetching Figma file data...'); // const data = await response.json() const data = await fetchFigmaData(); logger.info('Successfully fetched Figma file data'); // Process the component data const result = await generateComponent(data, true, componentName); logger.info('Component extraction successful'); // Return the result to the client return { componentsData: result.componentSets, // Pass the structured component data content: [ { type: 'text', text: result.message, }, ], }; } catch (error) { logger.error(`Error extracting component ${componentName}:`, error); return { isError: true, content: [ { type: 'text', text: `Error extracting component ${componentName}: ${error.message}`, }, ], }; } }); async function runServer() { // Start the server with stdio transport const transport = new StdioServerTransport(); await server.connect(transport); } runServer().catch(console.error);