Building Figma's MCP Server: Architecture and Evals
AI Engineergo watch the original →
the gist
Figma built an MCP server to bridge design and code by serializing scene graphs into React and Tailwind, using LLM-based evals to iterate on output quality and Code Connect to maintain enterprise-grade component fidelity.
Scene Graph Representation and Context Management
Figma represents its canvas as a C++ scene graph, similar to an HTML DOM. To make this accessible to LLMs, the team evaluated three representation strategies: abstract JSX-like tags, React and Tailwind code, and raw images. They selected React and Tailwind because models are heavily trained on these patterns, enabling pixel-perfect output. They explicitly abandoned passing base64 images directly into the context window, as it caused excessive token consumption and poor conversion results. Instead, they use images as secondary context alongside the code to improve agentic reasoning.
Scaling Quality with LLM Judges
Early attempts at evaluating output quality involved manual grading in spreadsheets, which proved unsustainable. The team shifted to an automated evaluation pipeline where LLM judges grade outputs based on quantitative metrics, such as correct variable usage and theming, and qualitative assessments of decision-making. This system now runs hundreds of times per week, allowing engineers to iterate on prompts and architecture with immediate feedback.
Enterprise Fidelity via Code Connect
Pixel-perfect generation is insufficient for enterprise use cases that require adherence to existing design systems, accessibility standards, and internationalization. Figma integrated their existing Code Connect feature to solve this. Instead of generating raw markup, the MCP server sends pointers to the user's actual codebase components. This reduces context window usage and ensures the generated code utilizes the organization's battle-tested, accessible components rather than generic UI elements.
Navigating Spec Volatility and Client Support
During development, the team faced significant challenges due to the evolving MCP specification and uneven client support. When the spec deprecated their chosen transport (server events), they had to pivot their architecture. Because client support for features like elicitation and sampling was inconsistent, they implemented workarounds using tool calls to mimic these behaviors. For instance, when a component was not mapped, they used tool-based prompts to ask the user for permission to scan the codebase and suggest mappings, effectively bridging gaps in the official client implementations.