All skills
figma avatar

/figma-use-slides

@a5e7e04 official
by figmafigma/mcp-server-guide2k stars
194

This skill helps agents use Figma's use_figma MCP tool in the Slides context. Can be used alongside figma-use which has foundational context for using the use_figma tool.

Use this Skill: https://skilld.dev/gh/figma/mcp-server-guide/figma-use-slides

This session only. Nothing lands on disk.

referencesslide-content.md

≈1.5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Slide Content

SlideNode extends BaseFrameMixin, which means slides support the same content creation patterns as frames in Design mode: text, shapes, auto-layout, images, components, and instances.

Adding text to a slide

Canonical recipe: load font → await → mutate → return affected IDs. Inter is preloaded; for any other family the same loadFontAsync step is required or you'll hit Cannot write to node with unloaded font "<family> <style>". See figma-use → gotchas.md → Canonical text-edit recipe.

const slide = figma.getNodeById("SLIDE_ID");

// Load font BEFORE any text mutation — required for every font, not just Inter
await figma.loadFontAsync({ family: "Inter", style: "Semi Bold" });
const title = figma.createText();
title.fontName = { family: "Inter", style: "Semi Bold" };
title.characters = "Quarterly Review";
title.fontSize = 48;

slide.appendChild(title);
title.x = 100;
title.y = 80;

return { createdNodeIds: [title.id] };

Use listAvailableFontsAsync() to discover exact style strings. Note: "Inter" uses "Semi Bold" (with a space), not "SemiBold" — guessing style names is a common cause of the unloaded-font error even when loadFontAsync is called.

Bulleted and numbered lists

Slides are bullet-heavy by nature. Use a single TextNode with \n-separated lines and setRangeListOptions(start, end, { type: 'UNORDERED' | 'ORDERED' }) for native bulleted text — it gives proper hanging indents on wrapped lines.

await figma.loadFontAsync({ family: "Inter", style: "Regular" });

const text = figma.createText();
slide.appendChild(text);
text.fontName = { family: "Inter", style: "Regular" };
text.fontSize = 20;
text.characters = [
  "Explore ideal outputs",
  "Eval: benchmark vs current on large files",
  "Eval: DS context into code generation · React / Vue / iOS / Android",
].join("\n");
text.fills = [{ type: "SOLID", color: { r: 0.07, g: 0.09, b: 0.13 } }];
text.lineHeight = { unit: "PERCENT", value: 145 };
text.setRangeListOptions(0, text.characters.length, { type: "UNORDERED" });

return { createdNodeIds: [text.id] };

Do NOT build bullets by laying out an ellipse + text in a horizontal auto-layout row. That pattern misaligns when text wraps to multiple lines (the wrapped line starts at the dot's x, not the first character's x — no hanging indent), and it produces a tree of vector nodes instead of a single editable text block. Use setRangeListOptions instead.

If only some lines should be bullets (e.g. a heading line followed by bullet items), pass a partial range: text.setRangeListOptions(headingLength + 1, text.characters.length, { type: "UNORDERED" }). Pass { type: "NONE" } to remove list formatting from a range.

Adding shapes

const slide = figma.getNodeById("SLIDE_ID");

const rect = figma.createRectangle();
rect.resize(400, 300);
rect.fills = [{ type: "SOLID", color: { r: 0.95, g: 0.95, b: 0.97 } }];
rect.cornerRadius = 12;

slide.appendChild(rect);
rect.x = 200;
rect.y = 200;

return { createdNodeIds: [rect.id] };

Adding images to a slide

upload_assets is the ONLY supported way to put images on slides. Call upload_assets with the Slides fileKey; the tool returns single-use upload URLs that you POST raw image bytes to, and each image is committed and placed automatically. Pass nodeIds (with one entry per upload) to attach uploads to existing slide nodes as fills (e.g. rectangles already on the slide); omit nodeIds to drop the images onto slides as new layers.

For the full request/response shape, see figma-use → api-reference.md → Images.

