Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Motion / 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.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | -39% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 46% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 91% | 0% |
| case-19 | ✗→✓ | ▲ Improved | 239% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 173% | 0% |
Motion context for the use_figma MCP tool. figma-use covers the foundational Plugin API rules — load both together.
Always pass skillNames: "figma-use-motion" (comma-separated alongside figma-use) when calling use_figma for motion work. Logging only.
Motion APIs are gated behind the metronome_plugin_api 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.
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.
Load this skill whenever a use_figma task involves:
manualKeyframeTracks, applyManualKeyframeTrack, removeManualKeyframeTrack).applyAnimationStyle, removeAnimationStyle, animationStyles).node.timelines / node.setTimelineDuration(id, seconds).Static design work (creating shapes, components, variables, layout) goes through figma-use alone — this skill is only for the time dimension.
node.manualKeyframeTracks — read/write manual keyframes (including fill, stroke, and effect tracks).node.applyManualKeyframeTrack(field, track) / node.removeManualKeyframeTrack(field) — add, replace, or remove one manual keyframe track without rewriting the whole object.node.animationStyles — read/write animation-style metadata applied to a node.node.applyAnimationStyle(styleId, presetData?) / node.removeAnimationStyle(id) — apply a discovered style and remove an applied style instance by its returned/read-back id.node.timelines — read-only timeline list for the containing top-level frame, with durations in seconds.node.setTimelineDuration(id, durationSeconds) — write the containing top-level frame timeline duration.node.animations — read-only resolved keyframe data (currently manual tracks only — see motion-patterns.md).figma.motion.figmaAnimationStyles() — read-only list of Figma's first-party animation styles.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.
Load these as needed based on what the task involves:
| Doc | When to load | What it covers | |-----|-------------|----------------| | motion-patterns.md | Adding/editing motion animation | Manual keyframes, animated fills/strokes, applying animation styles, timeline duration | | motion-easing.md | Setting animation easing | Keyframe easing objects, custom cubic/spring, HOLD, applying easing inside an animation style |
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.
Plan before rendering — cost scales with pixels × frames, so keep both no larger than the frames need:
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).fps: 5 covers a handful; 10 is an upper bound. Higher just bloats the render.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 instead.
Iterate until it's right. The export is a diagnostic, not a sign-off: if the frames are wrong (bad order, off timing, a missing element, a mask blanking the composite), fix the keyframes/styles and re-export. Read all the frames and batch every fix into one pass before re-rendering — every render carries real overhead, so make each one count instead of re-exporting after each small change.
Skip the export entirely for trivial or self-evident changes.
In addition to the figma-use pre-flight checklist, verify:
{ type: 'EASE_OUT', easingFunctionCubicBezier?: …, easingFunctionSpring?: … } shape — not internal scenegraph names like OUT_CUBIC.EASE_IN_AND_OUT (or EASE_IN_AND_OUT_BACK); never emit the invalid alias EASE_IN_OUT.setTimelineDuration; never shorten unless the user asked.TRANSLATION_X, TRANSLATION_Y, ROTATION, SCALE_X, SCALE_Y, SCALE_XY), not internal MOTION_* scenegraph names.figma-use Rule 15).ffmpeg) is available, verify via export_video + frame sampling — render small, low fps, iterate until right (see the Verifying the animation section above). get_screenshot shows only the resting state.Other measured skills in the registry, with their headline benchmark lift.