# Figma MCP and Design-to-Code in 2026

URL: https://developertoolkit.ai/en/ecosystem/mcp/design-tools-mcp/
Description: Connect Figma's remote MCP server to Claude Code, Codex and Cursor, reuse your real components through Code Connect, and prove the build matches the frame.

The Figma MCP server is Figma's official remote server at `https://mcp.figma.com/mcp`: it gives Claude Code, Codex and Cursor a frame's layout, variables, screenshot and Code Connect mappings, and in beta it can write to the canvas. Generated code reliably reuses a team's own components when Code Connect mappings exist or the prompt names them, and a screenshot test proves the match.

A designer hands you a Figma link for the new profile page. The agent builds it in four minutes, and the pull request adds a hand-rolled button in `#4F86F7`, a `rounded-[10px]` card, and an avatar that ignores the `<Avatar />` your team maintains. Nothing is broken. Your design system has just forked, and nobody will notice until the third blue ships.

This page is for developers who implement Figma designs with an agent, and for tech leads who want those implementations to reuse the design system and pass a visual gate instead of a reviewer squinting at pixels.

## What a working Figma MCP setup gives you

- The Figma server installed in Claude Code, Codex and Cursor, as a plugin with skills or as a bare MCP server, with the seat limits you need to know first.
- A copy-paste prompt that implements a frame with your existing `Button` and `Card` components.
- A four-step design-system sync: tokens, Code Connect mappings, component generation, and a Playwright visual check.
- A verification gate that proves parity without anyone reading the generated markup line by line.
- The traps that produce plausible but wrong setups, and the recovery for each failure.

## What the Figma MCP server can do in September 2026

The server reads design data and, on the remote server only, writes it. These tools were listed by the live server connected on 2026-09-26; Figma's [tools and prompts page](https://developers.figma.com/docs/figma-mcp-server/tools-and-prompts/) keeps the full, current list.

| Tool | What it returns or does | Use it for |
| --- | --- | --- |
| `get_design_context` | A structured React + Tailwind representation of the node, plus design context | The main input for implementation; translate it to your stack |
| `get_metadata` | A sparse map of layer IDs, names, types, positions and sizes | Large frames: find the child node before a full pull |
| `get_screenshot` | An image of the node | The visual reference, and the baseline for the parity check |
| `get_variable_defs` | Variables and styles used in the selection (color, spacing, typography) | Token names instead of raw hex values |
| `get_code_connect_map` · `add_code_connect_map` | Which Figma components map to which code components | Reusing your components instead of generating new ones |
| `use_figma` · `generate_figma_design` | Create or edit frames, components, variables and auto layout | Code-to-design work (write to canvas, beta) |

