Using the use_figma Tool for Programmatic Figma File Editing: Complete MCP Guide

The use_figma tool executes JavaScript in a headless Figma Plugin API runtime, requiring the figma-use skill to enforce 17 critical safety rules that ensure atomic execution and return-based communication.

The Figma MCP Server Guide repository enables AI agents to manipulate Figma files programmatically through the use_figma tool. Unlike traditional Figma plugins, this tool operates within a constrained, headless environment where every script execution is atomic and validated against strict runtime constraints defined in skills/figma-use/SKILL.md.

Core Architecture and Safety Model

The use_figma tool operates on a skill-driven architecture that prioritizes file safety and deterministic execution.

Skill-Driven Workflow

Every use_figma invocation must be preceded by loading the figma-use skill, which encodes mandatory operational rules. The skill definition resides at skills/figma-use/SKILL.md and establishes the contract between the AI agent and the headless runtime.

Atomic Execution Guarantees

The runtime executes scripts atomically—if any of the 17 critical constraints in SKILL.md are violated, the entire operation fails immediately and makes no changes to the design file. This atomicity enables safe retry patterns: you can fix errors and re-run without risk of partial mutations corrupting the document.

Return-Based Communication Pattern

Unlike standard Figma plugins, use_figma prohibits console.log and figma.closePlugin. The only communication channel is the JSON-serializable return value. All created or modified node IDs must be explicitly returned to enable reference in subsequent calls.

Critical Rules and Constraints

The figma-use skill mandates 17 non-negotiable constraints covering color ranges, async handling, page resets, and node manipulation. Key rules include:

  • Color values must use 0-1 floating point ranges, not 0-255 (Rule 6)
  • Page navigation requires await figma.setCurrentPageAsync(page); the synchronous setter throws an error (Rule 9)
  • Node appending must occur before any layoutSizing modifications (Rule 12)
  • ID tracking requires returning all created or mutated node IDs (Rule 15)
  • Incremental work recommends splitting large operations into separate atomic calls (Rule 5)

Working with Pages and Context

Each use_figma invocation automatically resets to the first page of the target file. To operate on other pages, you must explicitly switch context:

const targetPage = figma.root.children.find(p => p.name === "Landing");
await figma.setCurrentPageAsync(targetPage);

This asynchronous requirement differs from standard plugin development, where figma.currentPage might be synchronous. The deprecated synchronous setter throws an error in the headless environment.

Practical Implementation Examples

The following patterns demonstrate compliant use_figma workflows from the skill documentation.

Inspecting File Structure (Read-Only)

Start with inspection to understand the document structure before mutation:

const pages = figma.root.children.map(p => ({
  name: p.name,
  id: p.id,
  childCount: p.children.length,
}));
return { pages };

Creating Shapes with Validation

Create a rectangle on a specific page while respecting color range and appending rules:

// Switch to the target page
const targetPage = figma.root.children.find(p => p.name === "Landing");
await figma.setCurrentPageAsync(targetPage);

// Create a rectangle
const rect = figma.createRectangle();
rect.resize(200, 100);
rect.x = 300; // position away from (0,0) to avoid overlap
rect.fills = [{ type: "SOLID", color: { r: 1, g: 0, b: 0 } }]; // 0-1 range

// Append to page (must happen before layoutSizing changes)
targetPage.appendChild(rect);

return { createdNodeIds: [rect.id] };

Managing Design Tokens and Variables

Complex operations should follow the incremental approach, splitting creation and binding into separate atomic calls:

Step A: Create the variable collection and color token.

const coll = await figma.variables.createLocalVariableCollectionAsync("Design Tokens");
const colorVar = await coll.createVariableAsync("primaryRed", "COLOR");
await colorVar.setValueAsync({ r: 1, g: 0, b: 0 });
await colorVar.setScopesAsync(["FRAME_FILL", "SHAPE_FILL"]);

return { collectionId: coll.id, variableId: colorVar.id };

Step B: Bind the variable to an existing rectangle using IDs returned from previous operations.

const rect = figma.getNodeById('YOUR_RECT_ID_HERE'); // replace with ID from previous return
const paint = { type: "SOLID", color: { r: 1, g: 0, b: 0 } };
const boundPaint = await figma.createPaintStyleAsync();
boundPaint.paints = [paint];

const bound = await figma.setBoundVariableForPaintAsync(boundPaint.id, colorVar.id);
rect.fills = [bound];

return { mutatedNodeIds: [rect.id] };

Supported API Surface

The headless runtime implements the full Figma Plugin API surface defined in skills/figma-use/references/plugin-api-standalone.d.ts, with exceptions for UI-only methods such as figma.notify and getPluginData. For method availability and type safety, reference the typings file rather than standard Figma plugin documentation.

Error Recovery and Debugging

When scripts fail, the atomic execution model ensures the file remains unmodified. The Error Recovery & Self-Correction table in skills/figma-use/SKILL.md maps common error messages to specific fixes. Since partial states cannot occur, you can safely iterate on your code until it passes all 17 validation constraints.

Essential Reference Files

Summary

  • Atomic execution ensures failed use_figma scripts make zero changes to your Figma files
  • Mandatory skill loading of figma-use enforces 17 safety constraints that differ from standard plugin development
  • Return-value communication replaces console.log and figma.closePlugin for data extraction
  • Asynchronous page navigation requires await figma.setCurrentPageAsync() instead of synchronous assignment
  • Incremental workflows split complex operations into multiple atomic calls, returning node IDs for chaining

Frequently Asked Questions

What happens if a use_figma script encounters an error?

The script fails entirely and makes no changes to the file due to atomic execution. Unlike traditional Figma plugins where partial mutations might persist, the headless runtime rolls back all operations when any of the 17 critical rules are violated, allowing safe retries after fixes.

How do I debug code when console.log is not supported?

You must use the return statement to output debugging information. Return objects containing inspection data, variable states, or node properties, then examine the JSON response. The use_figma environment ignores console.log calls entirely, and figma.closePlugin is prohibited.

Can I use the full standard Figma Plugin API with use_figma?

Nearly all standard methods are available except UI-specific functions like figma.notify and getPluginData. The authoritative source is skills/figma-use/references/plugin-api-standalone.d.ts in the figma/mcp-server-guide repository, which defines the exact surface area available in the headless environment.

Why must I return node IDs from every creation operation?

The use_figma runtime resets between calls and starts on the first page each time. Without returning IDs like rect.id or collectionId, subsequent invocations cannot reference created nodes. This return-based reference system enables multi-step workflows while maintaining stateless, atomic execution.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →