Jesse Lumarie built Figma's first MCP server as a one-day-a-week project, then launched a local version before the MCP specification and client support had settled.
2
Figma chose React and Tailwind as its main scene-graph representation because the team expected models to have seen a great deal of code in that format, then added images as supporting context.
3
Pixel-perfect generated code was insufficient for enterprise users, so Code Connect lets the server point agents toward existing accessible and internationalized components in a codebase.
Summary
Jesse Lumarie describes how Figma built and shipped its first MCP server in about three months while the protocol and client ecosystem were changing. He began the work as a one-day-a-week project after seeing an internal demo and wanting non-designers to use Figma through AI tools. The team had to handle a deprecated transport, uneven client support, and incomplete implementations of MCP features. Figma represented its scene graph with React and Tailwind because the team suspected models had seen more examples in that format. Images helped when paired with code, but inline base64 data made the context too large. The team moved from manual eval grading to an automated web app with LLM judges. Code Connect addressed a deeper problem: enterprise teams need their own tested, accessible, internationalized components, even when generated output looks pixel perfect. Figma launched locally first for speed and enterprise privacy, then added a remote server and later read and write capabilities.
A one-day-a-week experiment became Figma's first MCP server
Jesse Lumarie started building a Figma plug-in based MCP server after seeing an internal demo and wanting non-designers to use Figma. Figma did not have formal 20% projects, but he worked on it one day a week anyway. Other people later joined the effort, and Jesse stresses that a larger team built the product. The initial goal was practical: let AI tools move context between production code and design without requiring every tool to build its own dedicated Figma integration. The project began before MCP had broad support from AI agents and labs, so the team was exploring both the protocol and the product at the same time.
The team had to build while clients and the protocol changed
A few weeks after the initial architecture work, a new MCP specification deprecated the server-events transport the team planned to use. Client support also arrived at different speeds. Claude Desktop had early support, while Claude Code, OpenAI products, and VS Code had incomplete or delayed support. In many cases, clients supported tools but not the rest of the specification. Jesse calls VS Code the eventual golden client because it supported more of the specification, but the uneven support made it difficult to know what the server should target. The team continued because they believed MCP would enable a useful product even before the details settled.
The local server brought Figma's developer context into coding agents
Figma launched its local MCP server for developer workflows. A developer could use a prompt such as "help me implement this" and pull into a coding agent the information they normally received from Figma's Dev Mode. That included component data, spacing, and variables. The team then added read tools for products such as FigJam and Make. The shared purpose was to make Figma context available to developers wherever they worked. The local design also suited enterprises because their data did not need to be sent elsewhere. Developers were the first target because they were adopting AI workflows early.
React and Tailwind gave the scene graph a model-friendly form
Figma's canvas is a scene graph in C++, made of connected nodes that Jesse compares with the HTML DOM. The team considered an internal JSX- or XML-like representation, a React and Tailwind representation, and plain images. The internal format was abstract and sparse but did not have enough fidelity. Figma already had a way to convert its scene graph into HTML through its Sites product, so the team used that experience for the React and Tailwind output. They chose it partly on a hunch that models had seen a lot of code in that format. Jesse says the result should be pixel perfect when pasted into a simple HTTP server.
Images helped only when paired with code, and base64 was too expensive
In early 2025, agents were not good enough at turning images directly into HTML or CSS, so Figma treated images as extra context rather than the sole representation. The server passed an image of the current node alongside the React and Tailwind code. That combination produced better agent output than either source alone. The first attempt embedded image data as base64 inside the code, which expanded the context window and caused the content to be cut off. Figma instead abstracted images from the scene graph and placed them at the top level. Jesse's advice is direct: embedding base64 image data in this way was a bad idea.
Automated evals replaced a painful spreadsheet process
The team evaluated outputs with quantitative checks and human judgment. They checked whether generated code used variables, applied the expected theme, and used the right spot. People also judged whether the result looked good and whether the agent made sensible decisions when information was incomplete. After spending about two hours grading one eval in an Excel spreadsheet, the team decided not to repeat the process. They created toy repositories, then built a web app to make evaluation easier. Because Figma files are harder to find in open-source repositories than code, they had to create files or find other ways to build automated tests. The current eval runs hundreds of times a week, with LLM judges grading prompt changes.
Pixel-perfect markup still fails when it ignores the codebase
Jesse says pixel-perfect React and Tailwind output is only half the problem for enterprise users. A company may already have accessible and internationalized components that it expects every generated interface to use. Figma's Code Connect links design components to components in a codebase. The MCP server uses those links so an agent can select the real component instead of generating a visually similar button in raw markup. This both preserves existing behavior and reduces context size. The representation changes from a large block of React and Tailwind to a small pointer such as "use button component." The result is closer to the user's actual implementation and design system.
Missing MCP features were approximated with tool calls
Figma wanted to combine elicitation, which asks the user for input, with sampling, which lets a server query the client's language model. The intended workflow was to ask whether the user wanted to map components in a codebase, have an agent find possible matches, and create Code Connect links. Client implementations were too incomplete for that design. Even when VS Code supported sampling, the query was general rather than specific to the user's codebase. Figma worked around the gap with tools. When a selected Figma component lacked a Code Connect link, the server sent a prompt asking whether the user wanted to map it. A second prompt asked the agent to scan the code, and the returned matches were sent back in bulk. Jesse also recommends the open-source MCP Inspector for server development.
Figma shipped local first, then moved to a remote server
Before its beta, the team wanted to launch quickly, maintain a high security bar, respect file permissions, and avoid pricing or packaging abuse vectors. When the MCP specification introduced OAuth in March 2025, Figma had to choose between staying local and taking on the work of a remote server using streamable HTTP. It kept the local architecture first because authentication support was not ready and Figma could relay authentication through its web and desktop applications. The desktop app is built with Electron, runs figma.com in its front end, and uses an IPC bridge to a Node process that can access the user's file system. Figma launched the remote server in September, merged both servers in October 2025, and later added read and write capabilities.
"Our first attempt was just passing B64 data into the code and that was just a terrible idea. It just blew up the context window and was bad all around."05:09
Who should watch
You are building an MCP server while the protocol and client support are still changing, and you need practical choices for shipping before the ecosystem settles.
Your design-to-code system produces attractive output but does not reliably use the components, accessibility behavior, or internationalization already present in customers' codebases.
You are still grading agent outputs by hand and want an example of how to move toward repeatable evals with automated checks and LLM judges.