AI Engineer World's Fair 2026
Building the Engine While Flying the Plane: Launching the Figma MCP Server — Jesse Lumarie, Figma
Read the talk
Building the Engine While Flying the Plane: Launching the Figma MCP Server
Jesse Lumarie traces how a one-day-a-week experiment became Figma’s first MCP server—through a changing protocol, tight context budgets, design-to-code representation choices, automated evaluations, and a local-first architecture.
From a talk by Jesse Lumarie
At a glance
Ideas worth remembering
Choose an agent representation by balancing fidelity with context cost. React and Tailwind provided structure models could use, while a rendered image supplied supporting visual context.
Do not inline Base64 assets into model context when references will do; the encoding can consume the window before the useful design information arrives.
Pixel-perfect generated markup is insufficient for enterprise code. Code Connect points agents to existing accessible, internationalized components while reducing serialized output.
Turn subjective manual review into repeatable evaluation infrastructure, but build paired test data that reflects the actual design-and-code task.
When MCP clients implement only part of the protocol, ordinary tool calls can temporarily emulate richer flows. Compatibility—and the deprecation of desired features such as sampling—becomes part of the product architecture.
Local-first deployment reused Figma’s Electron authentication and IPC path, reached users quickly, and bought time to build the remote OAuth architecture from real product feedback.
A side project meets a moving protocol
Figma’s MCP server began with a practical integration problem: coding agents needed design context, but requiring every AI tool to build a dedicated Figma integration would fragment the experience. An MCP server could provide a common path between production code and design. Jesse Lumarie, a Figma software engineer, started exploring that path after seeing an internal demo and imagining how non-designers might use Figma through their existing AI tools. 0:13
The work started as a plugin-based prototype built one day a week—“a twenty percent project” at a company that did not formally have them. It soon gained a broader team, jokingly called the “MC Peeps,” and became Figma’s first MCP server in about three months. The project did not begin with a settled product specification or stable ecosystem; it began with enough of a working demo to make the opportunity concrete. 1:13
A few weeks into architecture work, the ground moved. A protocol update deprecated the server-sent events transport the team intended to use, while MCP clients adopted different parts of the specification at different speeds. Some supported tools but not the rest of the protocol; even clients with early support lacked complete feature coverage. VS Code eventually became the closest thing to a “golden client,” but there was no single compatibility target the server could safely assume. 1:43
Figma still chose to build. The first local server deliberately targeted developers, who were already adopting coding agents and could tolerate setup complexity. A prompt such as “Help me implement this” could pull component data, spacing variables, and other information normally found in Figma Dev Mode into the coding workflow. Later tools expanded the available context for products including FigJam and Make, but the shared goal remained simple: make Figma context available where developers already work. 2:43
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Choosing a language models could use for the canvas
Figma’s canvas is represented as a scene graph in C++: connected nodes analogous to the HTML DOM. Sending that graph to an agent required a representation that preserved enough structure and appearance without wasting the context window. Three candidates exposed different tradeoffs:
- Sparse JSX/XML-like structure: Compact and abstract, but without rigorous visual fidelity.
- React and Tailwind: Figma already had machinery for converting scene graphs into HTML, and the team suspected models would handle this familiar code particularly well.
- A plain image: Visually direct, but agents in early 2025 were not reliable enough at converting an image alone into HTML, CSS, or another implementation language. 3:42
The team chose React and Tailwind on a hunch: models had likely encountered large amounts of similar code during training and post-training. The serialized output could be placed in a simple HTTP server and should reproduce the frame pixel for pixel. That was a stronger fidelity target than the sparse internal representation could offer, although the talk provides no comparative benchmark proving that training-data familiarity caused the result.
Images still helped as secondary context. A concrete frame could be sent as React/Tailwind structure plus a rendered image of the selected node. The code told the agent what elements and styles existed; the image showed how the composition should look. Together they produced better output than the image alone.
The first attempt at embedding image assets exposed the cost of a naive representation. Inlining Base64 image data inside the serialized code rapidly consumed the context window and could cause useful content to be cut off. The fix was to extract images from the scene graph and place references at the top level. Visual fidelity did not justify sending bulky binary encodings through a language model’s text context. 5:12
The comparison below answers a concrete design question: which representation gives an agent useful structure without discarding appearance or exhausting context? React and Tailwind became the primary serialization, while the rendered image remained supporting evidence.
Three representations of a Figma scene graph
Read the diagram as text
- C++ scene graph. source — Connected canvas nodes analogous to a DOM.
- JSX/XML-like representation. candidate — Sparse and abstract, with weaker fidelity.
- React + Tailwind. selected — Familiar code representation capable of pixel-perfect rendering.
- Plain image. candidate — Useful visual context, but insufficient by itself for reliable code conversion.
- C++ scene graph → JSX/XML-like representation: serialize sparsely.
- C++ scene graph → React + Tailwind: convert toward HTML.
- C++ scene graph → Plain image: render visually.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Pixel perfect is only half the job
“Better” needed an operational definition. The first evaluations mixed checks that could be counted with judgments that required taste:
- Quantitative checks: Did the implementation use the expected variables, theme, and placement?
- Qualitative checks: Did it look good, and did the agent make sensible decisions when information was incomplete? 5:42
The team spent about two hours grading one evaluation in an Excel spreadsheet and immediately decided not to repeat the experience. A web application made the review process easier, but test data remained a deeper constraint. Open-source repositories are plentiful; repositories paired with the corresponding Figma files are not. Figma therefore had to create toy repositories or assemble its own paired examples before automation could run over realistic design-to-code tasks.
The resulting evaluation now runs hundreds of times a week. Engineers can trigger it when prompts change, and LLM judges grade cases where human review is unnecessary. This converts a painful occasional spreadsheet exercise into a repeatable development loop, though the talk does not describe how those judges were calibrated against human decisions. 6:42
Visual reproduction then revealed a more important limitation. An enterprise does not merely need a generated button that looks right; it needs the organization’s existing button, with its tested accessibility, internationalization, behavior, and maintenance path. Reproducing that component as fresh React and Tailwind code can be visually accurate while bypassing the real design system. It also wastes context by describing implementation details the codebase already contains.
Code Connect supplied the missing link by associating a Figma design component with its implementation in the user’s codebase. For a primary button, the MCP response could replace a large block of generated markup with a sparse pointer meaning, in effect, “use the button component.” The agent then imports or invokes the real component instead of rebuilding an imitation. That raises implementation fidelity while reducing the amount of context sent. 8:12
The flow below answers why less generated markup can produce a better implementation. The sparse pointer resolves to maintained production code, so the visible button keeps the codebase’s accessibility and internationalization behavior rather than merely copying its appearance.
From design node to production component
Read the diagram as text
- Figma button node. design — The selected design component and its properties.
- React/Tailwind reconstruction. fallback — Pixel-perfect markup, but verbose and detached from the existing design system.
- Code Connect mapping. mapping — Links the Figma component to its codebase implementation.
- Sparse component pointer. output — Tells the agent to use the existing button component.
- Production button. codebase — Retains established accessibility and internationalization behavior.
- Figma button node → React/Tailwind reconstruction: serialize appearance.
- Figma button node → Code Connect mapping: identify mapped component.
- Code Connect mapping → Sparse component pointer: return sparse reference.
- Sparse component pointer → Production button: resolve in codebase.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
When clients lacked the protocol feature, tools carried the workflow
Once serialization was working, the server’s limits increasingly came from clients rather than Figma. A March 2025 compatibility matrix showed different hosts implementing different subsets of MCP. Resources could provide help articles and instructions directly to an agent, avoiding an error-first loop in which the agent spent another inference call diagnosing what went wrong. Server instructions existed in the specification, but clients initially did not implement them, so Figma repeated usage guidance inside individual tool calls. 9:25
Two desired capabilities were especially useful together. Elicitation lets a server ask the user a question and receive the answer. Sampling let the server ask the client’s language model to perform a small query, although sampling had been deprecated by the time described here. Combined conceptually, the two capabilities could establish Code Connect mappings: ask the user for permission, have the agent inspect the codebase for likely component matches, and return those suggestions to the server.
Most clients did not support that complete flow, and even a client with sampling support might expose only a general agent rather than one grounded in the current codebase. Figma recreated the interaction with ordinary tools. When get design context encountered an unmapped Figma component, the tool response prompted the agent to ask whether the user wanted to connect it. If the user agreed, a second prompt instructed the agent to scan the repository for possible matches. The agent formatted those suggestions and sent them back in bulk, allowing several mappings to be created together. 11:25
The workaround below separates the hidden control-flow steps. Tool responses temporarily carry what richer protocol support was meant to standardize: request permission, search the repository, format candidates, and create mappings. The user still approves the operation before the agent scans the codebase.
For server developers, Lumarie strongly recommends the open-source MCP Inspector. Figma used its interface to inspect the server interaction shown during this workflow, and he describes skipping it as “doing yourself a disservice.”
Figma also added optional arguments to tool calls such as get design context, asking the agent to report the user’s language and framework. This supplied a rough signal about whether React/Tailwind serialization worked for codebases using other frameworks such as Svelte. The limitation was explicit: “agents lie.” Self-reported framework information could guide investigation, but it could not serve as reliable telemetry by itself. 12:25
Emulating elicitation and sampling with tool responses
Read the diagram as text
- Unmapped Figma component. server — Design context reveals that the component lacks a Code Connect mapping.
- Ask the user. elicitation-like — A tool response prompts the agent to request permission to create a mapping.
- Scan the codebase. sampling-like — After approval, the agent searches for potential implementation matches.
- Formatted suggestions. agent — Candidate matches are returned in a specified structure.
- Bulk Code Connect mappings. server — The server creates several design-to-code links together.
- Unmapped Figma component → Ask the user: trigger prompt.
- Ask the user → Scan the codebase: user approves.
- Scan the codebase → Formatted suggestions: find candidate components.
- Formatted suggestions → Bulk Code Connect mappings: send matches back.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Launch locally, learn, then solve remote authentication
The first beta had four requirements: launch quickly, maintain a high security bar, respect file permissions, and preserve pricing and packaging so the server did not create abuse paths. A March 2025 protocol change introduced OAuth and a remote transport based on streamable HTTP, forcing a choice: stop and solve remote authentication immediately, or continue with a local server. Figma “punted” on remote and shipped local first. 12:54
The Electron desktop application made that shortcut viable. Its frontend runs the Figma web application, while an inter-process communication bridge connects the web layer to a Node process with local filesystem access. Authentication could be relayed from the web app through the desktop app, and the Node process exposed a local server-sent events endpoint that MCP clients could contact directly.
This architecture also appealed to enterprises because design data did not need to be sent to a new remote Figma service. More importantly for product development, it was the fastest route to real users. The team could test product-market fit, discover which tools mattered, and learn how developers actually used design context before finishing the harder remote authentication path. 13:54
Internal reception was “extremely honest,” which gave the team a chance to remove early rough edges. Work on the remote server started immediately after the local launch. Figma launched the remote server in September, made both servers generally available in October 2025, and then began adding read and write capabilities.
The deployment flow below explains why local was a sequencing decision rather than the final architecture. Existing desktop authentication and IPC lowered the cost of reaching users; production feedback then justified investment in OAuth, streamable HTTP, and remote access.
The local-first launch path
Read the diagram as text
- Figma web frontend. desktop — Runs inside the Electron desktop application and carries the authenticated session.
- IPC bridge. desktop — Connects the web layer to the desktop Node process.
- Local Node process. desktop — Can access the user’s filesystem and host the MCP endpoint.
- Local SSE server. local — Lets MCP clients communicate directly on the user’s machine.
- Coding clients. client — Request Figma context through the local endpoint.
- Remote server. remote — Later adds OAuth and remote access alongside the local option.
- Figma web frontend → IPC bridge: relay authentication and requests.
- IPC bridge → Local Node process: cross desktop boundary.
- Local Node process → Local SSE server: host endpoint.
- Coding clients → Local SSE server: connect locally.
- Local SSE server → Remote server: product learning precedes remote launch.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
The ending is an argument for permission to explore
The local and remote releases, followed by read and write capabilities, reportedly made the MCP server one of Figma’s fastest-growing products. No adoption figures or comparison methodology are supplied, so that characterization remains Figma’s account rather than a measured conclusion readers can independently assess. 14:59
The same exploratory pattern continued. Research suggested that some designers wanted to move into production code, but Figma lacked a dedicated product for that workflow. Lumarie began experimenting with MCP colleagues at an offsite; the work became Make in Your Local Codebase, an agentic approach to working with GitHub and local repositories.
The practical ending is that MCP remains early enough for architecture to change underneath a product while it is being built. Transports can be deprecated, clients can expose incompatible subsets, and desired features may need temporary tool-based substitutes. Waiting for the standard to settle would reduce churn, but it would also postpone the user feedback needed to discover the product. 15:57
The organizational lesson is equally concrete. Lumarie was initially staffed on neither MCP nor the later Make project. Figma gave engineers enough room to pursue promising prototypes, recruit collaborators, and turn evidence of usefulness into formal product work. The plane kept moving; the team learned to build the next piece without pretending the engine design was finished.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Resources
Related talks
- Full Spec MCP: Hidden Capabilities of the MCP Spec — Harald Kirschner, Microsoft/VS Code
Expands on the underused MCP features central to Figma’s compatibility problems, including resources, sampling, authorization, and elicitation.
- Building Protected MCP Servers
Develops the remote authorization and OAuth decisions that Figma deferred by launching its local server first.
- Build Evals That Actually Matter - Nick Ung & Akshay Sharma, Lyft
Provides a deeper treatment of production-representative test cases, LLM judges, launch gates, and evaluation scale.
Read the transcript and explore slides
Loading transcript and slides…