Figma Integration Guide

Technology: figma · Category: design · Last reviewed: 2026-08-23

Source: https://tech-stack.codeamanilabs.org/guide/figma

Insight:

The Figma MCP bridges design and code both ways — pull a frame into accurate component code, or push code into Figma. Use get_design_context / screenshots to ground UI work in the real design instead of guessing, keeping the motionstack design system consistent.

███████╗██╗ ██████╗ ███╗   ███╗ █████╗
██╔════╝██║██╔════╝ ████╗ ████║██╔══██╗
█████╗  ██║██║  ███╗██╔████╔██║███████║
██╔══╝  ██║██║   ██║██║╚██╔╝██║██╔══██║
██║     ██║╚██████╔╝██║ ╚═╝ ██║██║  ██║
╚═╝     ╚═╝ ╚═════╝ ╚═╝     ╚═╝╚═╝  ╚═╝

Figma Integration Guide

Focus: Design-to-code workflows, component inspection, and Figma canvas automation from Claude Code using the official Figma MCP server.

Overview

Figma is the standard design tool for UI/UX. Its official MCP server gives Claude Code direct access to design files — reading component specs, extracting tokens, generating code from components, writing content back to the canvas, and running Code Connect mappings. This enables a true design-to-code pipeline: Claude reads Figma, writes the component, and links it back.

Here is the big picture — the MCP bridges design and code both ways, and you get to use both directions:

flowchart LR
    A["Figma design file"] -->|"read"| B["Figma MCP server"]
    B --> C["Claude Code"]
    C -->|"generate"| D["React or Vue component"]
    C -->|"write canvas"| A
    D -->|"link back"| E["Code Connect map"]
    E --> A

Official Documentation

Resource URL
Figma Developers https://developers.figma.com
Figma MCP Server https://developers.figma.com/docs/figma-mcp-server/
Set up the MCP server in Claude Code https://help.figma.com/hc/en-us/articles/39888612464151-Claude-Code-and-Figma-Set-up-the-MCP-server
Write to Canvas (use_figma) https://developers.figma.com/docs/figma-mcp-server/write-to-canvas/
Code to Canvas (generate_figma_design) https://developers.figma.com/docs/figma-mcp-server/code-to-canvas/
MCP Help Guide https://help.figma.com/hc/en-us/articles/32132100833559-Guide-to-the-Figma-MCP-server
Figma REST API https://developers.figma.com/docs/rest-api/
Webhooks (REST API v2) https://developers.figma.com/docs/rest-api/webhooks/
Code Connect https://developers.figma.com/docs/code-connect/

MCP Server Setup

Figma recommends the hosted remote MCP server — it requires no desktop app, provides the broadest feature set, and is now available on all seats and plans. The endpoint is https://mcp.figma.com/mcp and auth is OAuth (an interactive "Allow access" browser flow) — there is no longer a static X-Figma-Token header on the MCP server itself. (The old mcp.figma.com/v1/mcp path is gone.)

Recommended path — install the official Figma plugin (bundles the MCP server config plus Agent Skills):

claude plugin install figma@claude-plugins-official
# then restart Claude Code, run /plugin, open the Installed tab,
# select the `figma` server, press Enter, and click "Allow access" to authorize (OAuth)

Manual alternative — add the remote server directly:

# Triggers the OAuth "Allow access" flow on first use — no token header needed
claude mcp add --transport http figma https://mcp.figma.com/mcp

.mcp.json Configuration (Remote)

{
  "mcpServers": {
    "figma": {
      "type": "http",
      "url": "https://mcp.figma.com/mcp"
    }
  }
}

On first connection Claude Code opens the OAuth flow; approve access to your Figma account. No personal access token is stored for the MCP server.

Desktop (local) MCP Server

For enterprise/org needs Figma also ships a local server inside the Figma desktop app (enable it under Preferences → "Enable local MCP server"). It is available on a Dev or Full seat on paid plans and listens on http://127.0.0.1:3845/mcp:

claude mcp add --transport http figma-desktop http://127.0.0.1:3845/mcp

Third-party Community Server (figma-developer-mcp)

figma-developer-mcp (the community "Framelink" server, currently 0.13.2) is a third-party stdio server — not Figma's official MCP. It authenticates with a personal access token and can be handy for read-only REST-backed workflows:

claude mcp add figma-framelink -- npx -y figma-developer-mcp \
  --figma-api-key=${FIGMA_ACCESS_TOKEN} \
  --stdio

Prefer the official remote server above for design-context and write-to-canvas work. A personal access token (for the REST API or this community server) is generated at: https://www.figma.com/settings → Personal access tokens

Available MCP Tools

Tool Description
get_design_context Get full design specs, code hints, and screenshot for a node
get_screenshot Capture a screenshot of a Figma node
get_metadata Get file metadata (name, pages, last modified)
get_figjam Get FigJam board content
get_libraries Get shared component libraries
search_design_system Search for components by name
get_variable_defs Get design tokens (colors, spacing, typography)
get_code_connect_map Map Figma components to codebase components
add_code_connect_map Link a Figma component to a code component
generate_diagram Create a diagram in FigJam
download_assets Export nodes as PNG / SVG / PDF via the MCP

The server's tool set keeps growing — recent additions include motion, shader, and Weave (weave_*) tools. Run /plugin (or your client's tool list) to see the current inventory; the standalone get_design_pages tool was folded into get_metadata.


Figma REST API Integration

npm install axios  # or use fetch

Extract Component Info

const FIGMA_TOKEN = process.env.FIGMA_ACCESS_TOKEN!;
const FILE_KEY = "your-file-key"; // from figma.com/design/{fileKey}/...

// Get file structure
const file = await fetch(`https://api.figma.com/v1/files/${FILE_KEY}`, {
  headers: { "X-Figma-Token": FIGMA_TOKEN },
}).then((r) => r.json());

// Get specific node
const nodeId = "1:23"; // from URL param node-id=1-23
const nodes = await fetch(
  `https://api.figma.com/v1/files/${FILE_KEY}/nodes?ids=${nodeId}`,
  { headers: { "X-Figma-Token": FIGMA_TOKEN } }
).then((r) => r.json());

// Export node as PNG
const images = await fetch(
  `https://api.figma.com/v1/images/${FILE_KEY}?ids=${nodeId}&format=png&scale=2`,
  { headers: { "X-Figma-Token": FIGMA_TOKEN } }
).then((r) => r.json());

console.log(images.images[nodeId]); // URL to the exported PNG

REST file/nodes/images endpoints are still under /v1 and still authenticate with the X-Figma-Token header (OAuth2 is also supported). No /v1 deprecation is in effect as of this review.

Webhooks (REST API v2)

Figma webhooks live at https://api.figma.com/v2/webhooks (note: v2, not v1) — subscribe to file events (FILE_UPDATE, FILE_COMMENT, FILE_VERSION_UPDATE, LIBRARY_PUBLISH, etc.). There is no HMAC signature header: you set a passcode when creating the webhook, Figma echoes it in every event payload, and your handler must compare the incoming passcode against the stored one and reject mismatches with 400 before acting — this is the codeAmani webhook-verification requirement applied to Figma.

// app/api/webhooks/figma/route.ts (Next.js App Router)
import { NextRequest, NextResponse } from "next/server";

export async function POST(req: NextRequest) {
  const body = await req.json();
  // Verify the request really came from Figma before doing any work
  if (body.passcode !== process.env.FIGMA_WEBHOOK_PASSCODE) {
    return new NextResponse("Invalid passcode", { status: 400 });
  }
  // handle body.event_type (FILE_UPDATE, FILE_COMMENT, ...)
  return NextResponse.json({ ok: true });
}

Environment Variables

# Required
FIGMA_ACCESS_TOKEN=figd_...         # Personal access token from Figma settings

# Optional for automation scripts
FIGMA_FILE_KEY=...                  # Default file key for automation
FIGMA_TEAM_ID=...                   # Team ID for shared library access
FIGMA_WEBHOOK_PASSCODE=...          # Passcode to verify inbound v2 webhook events

