$npx -y skills add figma/mcp-server-guide --skill figma-use-motionMotion / animation context for the use_figma MCP tool — animating Figma nodes via manual keyframes, animation styles, easing, and timeline duration. Load alongside figma-use whenever a task involves adding, editing, or inspecting animation on a node.
| 1 | # use_figma — Figma Plugin API Skill for Motion |
| 2 | |
| 3 | Motion context for the `use_figma` MCP tool. [figma-use](../figma-use/SKILL.md) covers the foundational Plugin API rules — load both together. |
| 4 | |
| 5 | **Always pass `skillNames: "figma-use-motion"` (comma-separated alongside `figma-use`) when calling `use_figma` for motion work.** Logging only. |
| 6 | |
| 7 | ## Runtime Gating |
| 8 | |
| 9 | Motion APIs are gated behind the `metronome` user feature flag. When the calling user doesn't have it, every motion property and helper referenced in this skill throws `"<name>" is not a supported API`. |
| 10 | |
| 11 | **Bail out fast on that error.** Do not retry; tell the user motion isn't enabled for them and stop. Otherwise you'll burn calls and confuse the user with repeated identical failures. |
| 12 | |
| 13 | ## When to use this skill |
| 14 | |
| 15 | Load this skill whenever a `use_figma` task involves: |
| 16 | |
| 17 | - Adding, editing, or removing keyframes on a node (`manualKeyframeTracks`, `applyManualKeyframeTrack`, `removeManualKeyframeTrack`). |
| 18 | - Animating fill or stroke colors over time. |
| 19 | - Applying, editing, or removing animation styles (`applyAnimationStyle`, `removeAnimationStyle`, `animationStyles`). |
| 20 | - Reading or writing timeline duration via `node.timelines` / `node.setTimelineDuration(id, seconds)`. |
| 21 | - Choosing easing for any of the above. |
| 22 | |
| 23 | Static design work (creating shapes, components, variables, layout) goes through [figma-use](../figma-use/SKILL.md) alone — this skill is only for the time dimension. |
| 24 | |
| 25 | ## Exposed motion API surface |
| 26 | |
| 27 | - `node.manualKeyframeTracks` — read/write manual keyframes (including fill, stroke, and effect tracks). |
| 28 | - `node.applyManualKeyframeTrack(field, track)` / `node.removeManualKeyframeTrack(field)` — add, replace, or remove one manual keyframe track without rewriting the whole object. |
| 29 | - `node.animationStyles` — read/write animation-style metadata applied to a node. |
| 30 | - `node.applyAnimationStyle(styleId, presetData?)` / `node.removeAnimationStyle(id)` — apply a discovered style and remove an applied style instance by its returned/read-back `id`. |
| 31 | - `node.timelines` — read-only timeline list for the containing top-level frame, with durations in seconds. |
| 32 | - `node.setTimelineDuration(id, durationSeconds)` — write the containing top-level frame timeline duration. |
| 33 | - `node.animations` — read-only resolved keyframe data (currently manual tracks only — see [motion-patterns.md](references/motion-patterns.md)). |
| 34 | - `figma.motion.figmaAnimationStyles()` — read-only list of Figma's first-party animation styles. |
| 35 | |
| 36 | Authoring custom `"figma:motion"` preset module source code is out of scope. If the user wants a brand-new animation style, say so and stop; don't fabricate one. |
| 37 | |
| 38 | ## Reference docs |
| 39 | |
| 40 | Load these as needed based on what the task involves: |
| 41 | |
| 42 | | Doc | When to load | What it covers | |
| 43 | |-----|-------------|----------------| |
| 44 | | [motion-patterns.md](references/motion-patterns.md) | Adding/editing motion animation | Manual keyframes, animated fills/strokes, applying animation styles, timeline duration | |
| 45 | | [motion-easing.md](references/motion-easing.md) | Setting animation easing | Keyframe easing objects, custom cubic/spring, `HOLD`, applying easing inside an animation style | |
| 46 | |
| 47 | ## Verifying the animation |
| 48 | |
| 49 | `get_screenshot` shows only the timeline's **resting state**, never motion. To check motion, `export_video` and sample frames — but it renders server-side and is **slow and expensive (~10s to minutes)**, so make each render count. |
| 50 | |
| 51 | **Plan before rendering — cost scales with pixels × frames, so keep both no larger than the frames need:** |
| 52 | |
| 53 | 1. **Pick the moments first.** You need one frame per *phase* (e.g. per stagger step, or start / mid / settle), not smooth playback — usually 4–6. This count sets your fps. |
| 54 | 2. **Size to what you must read.** Start small — `constraint: { type: 'WIDTH', value: 320 }`, `quality: "low"` — but text and small elements blur there, so raise `WIDTH` (768+) when you need to judge fine detail. Omitting `constraint` = full size (1x; server clamps to 10x / 4096px). |
| 55 | 3. **Set fps just high enough to land those frames:** `fps: 5` covers a handful; 10 is an upper bound. Higher just bloats the render. |
| 56 | |
| 57 | **Mechanics:** `export_video` works only on a **top-level frame** whose children carry the animation (pass that frame, not the descendant you keyframed). It returns a `jobId` with `status: "processing"` — re-invoke with `{ fileKey, jobId }` to poll. Then extract frames locally with `ffmpeg -ss <t> -i anim.mp4 -frames:v 1 frame_<t>.png` — extraction is free, so once you've paid for the render, mine it for every frame that tells you something rather than re-exporting. Without a frame extractor like `ffmpeg`, skip the export and reason about the keyframes i |