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

> Master programmatic Figma file editing with the use_figma tool. This guide covers the figma-use skill for safe, atomic JavaScript execution in Figma plugins.

- Repository: [Figma/mcp-server-guide](https://github.com/figma/mcp-server-guide)
- Tags: how-to-guide
- Published: 2026-03-30

---

**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`](https://github.com/figma/mcp-server-guide/blob/main/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`](https://github.com/figma/mcp-server-guide/blob/main/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`](https://github.com/figma/mcp-server-guide/blob/main/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:

```javascript
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:

```javascript
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:

```javascript
// 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.

```javascript
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.

```javascript
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`](https://github.com/figma/mcp-server-guide/blob/main/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`](https://github.com/figma/mcp-server-guide/blob/main/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

- **[`skills/figma-use/SKILL.md`](https://github.com/figma/mcp-server-guide/blob/main/skills/figma-use/SKILL.md)** – Mandatory skill definition containing the 17 critical rules and workflow guidance
- **[`skills/figma-use/references/plugin-api-standalone.d.ts`](https://github.com/figma/mcp-server-guide/blob/main/skills/figma-use/references/plugin-api-standalone.d.ts)** – Complete TypeScript typings for the supported Plugin API surface
- **[`skills/figma-use/references/api-reference.md`](https://github.com/figma/mcp-server-guide/blob/main/skills/figma-use/references/api-reference.md)** – Quick lookup for supported vs. unsupported methods
- **[`skills/figma-use/references/gotchas.md`](https://github.com/figma/mcp-server-guide/blob/main/skills/figma-use/references/gotchas.md)** – Real-world pitfalls with before-and-after code corrections
- **[`skills/figma-use/references/variable-patterns.md`](https://github.com/figma/mcp-server-guide/blob/main/skills/figma-use/references/variable-patterns.md)** – Best practices for design token creation and scoping
- **[`skills/figma-use/references/component-patterns.md`](https://github.com/figma/mcp-server-guide/blob/main/skills/figma-use/references/component-patterns.md)** – Component set and variant construction guides

## 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`](https://github.com/figma/mcp-server-guide/blob/main/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.