analyze_page_structure
Analyze Figma page structure to identify sections, estimate token usage, and recommend optimal agent allocation for parallel implementation work.
Instructions
Analyze page structure BEFORE any implementation.
MUST BE CALLED FIRST for any large page/frame.
HOW IT WORKS:
Identifies sections by background color changes
Detects transition elements spanning multiple sections
Groups icons by section
Estimates token usage
Recommends agent count for parallel work
RETURNS:
sections: List with id, name, bgColor, bounds, complexity
transition_elements: Elements spanning multiple sections
icons_by_section: Icons organized by section
total_estimated_tokens: Token estimate for full frame
recommended_division: 'single' or 'multiple'
recommended_agent_count: How many agents to use
TYPICAL WORKFLOW:
analyze_page_structure → understand structure
If recommended_division='multiple': use get_section_screenshot
Each agent uses get_agent_context for its section
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| file_key | Yes | Figma file key from URL | |
| page_name | Yes | Page name (partial match) | |
| frame_name | Yes | Frame name (partial match) |
Implementation Reference
- Main handler function that analyzes Figma page structure: identifies sections by background changes, detects transitions, groups assets, estimates tokens, and recommends implementation strategy.export async function analyzePageStructure(ctx, fileKey, pageName, frameName) { const { session, chunker, figmaClient } = ctx; session.setCurrentFile(fileKey); const file = await figmaClient.getFile(fileKey, 3); const page = figmaClient.findPageByName(file, pageName); if (!page) { const available = file.document.children.map((p) => p.name).join(", "); throw new Error(`Page "${pageName}" not found. Available: ${available}`); } const frameRef = figmaClient.findFrameByName(page, frameName); if (!frameRef) { const available = (page.children || []) .filter((c) => c.type === "FRAME" || c.type === "COMPONENT") .map((f) => f.name) .join(", "); throw new Error(`Frame "${frameName}" not found. Available: ${available}`); } const frame = await figmaClient.getNode(fileKey, frameRef.id); const frameChildren = frame.children || []; const sectionGroups = groupNodesBySection(frameChildren); const sections = sectionGroups.map((sectionGroup, idx) => { const firstNode = sectionGroup.nodes[0]; const inferredName = inferSectionName(firstNode.name) || `Section ${idx + 1}`; const sectionBounds = { x: Math.round(sectionGroup.minY), y: Math.round(sectionGroup.minY), width: frame.absoluteBoundingBox?.width || 0, height: Math.round(sectionGroup.maxY - sectionGroup.minY), }; const childCount = sectionGroup.nodes.reduce((sum, node) => sum + countElements(node), 0); return { id: `section-${idx}`, name: inferredName, bgColor: sectionGroup.bgColor || "#FFFFFF", bounds: sectionBounds, complexity: childCount <= 10 ? "low" : childCount <= 30 ? "medium" : "high", childCount: childCount, }; }); const iconsBySection = {}; const imagesBySection = {}; for (let i = 0; i < sectionGroups.length; i++) { const { icons, images } = extractIconsAndImages(sectionGroups[i], `section-${i}`); if (icons.length > 0) iconsBySection[`section-${i}`] = icons; if (images.length > 0) imagesBySection[`section-${i}`] = images; } const transitionElements = findTransitionElements(sectionGroups, frameChildren); const totalTokens = estimateTokens(frame); const recommendedDivision = sections.length > 3 || totalTokens > 20000 ? "multiple" : "single"; const recommendedAgentCount = Math.min(sections.length, Math.ceil(sections.length / 2)); const result = { frame: frame.name, sections, transitionElements, iconsBySection, imagesBySection, totalEstimatedTokens: totalTokens, recommendedDivision, recommendedAgentCount, }; const response = chunker.wrapResponse(result, { step: "Analyzed page structure", progress: `${sections.length} sections identified`, nextStep: recommendedDivision === "multiple" ? `Use get_section_screenshot or get_agent_context for parallel work (${recommendedAgentCount} agents)` : "Use get_frame_info for full frame details", strategy: `Recommended: ${recommendedDivision} mode with ${recommendedAgentCount} agent${recommendedAgentCount > 1 ? 's' : ''}`, }); return { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] }; }
- src/tools/schemas.js:265-307 (schema)Tool schema definition including name, description, input schema with file_key, page_name, frame_name parameters.name: "analyze_page_structure", description: `Analyze page structure BEFORE any implementation. MUST BE CALLED FIRST for any large page/frame. HOW IT WORKS: - Identifies sections by background color changes - Detects transition elements spanning multiple sections - Groups icons by section - Estimates token usage - Recommends agent count for parallel work RETURNS: - sections: List with id, name, bgColor, bounds, complexity - transition_elements: Elements spanning multiple sections - icons_by_section: Icons organized by section - total_estimated_tokens: Token estimate for full frame - recommended_division: 'single' or 'multiple' - recommended_agent_count: How many agents to use TYPICAL WORKFLOW: 1. analyze_page_structure → understand structure 2. If recommended_division='multiple': use get_section_screenshot 3. Each agent uses get_agent_context for its section`, inputSchema: { type: "object", properties: { file_key: { type: "string", description: "Figma file key from URL", }, page_name: { type: "string", description: "Page name (partial match)", }, frame_name: { type: "string", description: "Frame name (partial match)", }, }, required: ["file_key", "page_name", "frame_name"], }, },
- src/index.js:69-71 (registration)Registration in the main MCP server request handler switch statement, mapping tool name to the analyzePageStructure handler.case "analyze_page_structure": result = await handlers.analyzePageStructure(this.ctx, args.file_key, args.page_name, args.frame_name); break;
- src/tools/handlers/index.js:8-8 (registration)Re-export of the handler function for use in the main index.js dispatch.export { analyzePageStructure } from "./pageStructure.js";