Using auto-layout within slides

const slide = figma.getNodeById("SLIDE_ID");

const container = figma.createAutoLayout("VERTICAL", {
  name: "Content Block",
  itemSpacing: 16,
  paddingLeft: 40,
  paddingRight: 40,
  paddingTop: 40,
  paddingBottom: 40,
});

slide.appendChild(container);
container.resize(slide.width - 80, container.height);
container.layoutSizingVertical = "HUG";
container.x = 40;
container.y = 40;

return { createdNodeIds: [container.id] };

Slides are not auto-layout parents, so direct slide children cannot use FILL. Give the container an explicit width instead. For nested children, set FILL only after appending them to an auto-layout container.

Working with components

Components (SYMBOL) are intentionally allowed in Slides mode for MCP/assistant use. You can create components and instances within slides.

const component = figma.createComponent();
component.name = "Card";
component.resize(400, 200);

const instance = component.createInstance();
const slide = figma.getNodeById("SLIDE_ID");
slide.appendChild(instance);

return { createdNodeIds: [component.id, instance.id] };

Positioning within slides

Slides have a fixed canvas size (typically 1920x1080). Position content using absolute x/y coordinates within the slide, or use auto-layout containers to handle positioning automatically.

Critical: MUST set x/y AFTER appendChild — at every level of nesting. Setting position before parenting causes a (−240, −240) shift because new nodes are silently auto-parented to a slide context at absolute (240, 240). The rule applies to frames inside other frames, not just the slide root. See slide-gotchas.md for the helper pattern (addFrame / addText / addRect) you should use to make the order impossible to write wrong.

Recommended pattern — append first, then configure:

const slide = figma.getNodeById("SLIDE_ID");

const node = figma.createRectangle();
slide.appendChild(node);
node.resize(400, 300);
node.fills = [{ type: "SOLID", color: { r: 0.2, g: 0.2, b: 0.3 } }];
node.cornerRadius = 12;
node.x = 200;
node.y = 200;

return { width: slide.width, height: slide.height, nodeId: node.id };

Source: SKILL.md on GitHub

No alerts17d3 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    The skill provides technical guidance for automating Figma Slides. It is categorized as low risk because its core functionality—generating scripts based on user-provided briefs—creates a surface area for indirect prompt injection and involves dynamic execution of code.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

Signed by skilld at a5e7e04. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 3 months ago
disable-model-invocation
false
  • MCP
  • Design
  • figma
  • slides
  • plugin-api
  • presentation
  • deck-building

README badge

README badge for figma/mcp-server-guide/figma-use-slides

This skill provides Slides-specific context for the use_figma MCP tool, covering critical positioning rules, theme management, and the slide grid structure that differ from Figma's Design API. It includes a two-phase deck-building workflow with design thinking guidance and batch validation patterns for building multi-slide presentations via the Plugin API.

Generated from the current SKILL.md.

Do I need to load figma-use as well as figma-use-slides?
Yes. figma-use-slides provides Slides-specific context, but figma-use contains foundational context for the use_figma MCP tool and advanced plugin API use cases not covered here.
Can I use figma.createPage() in Slides files?
No. createPage() is Design-file only and will throw a TypeError in Slides. Use the slide grid (SLIDE_GRID / SLIDE_ROW / SLIDE) to organize deck structure instead.
What's the critical rule about setting x and y coordinates on new nodes?
Always call appendChild before setting x/y. Setting coordinates before appending causes nodes to land 240 pixels off their intended position. Use the helper pattern in slide-gotchas.md to make the order impossible to get wrong.
Does get_metadata work on Slides files?
No. Use read-only use_figma scripts for validation instead, and return created node positions in closePlugin() output to verify no overlapping bounding boxes.
When modifying an existing deck, should I delete and rebuild slides or edit in place?
Always modify slides in place unless the user explicitly asks to start over or redo from scratch. Inspect the existing deck to match its color palette, typography, and spatial habits.

Generated from the current SKILL.md. These answers refresh after source changes.