Automation Workflows

Design-to-Code Workflow

The core Claude Code + Figma workflow follows four clean steps — here is how the calls flow:

sequenceDiagram
    participant You
    participant Claude as "Claude Code"
    participant MCP as "Figma MCP"
    You->>Claude: "Share Figma URL or node ID"
    Claude->>MCP: "get_design_context"
    MCP-->>Claude: "specs, colors, spacing, screenshot"
    Claude->>Claude: "generate React or Vue component"
    Claude->>MCP: "add_code_connect_map"
    MCP-->>Claude: "Figma component linked"
  1. Share a Figma URL or node ID
  2. Claude calls get_design_context → gets specs, colors, spacing, component screenshot
  3. Claude generates a React/Vue component matching the design
  4. Claude calls add_code_connect_map → links the Figma component to the generated component

Example prompt inside Claude Code:

"Implement the Button/Primary component from figma.com/design/AbCdEf/Design-System?node-id=1:23"

Slash Command: Figma to Component

.claude/commands/figma.md:

Implement the Figma design at URL or node: $ARGUMENTS

1. Use the Figma MCP tool `get_design_context` with the file key and node ID extracted from $ARGUMENTS
2. Use `get_screenshot` to see the visual
3. Generate a TypeScript React component that matches the design exactly:
   - Use Tailwind CSS for styling
   - Extract all colors as CSS variables or Tailwind tokens
   - Make it responsive
   - Add proper TypeScript props interface
4. Write the component to the appropriate file in `src/components/`
5. Create a Storybook story for it
6. Report the component code and any design tokens used

Usage: /project:figma figma.com/design/AbCdEf/Design-System?node-id=1-23


Code → design (write to canvas)

The MCP is not read-only. Claude Code can write native Figma structure back into a file — real frames, components, variants, variables, and auto layout — not just flat screenshots. This is the inverse of the design-to-code flow above and is what keeps the motionstack design system in sync when code moves ahead of the canvas.

Three official write tools cover this direction:

Tool Direction What it produces
create_new_file scaffold A fresh, blank Figma / FigJam / Slides file to write into
use_figma code/intent → canvas Native Figma objects via the Plugin API — components, variables, frames, auto layout, with awareness of the existing design system
generate_figma_design running app → canvas "Code to canvas" — captures live rendered UI from the browser as standard, flat Figma layers for human review

MANDATORY skill note: You MUST load the /figma-use skill before every use_figma call, and the /figma-create-new-file skill before every create_new_file call. Calling these tools without first loading the matching skill causes common, hard-to-debug failures. For pushing a whole page or layout, also load /figma-generate-design.

Workflow: generate a component into Figma from a description or code

sequenceDiagram
    participant You
    participant Claude as "Claude Code"
    participant Skill as "figma-use skill"
    participant MCP as "Figma MCP"
    You->>Claude: "Build Button/Primary in Figma"
    Claude->>Skill: "load figma-use"
    Claude->>MCP: "search_design_system · get_variable_defs"
    MCP-->>Claude: "existing tokens and components"
    Claude->>MCP: "use_figma · Plugin API code"
    MCP-->>Claude: "native component on canvas"
  1. (If no target file) load /figma-create-new-file, then call create_new_file to scaffold a blank file
  2. Load /figma-use — this is required before the next step
  3. Discover what already exists: search_design_system plus get_variable_defs so the new work reuses real tokens and components instead of hardcoded values
  4. Call use_figma, which executes Plugin API JavaScript inside the file to assemble the component section-by-section, binding design-system variables
  5. For a full app screen instead of one component, capture the running UI with generate_figma_design ("code to canvas") for the team to review before implementation

Example prompt inside Claude Code:

"Create a Button/Primary component in our design-system file from src/components/Button.tsx, reusing our existing color and spacing variables."

Gotcha: use_figma is beta and intentionally limited — there is a ~20 KB response cap per call, no image / asset import, no custom fonts, and a Full seat with edit access is required (Dev seats are read-only). Make large changes incrementally across several calls rather than one giant payload, and expect to manually review and clean up the result.

