← All AI Engineer talks

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 Figma’s MCP Server While the Protocol Changed

Jesse Lumarie explains how Figma turned design data into useful agent context, connected generated interfaces to production components, and shipped a local server before tackling remote access.

From a talk by Jesse Lumarie

At a glance

Ideas worth remembering

  • Useful design context combines structure, visual evidence, and references to existing implementations. React and Tailwind conveyed layout, images supplemented it, and Code Connect reduced markup while directing agents toward production components.

  • Evaluation had to cover both appearance and implementation choices. Automation made prompt comparisons frequent, but paired design-and-code examples were scarce and agent-reported framework information remained an imperfect signal.

  • A feature’s presence in MCP did not ensure usable client support. Figma embedded guidance and multi-step mapping prompts in tools to reach the client agent and its codebase context.

  • Launching through the desktop app reused authentication and shortened the path to user feedback. The team then pursued remote access immediately, treating the local launch as a working foundation for further development.

From a one-day-a-week experiment to a developer tool

Figma’s first MCP server took about three months to build. Jesse Lumarie introduces it as a shared interface for exchanging context between design and production code: AI tools can use the server without each building a dedicated Figma integration. His own involvement began while he was working on growth initiatives. An internal demo suggested a way for non-designers to use Figma, so he began developing a plugin-based MCP server one day a week. Figma did not formally have 20% projects, but the experiment eventually became a larger team effort.

The infrastructure was changing underneath that work. Lumarie traces the starting point to Anthropic’s November 2024 release of the MCP specification, when support outside Anthropic was still limited. Access through Cursor helped the team move from experimentation toward a product. Then, a few weeks into architectural work, a specification update deprecated the server-events transport they had chosen. Clients also implemented different subsets of the protocol at different speeds; in many cases, tools were the only supported feature. Lumarie describes VS Code as eventually supporting the broader specification, but the team could not initially assume that a protocol feature would be available across clients.

The initial local server targeted developers because they were already adopting AI workflows. A request to implement a design could bring the information normally available in Figma’s Dev Mode—component data, spacing, and variables—into a coding agent. Additional read tools extended that approach to FigJam and Make. The consistent product goal was to make Figma context available wherever developers were working.

0:180:20
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

0:01 · section reference included

Choosing a representation the agent could use

Figma represents its canvas as a scene graph in C++: connected nodes that Lumarie compares to the HTML DOM. Giving an agent useful design context therefore required choosing a serialization of that graph. One existing internal representation resembled JSX or XML, translating nodes into tags. It was sparse and abstract, but did not preserve the level of visual fidelity the team wanted.

A second option, D2R, represented the design in React and Tailwind. Figma already had a route from scene graph to HTML through its Sites product, so this approach reused an existing capability. Lumarie says the resulting output should render pixel perfectly and treats deviations as bugs. That is an intended property of the generated representation, rather than a measured guarantee supplied in the talk. The team also had a hunch that models’ familiarity with React and Tailwind would make this representation especially effective as input.

The third option was an image alone. In the team’s early-2025 experience, agents did not translate images into HTML and CSS well enough for that to be the sole input. Images still helped when paired with code: the server supplied an image of the current node alongside its structural representation, and Lumarie reports better agent output from the combination. Embedded image assets needed separate treatment. The first attempt put base64 data directly into the code, consuming too much of the context window. The team instead extracted images from the scene graph and exposed references at the top level.

3:323:34
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

3:32 · section reference included

Making evaluation repeatable

The team initially evaluated output using both concrete checks and qualitative judgment. They asked whether an implementation used variables and the expected theming, then assessed whether it looked good and made sensible decisions when information was incomplete. These questions tested different aspects of success: following design conventions and producing a convincing result despite gaps in the input.

After spending about two hours grading an evaluation in an Excel spreadsheet, they decided to change the process. A web application made grading their toy repositories easier, but constructing useful cases was itself difficult. Open-source code was plentiful; code accompanied by corresponding Figma files was not. The team had to create its own paired material or find other ways to support automated evaluation.

By the time of the talk, engineers could launch evaluations against prompt changes using LLM judges, with runs occurring hundreds of times a week. Lumarie describes this as removing people from the loop where they were unnecessary. The account establishes a much more repeatable development process, though it does not give judge-agreement measurements or numerical output-quality results.

5:405:42
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