Three vendor facts decide whether this works for your team (Figma, [`figma/mcp-server-guide`](https://github.com/figma/mcp-server-guide) README, read 2026-09-26):

- **Rate limits depend on the seat.** Starter plan users, and View or Collab seats on paid plans, are limited to "up to 6 tool calls per month". Dev or Full seats on Professional, Organization and Enterprise plans get per-minute limits that follow Tier 1 of the Figma REST API. Some tools, such as those that write to Figma files, are exempt.
- **Write to canvas is a beta.** It is free "during the beta period" and "will eventually be a usage-based paid feature". Do not build a team process that depends on its price.
- **Code Connect needs Organization or Enterprise.** The Code Connect README (`@figma/code-connect` 2.0.1) says it "requires a full Design or Dev Mode seat". On Starter or Professional you still get design context, but no component mappings.

**Six calls a month is not a trial**

One implementation typically calls `get_design_context`, `get_screenshot` and `get_variable_defs` at least once each, and more for a large frame. On a View or Collab seat the monthly allowance runs out on the first or second frame. Confirm the implementer has a Dev or Full seat before you plan work around the server.

## Plugin or bare MCP server?

Figma ships the server two ways. The **plugin** bundles the remote server with 14 Agent Skills (Beta), including `figma-design-to-code`, `figma-code-connect`, `figma-generate-library` and `figma-use`, which the server itself names as mandatory before any `use_figma` canvas write. The **bare server** is only the MCP connection.

| | Figma plugin | Bare MCP server |
| --- | --- | --- |
| What you get | Remote server plus 14 skills that sequence the tools | Tools only; you write the sequence into your prompts or rules |
| Always-on context cost | ~2,133 tokens per session in Claude Code (`claude plugin details`, 2026-09-26) | Tool schemas only, loaded on demand by tool search |
| Choose it when | Several people implement designs, or you write to the canvas | You only read frames, or you keep the MCP list centrally managed |

The skills are what stop the most common error: the agent writing parser-based `.figma.tsx` Code Connect files from memory when the current format is a `.figma.ts` template (see [the traps](#which-figma-mcp-instructions-are-wrong-or-stale)).

## Install the Figma MCP server in Claude Code, Codex and Cursor

The server is identical in all three tools. Only the registration differs, and all three authenticate through OAuth in the browser, so no token goes in a committed file.

New to MCP? Start with the [MCP overview](/en/ecosystem/mcp/) and your tool's MCP setup page ([Claude Code](/en/claude-code/quick-start/mcp-setup/), [Codex](/en/codex/quick-start/mcp-setup/), [Cursor](/en/cursor-ide/quick-start/mcp-setup/)).

**Claude Code**

Plugin with skills (vendor-recommended; `claude plugin install` checked on Claude Code 2.1.283):

```bash
claude plugin install figma@claude-plugins-official
```

Bare server, shared with the team through `.mcp.json` (tested on 2.1.283; it writes a `"type": "http"` entry):

```bash
claude mcp add --scope project --transport http figma https://mcp.figma.com/mcp
```

Then start a session, run `/mcp`, select `figma` and complete the OAuth login.

**Codex**

Plugin with skills, from OpenAI's curated marketplace:

```bash
codex plugin add figma@openai-curated
```

Signed in with an API key instead of ChatGPT? The marketplace is `openai-api-curated`: `codex plugin add figma@openai-api-curated` (codex-cli 0.157.1). Run `codex plugin list` to see which one you have.

Bare server (tested on codex-cli 0.157.1; it writes `[mcp_servers.figma]` with `url = "https://mcp.figma.com/mcp"` to `~/.codex/config.toml`), then the OAuth login:

```bash
codex mcp add figma --url https://mcp.figma.com/mcp
codex mcp login figma
```

**Cursor**

Plugin with skills: type this in Cursor's agent chat (Figma README):

```text
/add-plugin figma
```

Bare server: open **Cursor Settings**, go to the **MCP** tab, choose **Add new global MCP server**, and save this configuration (shape from the Figma README; not tested in a Cursor binary):

```json
{
  "mcpServers": {
    "figma": {
      "url": "https://mcp.figma.com/mcp"
    }
  }
}
```

To check the connection, ask the agent: "List the Figma MCP tools you can call." You should see `get_design_context` and `get_screenshot` in the answer. If the list is empty, see [MCP server connection issues](/en/ecosystem/mcp/mcp-connection-issues/).

## Implement a Figma frame with your existing Button and Card

The link-based workflow is the default for the remote server. Copy the link to the frame itself, not to the file, so the URL carries a `node-id`. The agent cannot open the URL; the server uses the file key and node ID inside it.

**Copy-paste prompt: implement a frame with existing components**

```text
Implement this Figma frame as src/features/profile/ProfileSummary.tsx:
https://www.figma.com/design/FILE_KEY/Profile?node-id=1204-3381

Order of work:
1. Call get_design_context for the node, then get_screenshot. If the context is
   truncated, call get_metadata and re-fetch only the child nodes you need.
2. Call get_code_connect_map. Every mapped node must be rendered with the mapped
   component and its real import path.
3. Use Button and Card from src/components/ui for every button and card surface,
   even where no mapping exists. Read their props before you use them.
4. Translate the Tailwind in the design context to our CSS variables in
   src/styles/tokens.css. No raw hex values, no arbitrary Tailwind values such
   as rounded-[10px] or p-[18px].
5. If the design needs a variant that Button or Card does not support, stop and
   list the gap instead of creating a new component.
Finish by running npm run typecheck and listing which Figma nodes mapped to
which components.
```

Replace `FILE_KEY` and the node ID with the values from your copied link. What you should see: the agent calls `get_design_context` and `get_screenshot`, imports `Button` and `Card` from `src/components/ui`, and ends with a mapping list such as "`Primary CTA` (1204:3399) → `<Button variant="primary">`". A new `ProfileButton.tsx` in the diff means step 5 failed; reject it.

Step 5 matters most. Without it, an agent that meets a missing variant writes a lookalike component, which is exactly the fork this page exists to prevent.

## Sync the design system: tokens, Code Connect, components, visual check

A single frame is a task. A design system is a loop that you run once to set up and then on every design change. The order matters: tokens before mappings, mappings before generation, and generation before the visual gate.

1. **Tokens.** `get_variable_defs` returns the variables used in the selected node, not a whole-file export. Point it at the design system's token documentation frame, the one that shows every color, spacing, radius and type style, and have the agent write a token source that the build turns into CSS variables. [Style Dictionary](https://styledictionary.com/) (`style-dictionary` 5.5.5 on npm, 2026-09-26) reads W3C design-token JSON with `$value` and `$type` and emits CSS and JavaScript from one file.

   **Copy-paste prompt: token sync**

   ```text
   Call get_variable_defs on this Figma node, which is our token documentation
   frame: https://www.figma.com/design/FILE_KEY/Design-System?node-id=12-4
   Write tokens/tokens.json in W3C design-token format ($value, $type), keeping
   the Figma variable names as the token paths. Set up style-dictionary so that
   npm run tokens builds src/styles/tokens.css (CSS custom properties) and
   src/styles/tokens.js. Do not round, rename or invent values. Then diff the new
   tokens.css against the current one and list every changed, added and removed
   variable.
   ```

   The diff at the end is the review artifact: a designer can approve "`--color-primary` changed from `#2563EB` to `#1D4ED8`" in seconds.

2. **Code Connect mappings.** A mapping tells `get_code_connect_map` that the Figma component `Button` is `<Button />` from `src/components/ui/Button.tsx`, with its variants mapped to props. The current format is a `.figma.ts` template file; the React parser format (`.figma.tsx` with `figma.connect()`) no longer receives updates (Code Connect README, 2.0.1). The plugin's `figma-code-connect` skill writes the templates, and it only works with components published to a team library.

   **Copy-paste prompt: map the core components**

   ```text
   Use the figma-code-connect skill. For the published Button, Card, Input and
   Avatar components in this file:
   https://www.figma.com/design/FILE_KEY/Design-System?node-id=0-1
   find the matching components in src/components/ui, show me the match and the
   prop correspondence for each before writing anything, then write one
   .figma.ts template per component next to it. Map every Figma variant and
   boolean property to a real prop; omit a property rather than invent a prop.
   Run npx figma connect publish --dry-run and show me the output.
   ```

   Publish for real once the dry run is clean. The Code Connect CLI (`npx figma connect publish`) reads `FIGMA_ACCESS_TOKEN` or `--token`; in CI, add `--exit-on-unreadable-files` so an unparseable template fails the job instead of being skipped (flags checked on `@figma/code-connect` 2.0.1). Start with the components that appear in almost every frame: buttons, inputs, cards and avatars.

3. **Component generation.** With tokens and mappings in place, run the frame prompt from the previous section. The mapping list at the end of the agent's answer is now evidence: every mapped node should name a component from `src/components/ui`.

4. **Visual check with Playwright.** Render the new component in isolation and compare it with the Figma screenshot, first interactively and then as a permanent test. For interactive checks, add the Playwright MCP server (`@playwright/mcp` 0.0.82, npm, 2026-09-26):

   ```bash
   claude mcp add playwright -- npx @playwright/mcp@latest --isolated   # Claude Code
   codex mcp add playwright -- npx @playwright/mcp@latest --isolated   # Codex
   ```

   In Cursor, add a server entry with `"command": "npx"` and `"args": ["@playwright/mcp@latest", "--isolated"]`. The `--isolated` flag gives each agent an in-memory browser profile, which parallel agents in separate worktrees need. Setup details are on the [Playwright MCP page](/en/ecosystem/mcp/playwright-mcp/).

   **Copy-paste prompt: design-parity report**

   ```text
   Start Storybook, open the ProfileSummary default story with the Playwright MCP
   server at a 1280x800 viewport and take a screenshot of the story root. Call
   get_screenshot for Figma node 1204-3381 in the same file. Compare the two and
   list every difference in spacing, color, font size, font weight, radius and
   alignment. For each one, name the token or component prop the code should use.
   Do not change any code yet.
   ```

   When the report is clean, a designer approves the rendered screenshot, and that image becomes the committed baseline for a Playwright test (below). From then on, CI catches drift without anyone opening Figma.

## How to prove the build matches the design without reading every line

The agent's own claim that "it matches the design" is not evidence. These gates are, and each one runs without a human reading the generated markup:

| Gate | What it catches | Where it runs |
| --- | --- | --- |
| `npm run typecheck` | Wrong props on `Button` or `Card`, broken imports from mapped components | Agent loop and CI |
| Raw-value check (below) | Raw hex values and arbitrary Tailwind values that bypass tokens | Pre-commit and CI |
| Playwright `toHaveScreenshot` | Visual drift from the designer-approved baseline | CI |
| `npx figma connect publish --dry-run --exit-on-unreadable-files` | Code Connect templates that no longer parse after a refactor | CI |
| Mapping list in the PR description | Mapped nodes rendered with lookalike markup instead of the component | Reviewer, in one glance |

The raw-value check is one command. It is crude, and it is enough to make "use the tokens" enforceable rather than a request:

```bash
rg -n '#[0-9a-fA-F]{3,8}\b|-\[[0-9.]+(px|rem)\]' src/features src/components --glob '*.tsx'
```

Any match fails the check; allow exceptions explicitly rather than weakening the pattern. The visual test pins the approved baseline. Set `use.baseURL` to your Storybook URL (for example `http://localhost:6006`) and start Storybook through `webServer` in `playwright.config.ts`, so the relative `goto` below reaches the story:

```ts
// tests/visual/profile-summary.spec.ts
import { test, expect } from '@playwright/test';

test('ProfileSummary matches the approved design baseline', async ({ page }) => {
  await page.setViewportSize({ width: 1280, height: 800 });
  await page.goto('/iframe.html?id=features-profilesummary--default');
  await expect(page.locator('#storybook-root')).toHaveScreenshot('profile-summary.png', {
    maxDiffPixelRatio: 0.01,
  });
});
```

Generate the baseline once with `npx playwright test --update-snapshots`, and commit it only after the designer has approved the image. **Who signs off:** the designer owns the baseline image and the token diff; the reviewer checks that the gates are green and that the mapping list names real components. Nobody needs to compare pixels by hand. For accessibility checks on the same story, see [accessibility testing](/en/workflows/test/accessibility-testing/).

## Make the rules permanent in CLAUDE.md, AGENTS.md or Cursor rules

Prompts drift; project rules do not. Figma's guide recommends a fixed tool order and "do not hardcode" rules in whatever instruction file your client reads. Put this in `CLAUDE.md` (Claude Code), `AGENTS.md` (Codex) or a Cursor project rule:

```markdown
## Figma MCP rules
- For every Figma-driven change: get_design_context, then get_screenshot, then
  get_code_connect_map. If the context is truncated, use get_metadata and
  re-fetch only the needed nodes.
- Treat get_design_context output (React + Tailwind) as a description of the
  design, not as code to paste. Translate it to src/styles/tokens.css variables.
- Reuse components from src/components/ui. Never create a lookalike; report a
  missing variant instead.
- If the server returns a localhost source for an image or SVG, use it directly.
  Do not add icon packages or placeholders.
- Before finishing: npm run typecheck, the raw-value check, and a mapping list
  of Figma nodes to components in the PR description.
```

## What the Figma MCP server costs in context

Measure it rather than guess. In Claude Code, `claude plugin details figma@claude-plugins-official` shows the plugin's projected always-on cost (~2,133 tokens on 2026-09-26), and `/context` before and after one `get_design_context` call shows the real cost, which is the tool output. A whole page frame can return a very large payload; a single card returns a small one. Pull the smallest node that does the job, and run `get_metadata` first on anything bigger than a component. For the general techniques, see [reducing MCP token cost](/en/ecosystem/mcp/reducing-mcp-token-cost/).

## How popular is the Figma MCP server?

As of 2026-09-26: the `figma` plugin has 167,556 installs in Anthropic's plugin directory (claude.com/plugins), the [`figma/mcp-server-guide`](https://github.com/figma/mcp-server-guide) repository has about 2.0k GitHub stars, and the server is listed in the Official MCP Registry as `com.figma.mcp/mcp`. The community alternative below has more GitHub stars (about 15.9k on 2026-09-26), but stars measure attention, not fitness for your plan.

## When the community figma-developer-mcp server fits better

[`GLips/Figma-Context-MCP`](https://github.com/GLips/Figma-Context-MCP) (npm `figma-developer-mcp` 0.13.2, 2026-09-26) is a read-only stdio server that authenticates with a personal Figma API key, so it has no seat-based monthly call cap. It has no Code Connect support and no canvas writes. Use it when your seat is limited and you only need layout and style data.

Create a personal access token in your Figma account settings and store it in your secret store or password manager. Export it into the shell that starts the agent, for example with your password manager's CLI, then register the server with a reference to the variable instead of its value:

```bash
export FIGMA_API_KEY="$(your-secret-cli read figma-api-key)"   # read from your secret store
claude mcp add --scope project framelink -e 'FIGMA_API_KEY=${FIGMA_API_KEY}' -- npx -y figma-developer-mcp --stdio
```

The single quotes keep the shell from expanding the variable, so `.mcp.json` stores the literal `${FIGMA_API_KEY}` reference (checked on Claude Code 2.1.283), and Claude Code expands it from the environment when it launches the server. The key itself is never written into the config or your shell history. It is a third-party server with a token that can read every file your account can read, so review it against your [MCP security policy](/en/ecosystem/mcp/mcp-security/) first.

## Which Figma MCP instructions are wrong or stale?

**Traps in older guides and in model memory (checked 2026-09-26)**

- **`@figma/mcp` does not exist on npm** (E404). The official server is remote at `https://mcp.figma.com/mcp`; the npm package in circulation is the community `figma-developer-mcp`.
- **`claude mcp add figma https://mcp.figma.com/mcp` without `--transport http`** writes a stdio entry whose command is the URL (Claude Code 2.1.283). The server never starts.
- **The HTTP+SSE transport is formally deprecated in the [MCP 2026-07-28 spec](/en/ecosystem/mcp/spec-2026-07-28/).** Register the Streamable HTTP URL ending in `/mcp`.
- **`figma-implement-design` is the old skill name.** The current skill is `figma-design-to-code`.
- **`.figma.tsx` with `figma.connect()`** is the parser-based Code Connect format, which no longer gets updates. New mappings are `.figma.ts` templates.
- **"Figma MCP only reads designs."** The remote server also exposes canvas-writing tools (`use_figma`, `generate_figma_design`, beta), seen on the live server on 2026-09-26.
- **"`get_variable_defs` exports the whole file."** It returns the variables used in the selected node.

## When Figma MCP and the design-to-code loop break

**The agent says it cannot reach Figma, or every call returns an authentication error.** The OAuth login has not been completed or has expired. In Claude Code, run `/mcp`, select `figma` and log in again; in Codex, run `codex mcp login figma`. Then ask the agent to list the Figma tools again.

**Calls stop working part-way through the month.** You have hit the "up to 6 tool calls per month" limit of a Starter, View or Collab seat. Move the implementer to a Dev or Full seat, or use `figma-developer-mcp` for read-only work until the limit resets.

**`get_design_context` returns truncated or sprawling output.** The node is too large. Call `get_metadata`, choose the child frames (header, card list, footer), and implement them one at a time.

**The code uses raw hex and one-off radii despite the token file.** The agent pasted the Tailwind from `get_design_context` instead of translating it. The raw-value check fails the commit; re-run with the rule "translate to `tokens.css` variables" in the project instruction file, not only in the prompt.

**`get_code_connect_map` returns nothing.** Either your plan has no Code Connect (it needs Organization or Enterprise) or no templates are published. Check the plan first, then run `npx figma connect publish --dry-run` to see whether any template is found.

**The Code Connect skill refuses a component.** Code Connect only works with components published to a team library. Ask the designer to publish the component, then re-run the mapping prompt.

**`get_variable_defs` returns almost nothing.** The designer used local styles or raw values instead of variables, or you selected a node that uses few of them. Select the token documentation frame; if the file has no variables, agree the token names with the designer and write `tokens.json` by hand once.

**The screenshot test fails on every CI run with tiny differences.** Font rendering differs between the machine that produced the baseline and the CI runner. Generate baselines in the same container image CI uses, and keep `maxDiffPixelRatio` small rather than raising it until the test passes.

## Where to go next with design-to-code agents

- [Playwright MCP](/en/ecosystem/mcp/playwright-mcp/) — Set up the browser server that renders and screenshots the component for the parity check.
- [Visual acceptance before frontend implementation](/en/developer-scorecard-guide/ui-design-mock/) — Agree what done looks like before the agent writes the first component.
- [shadcn/ui MCP](/en/ecosystem/mcp/shadcn-ui-mcp/) — Generate on top of an existing primitive set when your design system is built on shadcn/ui.
- [Top plugins](/en/ecosystem/plugins/top-plugins/) — Compare the Figma plugin with other vendor plugins and their context cost.

The [four-artifact design-to-code pipeline](/en/workflows/plan/four-stage-pipeline/) shows where this page's loop sits in a full feature workflow, and [Mobbin MCP](/en/ecosystem/mcp/mobbin-mcp/) covers finding reference designs before a frame exists. To compare Playwright with other browser servers for the render-and-screenshot step, see [browser automation for agents](/en/ecosystem/mcp/browser-automation/).