Code Connect creates a permanent mapping between Figma components and real code so Dev Mode shows actual component usage instead of raw CSS.

Heads-up — Code Connect v2 (Aug 2026). @figma/code-connect is now 2.0.0. As of v2.0.0 (18 Aug 2026) the framework-specific parsers (the React .figma.tsx form below with an example: () => <JSX/> function) are no longer maintained — under v2 they only work with figma connect migrate/unpublish, and all other commands tell you to migrate. Parserless template files (.figma.ts / .figma.js) are now the only actively-maintained format. Author them with the shipped /figma-code-connect skill and follow the templates migration guide. npx figma connect publish is unchanged. To keep the legacy React parser, pin v1: npm install --save-dev @figma/code-connect@1.

Current (v2) — parserless template file (Button.figma.ts):

// Button.figma.ts — v2 template file (no framework parser)
/**
 * @figmaNode https://www.figma.com/design/[FILE_KEY]?node-id=[NODE_ID]
 */
import figma from "figma";
import { Button } from "./Button";

export default figma.connect(Button, {
  props: {
    variant: figma.enum("Variant", { Primary: "primary", Secondary: "secondary" }),
    disabled: figma.boolean("Disabled"),
    label: figma.string("Label"),
  },
  example: ({ variant, disabled, label }) => (
    <Button variant={variant} disabled={disabled}>{label}</Button>
  ),
});

Legacy (v1 React parser) — requires @figma/code-connect@1:

// Button.figma.tsx — legacy React parser (pin @figma/code-connect@1)
import { figma } from "@figma/code-connect/react";
import { Button } from "./Button";

figma.connect(Button, "https://www.figma.com/design/[FILE_KEY]?node-id=[NODE_ID]", {
  props: {
    variant: figma.enum("Variant", { Primary: "primary", Secondary: "secondary" }),
    disabled: figma.boolean("Disabled"),
    label: figma.string("Label"),
  },
  example: ({ variant, disabled, label }) => (
    <Button variant={variant} disabled={disabled}>{label}</Button>
  ),
});
# Publish Code Connect mappings to Figma (unchanged in v2)
npx figma connect publish

GitHub Actions: Auto-generate Types from Design Tokens

# .github/workflows/design-tokens.yml
name: Sync Figma Tokens
on:
  schedule:
    - cron: "0 9 * * 1"   # Every Monday morning
  workflow_dispatch:

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '22' }
      - name: Fetch design tokens
        env:
          FIGMA_ACCESS_TOKEN: ${{ secrets.FIGMA_ACCESS_TOKEN }}
          FIGMA_FILE_KEY: ${{ secrets.FIGMA_FILE_KEY }}
        run: node scripts/sync-tokens.js
      - name: Commit updated tokens
        run: |
          git config user.name "Design Sync Bot"
          git config user.email "noreply@figma.com"
          git add src/tokens/
          git diff --staged --quiet || git commit -m "chore: sync Figma design tokens"
          git push

Common Use Cases

Use Case Approach
Design to React component MCP get_design_context → generate code
Component library sync get_libraries + search_design_system
Design token extraction MCP get_variable_defs → CSS/TypeScript
Visual regression check get_screenshot → compare to rendered component
Code Connect linking add_code_connect_map + figma connect publish
FigJam diagrams MCP generate_diagram

Troubleshooting

Issue Fix
403 Forbidden Token lacks access to that file — check sharing settings
Node not found Extract node-id from URL; convert - to : (e.g., 1-23 → 1:23)
Design context empty Component may be in a library — use get_libraries first
Screenshot fails Node must be visible (not hidden) in the file
Code Connect not publishing Run npx figma connect publish from project root
figma connect errors telling you to migrate You're on v2 with legacy .figma.tsx parser files — migrate to template files (/figma-code-connect skill) or pin @figma/code-connect@1
MCP server won't connect Remote endpoint is https://mcp.figma.com/mcp (not /v1/mcp); re-run the OAuth "Allow access" flow via /plugin
Figma webhook events ignored Verify passcode matches before acting; reject mismatches with 400

Official docs: