Skip to main content
Glama

analyze_figma_file

Analyze Figma file structure to extract node hierarchies and understand component relationships for design system documentation and development handoff.

Instructions

Analyze a Figma file structure to understand its nodes and hierarchy

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
figmaUrlYesThe URL of the Figma file to analyze
depthNoOptional depth parameter to limit the node tree depth

Implementation Reference

  • The main execution function for the analyze_figma_file tool. Extracts Figma IDs from URL, fetches and generates the node tree structure using Figma API, and returns formatted text content with the tree JSON or error message.
    async function doAnalyzeFigmaFile(figmaUrl: string, depth?: number): Promise<CallToolResult> { try { // Get Figma API Key const figmaApiKey = process.env.FIGMA_API_KEY; if (!figmaApiKey) { throw new Error('FIGMA_API_KEY not configured'); } // Extract file ID and node ID from URL const { fileId, nodeId } = extractFigmaIds(figmaUrl); if (!fileId) { throw new Error('Could not extract file ID from URL'); } if (!nodeId) { throw new Error('No node ID specified in URL'); } // Generate the node tree const treeGenerator = new FigmaTreeGenerator(figmaApiKey); const tree = await treeGenerator.generateNodeTree(fileId, nodeId, depth); // Return the result return { content: [ { type: 'text', text: `Successfully analyzed Figma file: ${figmaUrl}`, }, { type: 'text', text: `File ID: ${fileId}`, }, { type: 'text', text: `Node ID: ${nodeId}`, }, { type: 'text', text: 'Node Tree Structure:', }, { type: 'text', text: JSON.stringify(tree, null, 2), }, ], }; } catch (error) { console.error('Error analyzing Figma file:', error); // Return error as text content instead of throwing return { content: [ { type: 'text', text: `Error analyzing Figma file: ${error instanceof Error ? error.message : 'Unknown error'}` } ] }; } }
  • src/index.ts:49-71 (registration)
    Tool definition with schema and registration in the listTools handler.
    const ANALYZE_FIGMA_FILE: Tool = { name: 'analyze_figma_file', description: 'Analyze a Figma file structure to understand its nodes and hierarchy', inputSchema: { type: 'object', properties: { figmaUrl: { type: 'string', description: 'The URL of the Figma file to analyze', }, depth: { type: 'number', description: 'Optional depth parameter to limit the node tree depth', }, }, required: ['figmaUrl'], }, }; // Register tools handler server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ANALYZE_FIGMA_FILE], }));
  • src/index.ts:74-81 (registration)
    Registration of the callTool handler that dispatches to doAnalyzeFigmaFile for the analyze_figma_file tool.
    server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name === 'analyze_figma_file') { const input = request.params.arguments as { figmaUrl: string; depth?: number }; return doAnalyzeFigmaFile(input.figmaUrl, input.depth); } throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`); });
  • Supporting helper function used by the handler to extract Figma file ID and node ID from the input URL.
    export function extractFigmaIds(figmaUrl: string): { fileId: string, nodeId: string | null } { try { const url = new URL(figmaUrl); // Extract the file ID from the URL path const pathParts = url.pathname.split('/'); let fileIdIndex = -1; // Look for file/design/proto in the URL path for (let i = 0; i < pathParts.length; i++) { if (pathParts[i] === 'file' || pathParts[i] === 'design' || pathParts[i] === 'proto') { fileIdIndex = i + 1; break; } } if (fileIdIndex === -1 || fileIdIndex >= pathParts.length) { throw new Error('Invalid Figma URL format: missing file/design/proto segment'); } const fileId = pathParts[fileIdIndex]; // Extract node ID from query parameters if present const nodeId = url.searchParams.get('node-id') || null; return { fileId, nodeId }; } catch (error) { throw new Error('Invalid Figma URL format'); } }
  • Core helper class for generating and processing the Figma node tree by calling the Figma API and recursively building the hierarchy (stops at INSTANCE nodes).
    export class FigmaTreeGenerator { private readonly apiKey: string; private readonly baseUrl = 'https://api.figma.com/v1'; constructor(apiKey: string) { this.apiKey = apiKey; } async generateNodeTree(fileId: string, nodeId: string, depth?: number): Promise<FigmaNode> { try { // Construct URL with optional depth parameter let url = `${this.baseUrl}/files/${fileId}/nodes?ids=${nodeId}`; if (depth !== undefined) { url += `&depth=${depth}`; } // Make request to Figma API const response = await axios.get<FigmaNodesResponse>( url, { headers: { 'X-Figma-Token': this.apiKey } } ); // Check if the node exists in the response if (!response.data.nodes[nodeId]) { throw new Error(`Node ${nodeId} not found in file ${fileId}`); } // Extract the document from the response const nodeData = response.data.nodes[nodeId].document; // Process the node tree return this.processNode(nodeData); } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; throw new Error(`Failed to fetch Figma node tree: ${errorMessage}`); } } private processNode(node: FigmaNode): FigmaNode { // Create a new node object to avoid mutating the original const processedNode: FigmaNode = { id: node.id, name: node.name, type: node.type }; // If this is an INSTANCE node, we stop traversal here // By not adding children property, we indicate this is a terminal node if (node.type === 'INSTANCE') { return processedNode; } // If node has children, process them recursively if (node.children && node.children.length > 0) { processedNode.children = node.children.map(child => this.processNode(child)); } else { processedNode.children = []; } return processedNode; } }
Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/moonray/mcp-figma'

If you have feedback or need assistance with the MCP directory API, please join our Discord server