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.
Connected canvas nodes analogous to a DOM.
The selected representation balanced compact structure, model familiarity, and visual fidelity; the rendered image remained supporting context rather than the sole input.
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.
The selected design component and its properties.
Code Connect replaces a verbose visual reconstruction with a sparse reference to the component already maintained in the 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
Design context reveals that the component lacks a Code Connect mapping.
The workaround preserves user permission and repository-aware matching even when clients do not implement the desired MCP features.
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.
Runs inside the Electron desktop application and carries the authenticated session.
Figma reused its Electron application and existing authentication path to reach users before completing the remote server.
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 complete timestamped transcript
- 0:01
[music]
- 0:12
All right, get started. Hi, I'm Jesse
- 0:15
and I've been a software engineer at
- 0:17
Figma for about three years and I'm
- 0:18
going to talk to you about how we built
- 0:20
Figma's first MCP server in about 3
- 0:22
months. Um, and in case you don't know
- 0:24
what it is, the Figma MCP server is a
- 0:26
way for you to send context between
- 0:28
production uh code and design and vice
- 0:30
versa. AI tools don't need to build a
- 0:33
dedicated integration. They can just use
- 0:35
our Figma MCP and they kind of get
- 0:37
started.
- 0:39
So, taking you back to November 2024,
- 0:42
long long time ago, Anthropic released
- 0:45
the MCP server spec and uh everyone in
- 0:47
the world of AI was sort of starting to
- 0:49
use it and experiment with it. Um but
- 0:51
outside of anthropic none of the other
- 0:53
AI agents or labs were really using it.
- 0:55
So OpenAI cursor VS Code they didn't
- 0:56
support it yet. Um once we got access to
- 1:00
the feature in cursor however uh we were
- 1:02
able to kind of ideate and understand
- 1:04
what it was capable of and we got
- 1:05
something a little bit closer to an
- 1:06
actual product and that's where my story
- 1:09
begins. Um I was working on growth
- 1:11
initiatives at the time and I saw our
- 1:13
internal demo and I really wanted to use
- 1:15
it. I thought it'd be great for
- 1:16
non-designers uh to kind of be able to
- 1:18
use Figma. Um, I started creating
- 1:20
actually a Figma plug-in based MCP
- 1:22
server and I started doing it one day a
- 1:24
week. It was kind of my 20% project that
- 1:26
we didn't we didn't really have 20%
- 1:27
projects, but I really wanted to work on
- 1:29
it, so I did. Um, and so I got staffed
- 1:31
with some other folks um on the team. We
- 1:33
were the MC Peeps. That's a peep. It's a
- 1:35
candy if you don't know. Um, they're
- 1:37
delicious. And I I just want to be very
- 1:39
clear um I'm going to say I a lot and we
- 1:41
there was a big team behind this so it's
- 1:43
not just me and they're all fantastic.
- 1:45
Um a few weeks later after we started
- 1:48
getting our initial architecture sorted
- 1:50
a new version of the spec dropped uh
- 1:51
deprecating the support type that we
- 1:53
were going to use which was server
- 1:54
events and while the MCP spec was sort
- 1:58
of chugging along clients were adding
- 2:00
features and support in different paces.
- 2:02
Uh cloud had early support cloud desktop
- 2:04
but cloud code you was wasn't really
- 2:06
supported uh with all the complete set
- 2:08
of features. OpenAI and VS Code didn't h
- 2:11
have support until that spec update and
- 2:13
then it wasn't even then uh VS Code
- 2:15
didn't go out of uh didn't get to G
- 2:17
until July. It didn't mean that all the
- 2:19
features were implemented either. There
- 2:21
are lots of different pieces um and in
- 2:23
many cases only tools were supported.
- 2:26
VS Code was truly like the golden
- 2:28
client. Uh they eventually supported
- 2:30
kind of all pieces of the spec, but it
- 2:32
was it was hard to kind of understand
- 2:34
what you were building towards because
- 2:35
clients supported so many different
- 2:36
things. [snorts]
- 2:37
But even though we didn't know exactly
- 2:39
what the MCP server spec would be
- 2:41
supported, we we knew that it would be
- 2:42
extremely powerful and a great product
- 2:44
uh for us to to utilize. And so we
- 2:45
started building
- 2:47
um and so taking a a more highle re
- 2:50
recap about a year ago uh we launched
- 2:53
our local MCP server. And what local
- 2:55
means it was heavily designed for
- 2:57
developer use cases. You kind of had to
- 2:59
know what you were doing a little bit
- 3:00
and we targeted developers because they
- 3:03
were the first to adopt AI workflows.
- 3:05
they would use a single plop prompt like
- 3:07
help me implement this and a developer
- 3:09
could pull everything that they would
- 3:10
normally get from Figma's dev mode into
- 3:12
their coding agent. This include things
- 3:15
like component data, spacing, variables
- 3:18
um and from there we just kept adding
- 3:20
more and more re read tools like for fig
- 3:21
jam for make um etc. But they all shared
- 3:24
this kind of uh mutual goal to make
- 3:27
Figma context available for develop
- 3:29
develop developers wherever they are.
- 3:32
So, Figma, if you don't know about
- 3:34
Figma, um Figma is a canvas. Um and it's
- 3:38
represented as a scene graph in C++.
- 3:41
It's a graph of connected nodes, not
- 3:42
unlike the HTML DOM. And we had a number
- 3:44
of different ways we could represent the
- 3:46
scene graph. We had this internal
- 3:48
representation which was kind of akin to
- 3:50
JSX or XML, effectively converting the
- 3:52
scene graph into JSS tags and XML tags
- 3:55
and passing those to the agent. It was
- 3:57
abstract and sparse, but it didn't have
- 3:59
super rigorous fidelity. Another option
- 4:02
that we had internally was um D2R which
- 4:06
is our like way of saying a react
- 4:08
tailwind representation. Uh and the
- 4:10
reason we had this is Figma has a sites
- 4:12
product and so we already had a way of
- 4:14
basically converting the scene graph
- 4:15
into HTML.
- 4:18
If you actually copy the output of the
- 4:20
Figma MCP today and you paste into like
- 4:21
a simple MCP or simple HTTP server, it
- 4:24
should be pixel perfect. Um and if it's
- 4:26
not, file a bug. Uh but um we had a
- 4:31
hunch that this representation would be
- 4:33
the best one because lots of the models
- 4:34
were sort of rldled on this React
- 4:36
Tailwind type of code. Um and we we had
- 4:39
a suspicion that it would work really
- 4:40
well. The last one that we kind of
- 4:42
considered was just a plain image. But
- 4:44
back in early 2025, 2025 agents weren't
- 4:47
great at converting images directly to
- 4:49
HTML or CSS or sort of other languages.
- 4:51
And so we kind of use that as an
- 4:52
additional piece of context, not as the
- 4:54
sole one. And to give you what what this
- 4:56
kind of looks like in practice, on the
- 4:58
left here we have a a Figma frame and on
- 5:00
the right we have the React Tailwind
- 5:03
code. Um you can also see at the very
- 5:05
top the image can crew meetup uh link.
- 5:09
Uh we also basically abstract out the
- 5:11
images within the code or sorry within
- 5:13
the scene graph and put them at the top
- 5:15
level. Our first attempt was just
- 5:17
passing B 64 data into the code and that
- 5:20
was just a terrible idea. It it just
- 5:21
blew up the context window and was bad
- 5:23
all around. um don't do that. Um we'd
- 5:27
also pass an image of the current node
- 5:29
to the agent as well. While the image by
- 5:30
itself did not do a good job of
- 5:32
converting to uh code, having the code
- 5:35
context plus the image actually had
- 5:38
better agentic output.
- 5:40
So what do I mean by better? How did we
- 5:42
know what was better? We tried to do
- 5:44
evals. Um and so we did some sort of
- 5:46
very simple eval to start with a mix of
- 5:49
quantitative and qualitative data. Uh,
- 5:52
from a quantitative standpoint, we we
- 5:53
looked at did it use variables? Uh, did
- 5:55
it use the theming we expected? Did it
- 5:57
use the right spot? And from the
- 5:59
qualitative side of things, does it look
- 6:01
good? Did it make good decisions with
- 6:03
incomplete information? And we spent
- 6:06
like two hours grading an eval into an
- 6:08
Excel spreadsheet. And we said, we're
- 6:09
never we're never doing that again. It
- 6:11
was awful. Don't do eval by hand if you
- 6:13
can help it. Um, we had a bunch of toy
- 6:15
repos that we kind of created or kind of
- 6:17
had folks create for us. Um and we
- 6:20
eventually ended up coding up a web app
- 6:23
to sort of help us with the eval which
- 6:24
made things a lot easier at least from
- 6:26
like a um process perspective. One
- 6:28
interesting thing is Figma um there are
- 6:32
Figma files which we are converting
- 6:34
there's a lot of open source code out
- 6:35
there but there's not a lot of uh open-
- 6:37
source code that also has fig files
- 6:39
attached and so we had to either create
- 6:41
our own or sort of find different ways
- 6:43
to make automated systems. Um, and now
- 6:45
we have a um, eval that sort of runs
- 6:48
like hundreds of times a week. Engineers
- 6:50
can kick this off and sort of grade
- 6:52
against prompt changes um, with LLM
- 6:55
judges. So, we kind of remove the human
- 6:56
from the loop where we don't need it.
- 6:58
Um, but having an agent translate a
- 7:00
pixel uh, perfect version of code isn't
- 7:03
enough. Um, I mentioned that the React
- 7:06
Tailwind version of our output was pixel
- 7:08
perfect. That's really only half the
- 7:10
story. An enterprise doesn't care if
- 7:12
it's pixel perfect if it's not using its
- 7:13
like battle tested accessible and
- 7:15
internationalized components. At Figma,
- 7:17
we already had this concept of code
- 7:19
connect which allows you to link design
- 7:20
components to components in your
- 7:22
codebase. We needed a way to use this
- 7:24
with our MCP server so that an a an
- 7:26
agent used the correct components. For
- 7:28
example, this beautiful button here. Uh
- 7:32
this would be a perfect representation
- 7:34
if you were to throw that into an HTML
- 7:36
server. But you kind of see two
- 7:38
problems. um if you had a primary button
- 7:40
in your codebase, you wouldn't be
- 7:41
referencing it. And that's not ideal if
- 7:43
it has accessibil accessibility
- 7:45
properties or internationalization
- 7:46
properties. And then second, um you'd
- 7:49
eat up the context window. We we use Oh,
- 7:52
this happened last time. Uh we use React
- 7:54
Tailwind to um basically convert things
- 7:57
over. Um but we want to make sure we do
- 8:01
it in the sparest way possible.
- 8:04
All right, just going to keep vamping a
- 8:06
bit here. And so picture the same thing
- 8:08
on screen. Uh but now we have like all
- 8:11
this React Tailwind code. It's going to
- 8:12
then be converted into sending over uh
- 8:15
basically a sparse representation of it
- 8:17
via code connect. Um and by connecting
- 8:19
the user's code to the design, we're
- 8:22
able to pass back effectively what is a
- 8:24
pointer which allows the agent to use
- 8:26
the code component leading to our higher
- 8:28
fidelity uh implementation. So
- 8:30
effectively you go from like this big
- 8:31
old thing of uh react tailin to the
- 8:34
small react component that just says use
- 8:36
button component.
- 8:40
Um all right it's going to let you
- 8:43
restart it. Okay cool pause
- 8:47
that.
- 8:55
All right I can start talking a little
- 8:56
bit about the next bit. Oh, wait. You
- 8:57
can see this cool thing. You can ask
- 9:00
yourself how I described it well, but
- 9:01
yeah, it's basically like a React
- 9:02
component that you're able to then bring
- 9:03
into your code. Um, once we felt good
- 9:06
about the serialization syntax, we
- 9:08
started to look at what an MCB server
- 9:10
can be. And the MCP spec had a lot of
- 9:13
great pieces in it, but some features
- 9:15
weren't quite fleshed out within
- 9:16
clients, and other features we really
- 9:18
wish existed. Many clients only
- 9:20
implemented a subset of the spec, and
- 9:22
many features were very experimental.
- 9:24
This is the client compatibility matrix
- 9:26
from March 2025.
- 9:28
Today, for example, we expose a host of
- 9:31
resources to an agent so that it can
- 9:33
figure out um how to use our server as
- 9:35
well as different help articles within
- 9:36
Figma. Um whereas before we would send
- 9:39
that information down with like an air
- 9:41
for example, and the agent would have to
- 9:42
call uh wasting inference and sort of
- 9:44
reasoning to sort of figure out what is
- 9:46
actually going wrong. Um one small part
- 9:49
of the spec uh that was missing was
- 9:50
server instructions. I shouldn't say
- 9:52
missing from the spec. it was in the
- 9:53
spec, but no clients implemented it. Um,
- 9:55
and it wasn't really highlighted in the
- 9:57
docs until Anthropic added a nice blog
- 9:59
post uh to sort of talk about it and
- 10:01
then some clients started adding it. And
- 10:02
therefore, we would add uh additional
- 10:05
instructions into each tool call.
- 10:07
Basically instructing the LLM how to use
- 10:09
our server um even though server
- 10:12
descriptions weren't necessarily written
- 10:14
out yet. Some other features that we
- 10:16
really really wanted were elicitation
- 10:18
and sampling. Um, elicitation, if you
- 10:21
haven't heard of it, is a way for you to
- 10:23
ask the user a question, take that
- 10:25
input, and pass it back to your server.
- 10:27
So, here we have it's VS Code, uh, and
- 10:30
basically just asking, you know, what's
- 10:31
my name? And you're able to take that
- 10:32
input and pass it back, uh, to the
- 10:34
server. Um, which is interesting on its
- 10:38
own, but we thought in combination with
- 10:40
sampling, which is unfortunately
- 10:41
deprecated, but it's fine because you're
- 10:42
able to work around it.
- 10:44
Sampling is a way of having a server
- 10:48
query the client's LLM from from our
- 10:51
server and in kind of the canonical case
- 10:53
was for small queries. We thought it'd
- 10:55
be really useful to combine elicitation
- 10:56
and sampling into a single workflow. We
- 10:59
talked about how code connect improves
- 11:01
users workflows quite a bit and kind of
- 11:03
makes outputs a lot better. What we
- 11:05
wanted to do was ask a user can we map
- 11:08
out your code code base for code
- 11:10
connections so that our MC MCP server
- 11:12
can link them so that the output would
- 11:14
be better and reduce the amount of
- 11:15
context we send. Unfortunately though
- 11:17
most of the clients didn't implement
- 11:19
these features and didn't allow you to
- 11:20
properly query the the agent in the
- 11:22
context of the codebase. So for sampling
- 11:24
even when VS code supported it you could
- 11:26
only really query it as a general agent
- 11:28
not specific to the codebase. But we
- 11:30
were able to kind of hack around it
- 11:32
using tools.
- 11:33
When you got the context of a particular
- 11:35
component or sorry of a particular
- 11:37
design in Figma, if we noticed it was a
- 11:39
component and that it wasn't code
- 11:41
connected, we'd send down a prompt to
- 11:43
ask the user if they'd want to map the
- 11:44
unlink component component. Kind of
- 11:46
mimicking elicitation.
- 11:49
If the user said yes, we'd send down
- 11:51
another prompt to have the agent scan
- 11:53
the code for potential matches,
- 11:54
mimicking sampling. We then service them
- 11:57
in a specified format or ask the agent
- 11:59
to do so and then have them send it back
- 12:00
in bulk to make a bunch of code
- 12:02
connections. Um the screenshot on the
- 12:05
right is the MCP inspector and if you
- 12:07
haven't used it and you're developing an
- 12:09
MCP server, you're doing yourself a
- 12:10
disservice. It's a really great tool and
- 12:12
it's open source and great. Um but the
- 12:15
magic in our case was combining these
- 12:17
two features because we could ask the
- 12:19
user for for permission. we can have the
- 12:21
agent give us those suggestions and we
- 12:23
can map them and in the end the users
- 12:24
got a better experience. Um that's
- 12:26
pretty great. Um the last sort of little
- 12:29
thing that we did was we wanted to make
- 12:31
our output the best it could be and we
- 12:33
didn't necessarily know when we were
- 12:34
starting you know we had our eval but we
- 12:36
didn't know if the react tailwind code
- 12:38
would be successful for other types of
- 12:39
code bases. Um and outside of the
- 12:41
elicitation and sampling which didn't
- 12:42
really work as we wanted there was no
- 12:44
way of getting that information from the
- 12:45
user. So we added some optional query
- 12:47
arguments to our tool calls for ones
- 12:49
like get design context where they would
- 12:50
send back what sort of language what
- 12:52
sort of framework the user might be
- 12:53
using. This is imperfect uh agents lie
- 12:56
but it was at least a signal for us to
- 12:58
understand like oh this type of user
- 13:00
this felt user may not have had a good
- 13:02
experience. Perhaps it's because our
- 13:04
translation layer wasn't working as
- 13:05
well. We have found that that works
- 13:07
pretty well but this was kind of our way
- 13:08
of verifying that.
- 13:10
Um while we were working towards our
- 13:13
first beta, we know we wanted four
- 13:15
things. We wanted to launch quickly. Um
- 13:18
we wanted to have the highest possible
- 13:20
bar for our security. We wanted to
- 13:21
respect file permissions. And we wanted
- 13:23
to respect our pricing impact packaging
- 13:26
so we didn't have abuse vectors. And so
- 13:28
after the spec changed and introduced
- 13:30
OOTH in March 2025, we had to decide
- 13:32
whether to keep our MCP server local or
- 13:34
sort of switch to the new remote server
- 13:36
using streamable HTTP and kind of like
- 13:38
work on all the off problems. Um we
- 13:41
punted so until HMR there wasn't this
- 13:44
offspec to to build from and we could
- 13:46
easily relay off from our web app to our
- 13:48
desktop app. So for folks who don't know
- 13:50
the Figma desktop app is Electron and so
- 13:53
the front end of it is a web app and we
- 13:55
basically just run figma.com in that and
- 13:57
then we have an um IPC uh bridge between
- 14:01
the two and that sends it to our node
- 14:02
process that allows us to talk to the
- 14:04
user's file system. Um we then sort of
- 14:06
expose a server events server in node
- 14:10
and that way clients could talk directly
- 14:11
locally. The local story was also really
- 14:13
great with enterprises because they kind
- 14:15
of like the idea of our data not being
- 14:16
sent anywhere. Um, this architecture was
- 14:19
our fastest path to getting something
- 14:21
into the hands of users to understand
- 14:22
product market fit and what kind of
- 14:24
tools and use cases folks had.
- 14:28
Um, we launched the MCP server
- 14:30
internally and the reception was
- 14:33
extremely honest. Um, we [laughter]
- 14:36
uh but we we worked out a lot of the
- 14:38
kinks and we started to get some really
- 14:39
positive feedback in the community um
- 14:41
from from a bunch of nice folks. Um, but
- 14:44
launching this part was just the
- 14:45
beginning. Um we had a lot of
- 14:47
improvements that we wanted to make and
- 14:48
we immediately started working on the
- 14:49
remote server as soon as we launched.
- 14:52
Um clients were on different timelines
- 14:55
and we were still trying to figure out
- 14:56
you know where we're going but we knew
- 14:57
we wanted to get the remote server out
- 14:59
so that's what we worked on. Um in
- 15:01
September we launched the remote server.
- 15:03
We ged both servers in October 2025. Um,
- 15:07
and then we started adding read and
- 15:09
write capabilities and kind of all these
- 15:11
things combined ended up making for
- 15:13
Figma one of the fastest growing
- 15:14
products that they've ever had, which
- 15:15
was not something we expected when we
- 15:17
started working on this.
- 15:19
Um, so late last year, I started working
- 15:21
on a slightly different thing. Um, we
- 15:24
started to see some research that
- 15:25
designers really wanted to shift to
- 15:27
writing production code in certain cases
- 15:29
and we didn't really have a dedicated
- 15:30
product for this. So I started hacking
- 15:32
with a bunch of MCP MCP folks at an
- 15:34
offsite and this eventually became
- 15:36
something called make in your local
- 15:37
codebase uh which is kind of Figma's
- 15:40
agent solution for for working on on git
- 15:43
GitHub and and local code bases. Um and
- 15:45
the reason I bring this up is only
- 15:46
slightly self- serving but it relates to
- 15:48
this this next slide. Um if there's one
- 15:51
thing you want to take away from this
- 15:52
talk it's that we're so early like this
- 15:55
has not been a long time. The MC MCP
- 15:58
spec is only two years old and we're
- 16:00
still figuring out the best way to do
- 16:01
things. And then second, um, Figma's
- 16:05
done a great job of letting engineers
- 16:06
build and figure out, uh, what's next
- 16:08
and letting them run with it run with
- 16:10
it. I wasn't staffed on MCP. I wasn't
- 16:13
staffed on our make product, but I ended
- 16:15
up helping them be built um, just
- 16:17
because I was kind of given the leeway
- 16:18
to do so and learning a ton along the
- 16:20
way. Um, that's all for my talk. I'll be
- 16:24
around today and tomorrow, but feel free
- 16:25
to reach and happy to talk about MCP,
- 16:27
Figma and all that. Thanks so much for
- 16:28
your time.