5:40 · section reference included

Replacing a button’s markup with the right component

A visually accurate implementation was only half the requirement. An enterprise might already have a primary button with tested accessibility and internationalization behavior. Recreating its appearance in generated markup would bypass that work. It would also spend context on describing an implementation that already existed in the repository.

Code Connect supplied the missing relationship by linking design components to components in the user’s codebase. The MCP server could then return a sparse reference—effectively a pointer to the existing implementation—in place of a large React and Tailwind expansion. In Lumarie’s button example, the context shrinks to a small component reference telling the agent to use the button component. This improves fidelity to the application’s actual component system while reducing the amount of context sent to the model.

6:587:00
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

6:58 · section reference included

Teaching clients how to use the server

With serialization established, the team explored more of MCP’s capabilities. A client compatibility matrix from March 2025 captured the practical problem: clients implemented subsets of the specification, and many features remained experimental. Resources eventually let Figma expose server guidance and help articles directly to agents. Earlier, that information had been sent with errors, leaving agents to spend additional calls and reasoning working out what had gone wrong.

Server instructions illustrated the distinction between specification support and usable client behavior. Lumarie corrects himself on this point: instructions existed in the specification, but clients initially did not implement them. Figma compensated by adding usage instructions to individual tool calls. Some clients later added support after Anthropic drew attention to the feature, but during development the team had to put guidance where clients would actually deliver it to the model.

9:069:08
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

9:06 · section reference included

Using tool responses to build component connections

Two capabilities suggested a richer workflow. Elicitation lets a server ask the user a question and receive the answer; Lumarie’s simple example asks for a name through VS Code. Sampling lets a server request an LLM response through the client. The team wanted to combine them: first ask permission to map the user’s codebase, then use the agent to find code components that could be linked to Figma designs.

Client support blocked that direct approach. Most clients lacked the required features, and even VS Code’s sampling support, as Lumarie describes it, queried a general agent without the codebase context needed for component matching. He also calls sampling deprecated, but the account does not establish whether that refers to the protocol feature or a particular implementation. The concrete limitation was that the server could not reliably ask a repository-aware agent to perform the search through sampling.

The workaround used ordinary tools to guide the client’s existing agent through the same sequence. When a design-context request revealed an unconnected component, the server returned a prompt asking the agent to offer component mapping to the user. If the user agreed, another prompt instructed the agent to scan the codebase for possible matches. The agent then presented the candidates in a specified format and returned them in bulk so the server could create the connections. This approximated elicitation and sampling while using an agent that already had access to the relevant code.

Lumarie recommends the open-source MCP Inspector as a development aid, but attributes the workflow’s value to the combination of user permission, agent-generated suggestions, and server-side mapping. Together, those steps helped users obtain better component connections without having to establish every relationship manually.

10:1610:18
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

10:16 · section reference included

Learning whether React and Tailwind traveled well

The team still needed to understand whether React and Tailwind context worked well for codebases using other technologies. Their evaluations did not settle every such case, and elicitation and sampling did not provide the feedback channel they wanted. They added optional arguments to tools such as get design context so the agent could report the user’s language and framework. Those reports helped them investigate whether a poor experience might reflect a weakness in the translation layer. Lumarie explicitly treats this as an imperfect signal: agents can report incorrect information. He says the translation worked fairly well, without supplying framework-specific measurements.

12:2612:29
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

12:26 · section reference included

Shipping locally before solving remote access

The first beta had four priorities: launch quickly, maintain a high security bar, respect file permissions, and preserve pricing and packaging boundaries to avoid abuse. Lumarie places the introduction of OAuth into the specification in March 2025. That change presented a choice between continuing with a local server and adopting a remote server over streamable HTTP, with the accompanying authentication work. The team deferred the remote option because the desktop application offered a faster route using existing authentication.

Figma’s desktop app runs its web application inside Electron. An IPC bridge connects that frontend to a Node process, which can interact with the user’s filesystem. The team relayed authentication from the web application and exposed a local server-events server in Node for MCP clients to contact. This reused an existing application boundary and let the team put the product into users’ hands quickly enough to learn which tools and use cases mattered. Enterprises also liked the local architecture’s data-handling story, though that preference does not establish where a connected AI client performs its own processing.

Internal reception exposed problems the team needed to fix, followed by more positive community feedback. Work on the remote server began immediately after the local launch. Lumarie reports a September remote launch and general availability for both servers in October 2025, followed by additional read and write capabilities. He describes the combined result as one of Figma’s fastest-growing products, an outcome the team had not anticipated; the talk does not provide adoption counts or a growth comparison.

13:1013:13
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

13:10 · section reference included

Opening production code to designers

The next experiment grew from research suggesting that designers wanted to write production code in some situations. Figma did not have a dedicated product for that need, so Lumarie began working with MCP colleagues at an offsite. That effort became Make in your local codebase, which he describes as Figma’s agent solution for working with Git, GitHub, and local repositories. It extended the work toward designers participating directly in codebase workflows.

Lumarie closes by emphasizing how early the work remains: the ecosystem is still discovering effective ways to build these interactions. He also credits the freedom to pursue ideas before they became formal assignments. He had not initially been staffed on either MCP or Make, yet helped build both because he had room to experiment and learn. His closing invitation to discuss MCP and Figma leaves that exploration open rather than presenting the server’s architecture as a finished answer.

15:1915:21
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

15:19 · section reference included

Read the complete timestamped transcript
  1. 0:01

    [music]

  2. 0:12

    All right, get started. Hi, I'm Jesse

  3. 0:15

    and I've been a software engineer at

  4. 0:17

    Figma for about three years and I'm

  5. 0:18

    going to talk to you about how we built

  6. 0:20

    Figma's first MCP server in about 3

  7. 0:22

    months. Um, and in case you don't know

  8. 0:24

    what it is, the Figma MCP server is a

  9. 0:26

    way for you to send context between

  10. 0:28

    production uh code and design and vice

  11. 0:30

    versa. AI tools don't need to build a

  12. 0:33

    dedicated integration. They can just use

  13. 0:35

    our Figma MCP and they kind of get

  14. 0:37

    started.

  15. 0:39

    So, taking you back to November 2024,

  16. 0:42

    long long time ago, Anthropic released

  17. 0:45

    the MCP server spec and uh everyone in

  18. 0:47

    the world of AI was sort of starting to

  19. 0:49

    use it and experiment with it. Um but

  20. 0:51

    outside of anthropic none of the other

  21. 0:53

    AI agents or labs were really using it.

  22. 0:55

    So OpenAI cursor VS Code they didn't

  23. 0:56

    support it yet. Um once we got access to

  24. 1:00

    the feature in cursor however uh we were

  25. 1:02

    able to kind of ideate and understand

  26. 1:04

    what it was capable of and we got

  27. 1:05

    something a little bit closer to an

  28. 1:06

    actual product and that's where my story

  29. 1:09

    begins. Um I was working on growth

  30. 1:11

    initiatives at the time and I saw our

  31. 1:13

    internal demo and I really wanted to use

  32. 1:15

    it. I thought it'd be great for

  33. 1:16

    non-designers uh to kind of be able to

  34. 1:18

    use Figma. Um, I started creating

  35. 1:20

    actually a Figma plug-in based MCP

  36. 1:22

    server and I started doing it one day a

  37. 1:24

    week. It was kind of my 20% project that

  38. 1:26

    we didn't we didn't really have 20%

  39. 1:27

    projects, but I really wanted to work on

  40. 1:29

    it, so I did. Um, and so I got staffed

  41. 1:31

    with some other folks um on the team. We

  42. 1:33

    were the MC Peeps. That's a peep. It's a

  43. 1:35

    candy if you don't know. Um, they're

  44. 1:37

    delicious. And I I just want to be very

  45. 1:39

    clear um I'm going to say I a lot and we

  46. 1:41

    there was a big team behind this so it's

  47. 1:43

    not just me and they're all fantastic.

  48. 1:45

    Um a few weeks later after we started

  49. 1:48

    getting our initial architecture sorted

  50. 1:50

    a new version of the spec dropped uh

  51. 1:51

    deprecating the support type that we

  52. 1:53

    were going to use which was server

  53. 1:54

    events and while the MCP spec was sort

  54. 1:58

    of chugging along clients were adding

  55. 2:00

    features and support in different paces.

  56. 2:02

    Uh cloud had early support cloud desktop

  57. 2:04

    but cloud code you was wasn't really

  58. 2:06

    supported uh with all the complete set

  59. 2:08

    of features. OpenAI and VS Code didn't h

  60. 2:11

    have support until that spec update and

  61. 2:13

    then it wasn't even then uh VS Code

  62. 2:15

    didn't go out of uh didn't get to G

  63. 2:17

    until July. It didn't mean that all the

  64. 2:19

    features were implemented either. There

  65. 2:21

    are lots of different pieces um and in

  66. 2:23

    many cases only tools were supported.

  67. 2:26

    VS Code was truly like the golden

  68. 2:28

    client. Uh they eventually supported

  69. 2:30

    kind of all pieces of the spec, but it

  70. 2:32

    was it was hard to kind of understand

  71. 2:34

    what you were building towards because

  72. 2:35

    clients supported so many different

  73. 2:36

    things. [snorts]

  74. 2:37

    But even though we didn't know exactly

  75. 2:39

    what the MCP server spec would be

  76. 2:41

    supported, we we knew that it would be

  77. 2:42

    extremely powerful and a great product

  78. 2:44

    uh for us to to utilize. And so we

  79. 2:45

    started building

  80. 2:47

    um and so taking a a more highle re

  81. 2:50

    recap about a year ago uh we launched

  82. 2:53

    our local MCP server. And what local

  83. 2:55

    means it was heavily designed for

  84. 2:57

    developer use cases. You kind of had to

  85. 2:59

    know what you were doing a little bit

  86. 3:00

    and we targeted developers because they

  87. 3:03

    were the first to adopt AI workflows.

  88. 3:05

    they would use a single plop prompt like

  89. 3:07

    help me implement this and a developer

  90. 3:09

    could pull everything that they would

  91. 3:10

    normally get from Figma's dev mode into

  92. 3:12

    their coding agent. This include things

  93. 3:15

    like component data, spacing, variables

  94. 3:18

    um and from there we just kept adding

  95. 3:20

    more and more re read tools like for fig

  96. 3:21

    jam for make um etc. But they all shared

  97. 3:24

    this kind of uh mutual goal to make

  98. 3:27

    Figma context available for develop

  99. 3:29

    develop developers wherever they are.

  100. 3:32

    So, Figma, if you don't know about

  101. 3:34

    Figma, um Figma is a canvas. Um and it's

  102. 3:38

    represented as a scene graph in C++.

  103. 3:41

    It's a graph of connected nodes, not

  104. 3:42

    unlike the HTML DOM. And we had a number

  105. 3:44

    of different ways we could represent the

  106. 3:46

    scene graph. We had this internal

  107. 3:48

    representation which was kind of akin to

  108. 3:50

    JSX or XML, effectively converting the

  109. 3:52

    scene graph into JSS tags and XML tags

  110. 3:55

    and passing those to the agent. It was

  111. 3:57

    abstract and sparse, but it didn't have

  112. 3:59

    super rigorous fidelity. Another option

  113. 4:02

    that we had internally was um D2R which

  114. 4:06

    is our like way of saying a react

  115. 4:08

    tailwind representation. Uh and the

  116. 4:10

    reason we had this is Figma has a sites

  117. 4:12

    product and so we already had a way of

  118. 4:14

    basically converting the scene graph

  119. 4:15

    into HTML.

  120. 4:18

    If you actually copy the output of the

  121. 4:20

    Figma MCP today and you paste into like

  122. 4:21

    a simple MCP or simple HTTP server, it

  123. 4:24

    should be pixel perfect. Um and if it's

  124. 4:26

    not, file a bug. Uh but um we had a

  125. 4:31

    hunch that this representation would be

  126. 4:33

    the best one because lots of the models

  127. 4:34

    were sort of rldled on this React

  128. 4:36

    Tailwind type of code. Um and we we had

  129. 4:39

    a suspicion that it would work really

  130. 4:40

    well. The last one that we kind of

  131. 4:42

    considered was just a plain image. But

  132. 4:44

    back in early 2025, 2025 agents weren't

  133. 4:47

    great at converting images directly to

  134. 4:49

    HTML or CSS or sort of other languages.

  135. 4:51

    And so we kind of use that as an

  136. 4:52

    additional piece of context, not as the

  137. 4:54

    sole one. And to give you what what this

  138. 4:56

    kind of looks like in practice, on the

  139. 4:58

    left here we have a a Figma frame and on

  140. 5:00

    the right we have the React Tailwind

  141. 5:03

    code. Um you can also see at the very

  142. 5:05

    top the image can crew meetup uh link.

  143. 5:09

    Uh we also basically abstract out the

  144. 5:11

    images within the code or sorry within

  145. 5:13

    the scene graph and put them at the top

  146. 5:15

    level. Our first attempt was just

  147. 5:17

    passing B 64 data into the code and that

  148. 5:20

    was just a terrible idea. It it just

  149. 5:21

    blew up the context window and was bad

  150. 5:23

    all around. um don't do that. Um we'd

  151. 5:27

    also pass an image of the current node

  152. 5:29

    to the agent as well. While the image by

  153. 5:30

    itself did not do a good job of

  154. 5:32

    converting to uh code, having the code

  155. 5:35

    context plus the image actually had

  156. 5:38

    better agentic output.

  157. 5:40

    So what do I mean by better? How did we

  158. 5:42

    know what was better? We tried to do

  159. 5:44

    evals. Um and so we did some sort of

  160. 5:46

    very simple eval to start with a mix of

  161. 5:49

    quantitative and qualitative data. Uh,

  162. 5:52

    from a quantitative standpoint, we we

  163. 5:53

    looked at did it use variables? Uh, did

  164. 5:55

    it use the theming we expected? Did it

  165. 5:57

    use the right spot? And from the

  166. 5:59

    qualitative side of things, does it look

  167. 6:01

    good? Did it make good decisions with

  168. 6:03

    incomplete information? And we spent

  169. 6:06

    like two hours grading an eval into an

  170. 6:08

    Excel spreadsheet. And we said, we're

  171. 6:09

    never we're never doing that again. It

  172. 6:11

    was awful. Don't do eval by hand if you

  173. 6:13

    can help it. Um, we had a bunch of toy

  174. 6:15

    repos that we kind of created or kind of

  175. 6:17

    had folks create for us. Um and we

  176. 6:20

    eventually ended up coding up a web app

  177. 6:23

    to sort of help us with the eval which

  178. 6:24

    made things a lot easier at least from

  179. 6:26

    like a um process perspective. One

  180. 6:28

    interesting thing is Figma um there are

  181. 6:32

    Figma files which we are converting

  182. 6:34

    there's a lot of open source code out

  183. 6:35

    there but there's not a lot of uh open-

  184. 6:37

    source code that also has fig files

  185. 6:39

    attached and so we had to either create

  186. 6:41

    our own or sort of find different ways

  187. 6:43

    to make automated systems. Um, and now

  188. 6:45

    we have a um, eval that sort of runs

  189. 6:48

    like hundreds of times a week. Engineers

  190. 6:50

    can kick this off and sort of grade

  191. 6:52

    against prompt changes um, with LLM

  192. 6:55

    judges. So, we kind of remove the human

  193. 6:56

    from the loop where we don't need it.

  194. 6:58

    Um, but having an agent translate a

  195. 7:00

    pixel uh, perfect version of code isn't

  196. 7:03

    enough. Um, I mentioned that the React

  197. 7:06

    Tailwind version of our output was pixel

  198. 7:08

    perfect. That's really only half the

  199. 7:10

    story. An enterprise doesn't care if

  200. 7:12

    it's pixel perfect if it's not using its

  201. 7:13

    like battle tested accessible and

  202. 7:15

    internationalized components. At Figma,

  203. 7:17

    we already had this concept of code

  204. 7:19

    connect which allows you to link design

  205. 7:20

    components to components in your

  206. 7:22

    codebase. We needed a way to use this

  207. 7:24

    with our MCP server so that an a an

  208. 7:26

    agent used the correct components. For

  209. 7:28

    example, this beautiful button here. Uh

  210. 7:32

    this would be a perfect representation

  211. 7:34

    if you were to throw that into an HTML

  212. 7:36

    server. But you kind of see two

  213. 7:38

    problems. um if you had a primary button

  214. 7:40

    in your codebase, you wouldn't be

  215. 7:41

    referencing it. And that's not ideal if

  216. 7:43

    it has accessibil accessibility

  217. 7:45

    properties or internationalization

  218. 7:46

    properties. And then second, um you'd

  219. 7:49

    eat up the context window. We we use Oh,

  220. 7:52

    this happened last time. Uh we use React

  221. 7:54

    Tailwind to um basically convert things

  222. 7:57

    over. Um but we want to make sure we do

  223. 8:01

    it in the sparest way possible.

  224. 8:04

    All right, just going to keep vamping a

  225. 8:06

    bit here. And so picture the same thing

  226. 8:08

    on screen. Uh but now we have like all

  227. 8:11

    this React Tailwind code. It's going to

  228. 8:12

    then be converted into sending over uh

  229. 8:15

    basically a sparse representation of it

  230. 8:17

    via code connect. Um and by connecting

  231. 8:19

    the user's code to the design, we're

  232. 8:22

    able to pass back effectively what is a

  233. 8:24

    pointer which allows the agent to use

  234. 8:26

    the code component leading to our higher

  235. 8:28

    fidelity uh implementation. So

  236. 8:30

    effectively you go from like this big

  237. 8:31

    old thing of uh react tailin to the

  238. 8:34

    small react component that just says use

  239. 8:36

    button component.

  240. 8:40

    Um all right it's going to let you

  241. 8:43

    restart it. Okay cool pause

  242. 8:47

    that.

  243. 8:55

    All right I can start talking a little

  244. 8:56

    bit about the next bit. Oh, wait. You

  245. 8:57

    can see this cool thing. You can ask

  246. 9:00

    yourself how I described it well, but

  247. 9:01

    yeah, it's basically like a React

  248. 9:02

    component that you're able to then bring

  249. 9:03

    into your code. Um, once we felt good

  250. 9:06

    about the serialization syntax, we

  251. 9:08

    started to look at what an MCB server

  252. 9:10

    can be. And the MCP spec had a lot of

  253. 9:13

    great pieces in it, but some features

  254. 9:15

    weren't quite fleshed out within

  255. 9:16

    clients, and other features we really

  256. 9:18

    wish existed. Many clients only

  257. 9:20

    implemented a subset of the spec, and

  258. 9:22

    many features were very experimental.

  259. 9:24

    This is the client compatibility matrix

  260. 9:26

    from March 2025.

  261. 9:28

    Today, for example, we expose a host of

  262. 9:31

    resources to an agent so that it can

  263. 9:33

    figure out um how to use our server as

  264. 9:35

    well as different help articles within

  265. 9:36

    Figma. Um whereas before we would send

  266. 9:39

    that information down with like an air

  267. 9:41

    for example, and the agent would have to

  268. 9:42

    call uh wasting inference and sort of

  269. 9:44

    reasoning to sort of figure out what is

  270. 9:46

    actually going wrong. Um one small part

  271. 9:49

    of the spec uh that was missing was

  272. 9:50

    server instructions. I shouldn't say

  273. 9:52

    missing from the spec. it was in the

  274. 9:53

    spec, but no clients implemented it. Um,

  275. 9:55

    and it wasn't really highlighted in the

  276. 9:57

    docs until Anthropic added a nice blog

  277. 9:59

    post uh to sort of talk about it and

  278. 10:01

    then some clients started adding it. And

  279. 10:02

    therefore, we would add uh additional

  280. 10:05

    instructions into each tool call.

  281. 10:07

    Basically instructing the LLM how to use

  282. 10:09

    our server um even though server

  283. 10:12

    descriptions weren't necessarily written

  284. 10:14

    out yet. Some other features that we

  285. 10:16

    really really wanted were elicitation

  286. 10:18

    and sampling. Um, elicitation, if you

  287. 10:21

    haven't heard of it, is a way for you to

  288. 10:23

    ask the user a question, take that

  289. 10:25

    input, and pass it back to your server.

  290. 10:27

    So, here we have it's VS Code, uh, and

  291. 10:30

    basically just asking, you know, what's

  292. 10:31

    my name? And you're able to take that

  293. 10:32

    input and pass it back, uh, to the

  294. 10:34

    server. Um, which is interesting on its

  295. 10:38

    own, but we thought in combination with

  296. 10:40

    sampling, which is unfortunately

  297. 10:41

    deprecated, but it's fine because you're

  298. 10:42

    able to work around it.

  299. 10:44

    Sampling is a way of having a server

  300. 10:48

    query the client's LLM from from our

  301. 10:51

    server and in kind of the canonical case

  302. 10:53

    was for small queries. We thought it'd

  303. 10:55

    be really useful to combine elicitation

  304. 10:56

    and sampling into a single workflow. We

  305. 10:59

    talked about how code connect improves

  306. 11:01

    users workflows quite a bit and kind of

  307. 11:03

    makes outputs a lot better. What we

  308. 11:05

    wanted to do was ask a user can we map

  309. 11:08

    out your code code base for code

  310. 11:10

    connections so that our MC MCP server

  311. 11:12

    can link them so that the output would

  312. 11:14

    be better and reduce the amount of

  313. 11:15

    context we send. Unfortunately though

  314. 11:17

    most of the clients didn't implement

  315. 11:19

    these features and didn't allow you to

  316. 11:20

    properly query the the agent in the

  317. 11:22

    context of the codebase. So for sampling

  318. 11:24

    even when VS code supported it you could

  319. 11:26

    only really query it as a general agent

  320. 11:28

    not specific to the codebase. But we

  321. 11:30

    were able to kind of hack around it

  322. 11:32

    using tools.

  323. 11:33

    When you got the context of a particular

  324. 11:35

    component or sorry of a particular

  325. 11:37

    design in Figma, if we noticed it was a

  326. 11:39

    component and that it wasn't code

  327. 11:41

    connected, we'd send down a prompt to

  328. 11:43

    ask the user if they'd want to map the

  329. 11:44

    unlink component component. Kind of

  330. 11:46

    mimicking elicitation.

  331. 11:49

    If the user said yes, we'd send down

  332. 11:51

    another prompt to have the agent scan

  333. 11:53

    the code for potential matches,

  334. 11:54

    mimicking sampling. We then service them

  335. 11:57

    in a specified format or ask the agent

  336. 11:59

    to do so and then have them send it back

  337. 12:00

    in bulk to make a bunch of code

  338. 12:02

    connections. Um the screenshot on the

  339. 12:05

    right is the MCP inspector and if you

  340. 12:07

    haven't used it and you're developing an

  341. 12:09

    MCP server, you're doing yourself a

  342. 12:10

    disservice. It's a really great tool and

  343. 12:12

    it's open source and great. Um but the

  344. 12:15

    magic in our case was combining these

  345. 12:17

    two features because we could ask the

  346. 12:19

    user for for permission. we can have the

  347. 12:21

    agent give us those suggestions and we

  348. 12:23

    can map them and in the end the users

  349. 12:24

    got a better experience. Um that's

  350. 12:26

    pretty great. Um the last sort of little

  351. 12:29

    thing that we did was we wanted to make

  352. 12:31

    our output the best it could be and we

  353. 12:33

    didn't necessarily know when we were

  354. 12:34

    starting you know we had our eval but we

  355. 12:36

    didn't know if the react tailwind code

  356. 12:38

    would be successful for other types of

  357. 12:39

    code bases. Um and outside of the

  358. 12:41

    elicitation and sampling which didn't

  359. 12:42

    really work as we wanted there was no

  360. 12:44

    way of getting that information from the

  361. 12:45

    user. So we added some optional query

  362. 12:47

    arguments to our tool calls for ones

  363. 12:49

    like get design context where they would

  364. 12:50

    send back what sort of language what

  365. 12:52

    sort of framework the user might be

  366. 12:53

    using. This is imperfect uh agents lie

  367. 12:56

    but it was at least a signal for us to

  368. 12:58

    understand like oh this type of user

  369. 13:00

    this felt user may not have had a good

  370. 13:02

    experience. Perhaps it's because our

  371. 13:04

    translation layer wasn't working as

  372. 13:05

    well. We have found that that works

  373. 13:07

    pretty well but this was kind of our way

  374. 13:08

    of verifying that.

  375. 13:10

    Um while we were working towards our

  376. 13:13

    first beta, we know we wanted four

  377. 13:15

    things. We wanted to launch quickly. Um

  378. 13:18

    we wanted to have the highest possible

  379. 13:20

    bar for our security. We wanted to

  380. 13:21

    respect file permissions. And we wanted

  381. 13:23

    to respect our pricing impact packaging

  382. 13:26

    so we didn't have abuse vectors. And so

  383. 13:28

    after the spec changed and introduced

  384. 13:30

    OOTH in March 2025, we had to decide

  385. 13:32

    whether to keep our MCP server local or

  386. 13:34

    sort of switch to the new remote server

  387. 13:36

    using streamable HTTP and kind of like

  388. 13:38

    work on all the off problems. Um we

  389. 13:41

    punted so until HMR there wasn't this

  390. 13:44

    offspec to to build from and we could

  391. 13:46

    easily relay off from our web app to our

  392. 13:48

    desktop app. So for folks who don't know

  393. 13:50

    the Figma desktop app is Electron and so

  394. 13:53

    the front end of it is a web app and we

  395. 13:55

    basically just run figma.com in that and

  396. 13:57

    then we have an um IPC uh bridge between

  397. 14:01

    the two and that sends it to our node

  398. 14:02

    process that allows us to talk to the

  399. 14:04

    user's file system. Um we then sort of

  400. 14:06

    expose a server events server in node

  401. 14:10

    and that way clients could talk directly

  402. 14:11

    locally. The local story was also really

  403. 14:13

    great with enterprises because they kind

  404. 14:15

    of like the idea of our data not being

  405. 14:16

    sent anywhere. Um, this architecture was

  406. 14:19

    our fastest path to getting something

  407. 14:21

    into the hands of users to understand

  408. 14:22

    product market fit and what kind of

  409. 14:24

    tools and use cases folks had.

  410. 14:28

    Um, we launched the MCP server

  411. 14:30

    internally and the reception was

  412. 14:33

    extremely honest. Um, we [laughter]

  413. 14:36

    uh but we we worked out a lot of the

  414. 14:38

    kinks and we started to get some really

  415. 14:39

    positive feedback in the community um

  416. 14:41

    from from a bunch of nice folks. Um, but

  417. 14:44

    launching this part was just the

  418. 14:45

    beginning. Um we had a lot of

  419. 14:47

    improvements that we wanted to make and

  420. 14:48

    we immediately started working on the

  421. 14:49

    remote server as soon as we launched.

  422. 14:52

    Um clients were on different timelines

  423. 14:55

    and we were still trying to figure out

  424. 14:56

    you know where we're going but we knew

  425. 14:57

    we wanted to get the remote server out

  426. 14:59

    so that's what we worked on. Um in

  427. 15:01

    September we launched the remote server.

  428. 15:03

    We ged both servers in October 2025. Um,

  429. 15:07

    and then we started adding read and

  430. 15:09

    write capabilities and kind of all these

  431. 15:11

    things combined ended up making for

  432. 15:13

    Figma one of the fastest growing

  433. 15:14

    products that they've ever had, which

  434. 15:15

    was not something we expected when we

  435. 15:17

    started working on this.

  436. 15:19

    Um, so late last year, I started working

  437. 15:21

    on a slightly different thing. Um, we

  438. 15:24

    started to see some research that

  439. 15:25

    designers really wanted to shift to

  440. 15:27

    writing production code in certain cases

  441. 15:29

    and we didn't really have a dedicated

  442. 15:30

    product for this. So I started hacking

  443. 15:32

    with a bunch of MCP MCP folks at an

  444. 15:34

    offsite and this eventually became

  445. 15:36

    something called make in your local

  446. 15:37

    codebase uh which is kind of Figma's

  447. 15:40

    agent solution for for working on on git

  448. 15:43

    GitHub and and local code bases. Um and

  449. 15:45

    the reason I bring this up is only

  450. 15:46

    slightly self- serving but it relates to

  451. 15:48

    this this next slide. Um if there's one

  452. 15:51

    thing you want to take away from this

  453. 15:52

    talk it's that we're so early like this

  454. 15:55

    has not been a long time. The MC MCP

  455. 15:58

    spec is only two years old and we're

  456. 16:00

    still figuring out the best way to do

  457. 16:01

    things. And then second, um, Figma's

  458. 16:05

    done a great job of letting engineers

  459. 16:06

    build and figure out, uh, what's next

  460. 16:08

    and letting them run with it run with

  461. 16:10

    it. I wasn't staffed on MCP. I wasn't

  462. 16:13

    staffed on our make product, but I ended

  463. 16:15

    up helping them be built um, just

  464. 16:17

    because I was kind of given the leeway

  465. 16:18

    to do so and learning a ton along the

  466. 16:20

    way. Um, that's all for my talk. I'll be

  467. 16:24

    around today and tomorrow, but feel free

  468. 16:25

    to reach and happy to talk about MCP,

  469. 16:27

    Figma and all that. Thanks so much for

  470. 16:28

    your time.