# rive-mcp [Health: Active]

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/ODU33104/rive-mcp  
**GitHub Stars:** 26  
**npm Downloads (last month):** 3014  
**Views:** 8  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/rive-mcp

## Description
Free, editor-less MCP server for Rive: create, edit, inspect, render and preview .riv animations

## Tools
Capabilities this server exposes over MCP:

- **riv_list** — Recursively find .riv files under a directory and report size and format version for each.
- **riv_inspect** — Extract full metadata from a .riv file: artboards, animations (duration/fps/loop), state machines and their inputs (name/type/initial value). Uses the official Rive runtime. Also decodes Data Binding (ViewModel) structure when present — ViewModel definitions and their properties, ViewModelInstances with resolved property values (including enum/nested-viewmodel/list references), enums, converters, and DataBind wiring (which target object/property each bind writes to) — via direct binary parsing (returned as `dataBinding`, omitted when the file has none).
- **riv_render_frame** — Render one frame of a .riv animation or state machine to PNG. Returns the image inline and saves it to disk.
- **riv_render_gif** — Render a .riv animation (or state machine idle playback) to an animated GIF file for preview.
- **riv_render_apng** — Render a .riv animation (or state machine playback) to an animated PNG (APNG). Unlike GIF this supports 24-bit color plus full alpha transparency, and GitHub READMEs animate it like a regular image. Frames are rendered with a transparent background by default.
- **riv_play_state_machine** — Run a .riv state machine step by step: set/fire inputs, advance time, observe state transitions, and optionally capture frames. Returns a transition report.
- **riv_generate_code** — Generate ready-to-use integration code (React/Vue/Svelte/plain JS/Flutter) for a .riv file, using its real artboard, state machine and input names.
- **riv_dump** — Low-level dump of a .riv file's object stream (typeKeys, property values, hierarchy). Useful for debugging and format research. Large files return a summary unless full=true.
- **riv_lint** — Static diagnostic pass over a .riv file: broken/out-of-range references, oversized embedded assets, state-machine states unreachable by any transition, unconditional self-transitions (infinite-loop risk), unused state-machine inputs, keyframe easing silently discarded on a track's last keyframe, plus motion-quality rules (all-linear robotic movement, teleporting objects, missing stagger on simultaneous fade-ins, one-sided scale animation). Complements riv_dump (which shows raw structure but doesn't judge it).
- **riv_design_tokens** — Deterministically generate professional design tokens for a scene BEFORE calling riv_create: an OKLCH-harmonized palette (with WCAG contrast ratios), gradient pairs, Material-Motion-derived durations & easing roles, spacing/radius/stroke scales and a type scale. Call this first, then use ONLY the returned values in the scene spec — never invent raw hex colors or ad-hoc durations. Inputs: optional seed color, mood (calm|playful|elegant|tech|warm|natural), scheme (dark|light).
- **riv_critique** — One-call review bundle for the render→critique→revise loop. Returns (1) a FILMSTRIP image — N frames left→right across the duration, so motion is readable as a sequence, (2) an ONION-SKIN image — all frames ghost-overlaid so every mover leaves a visible trail (use it to check trajectories and travel direction vs the artwork's facing), (3) a MOTION REPORT — net displacement/rotation vector per animated object computed from the file data, (4) objective design metrics + lint findings, and (5) a fixed 7-axis scoring checklist (incl. spatial/directional coherence). LOOK at the images, score each axis 1-5, fix anything below 4 (riv_edit / regenerate), then re-run. Iterate at least twice before delivering any non-trivial scene.
- **riv_import_svg** — Convert an SVG file (Figma/Illustrator export, icon, illustration) into Rive bezier path shapes — the professional way to get high-quality artwork instead of drawing with primitives. Writes a scene-fragment JSON (shapes with full cubic vertices, gradients, strokes) and returns a rendered preview. Use the fragment in riv_create via "imports". Supports path/rect/circle/ellipse/polygon/polyline/line, nested transforms, style attrs, linear/radial gradients. Not imported: <text> (use texts[] with a font), <image>, filters, masks.
- **riv_asset_search** — Search Iconify's ~200k professionally designed open-source icons and convert one directly into Rive shapes. Two modes: query-only returns matching icon names; icon+outSpec downloads the SVG and imports it (same output as riv_import_svg). Requires network access to api.iconify.design.
- **riv_lottie_import** — Convert a Lottie (bodymovin, .json) animation — the format used by LottieFiles' huge library of free, professionally animated assets — into a riv_create scene fragment. Unlike riv_import_svg (shapes only), this carries over the professional's actual choreography: keyframed position/rotation/scale/opacity with their exact bezier easing curves (not approximated to a named preset), shape/null/precomp layer hierarchy, solid layers, gradient fills, stroke trim-path animation, and layer in/out visibility windows. Writes a scene-fragment JSON with {groups,shapes,animations} plus a rendered preview and a coverage/warnings summary. Since the fragment includes animations (which riv_create's "imports" mechanism does not merge), splice its groups/shapes/animations arrays directly into your riv_create scene spec instead of using "imports". Supported: shape layers (path/ellipse/rect/star/polygon/fill/stroke/gradient/trim/nested groups), null layers, solid layers, one level of precomp inlining, parented layers, hold and bezier easing. Not imported (counted in coverage.skipped, not silently dropped): text layers, masks, track mattes, repeaters, merge-paths, path/gradient-position keyframe morphing (frozen to first frame + warning), time-remapped precomps, expressions.
- **riv_decompile** — Reverse a .riv file into a riv_create scene spec (shapes with bezier vertices, solid/gradient fills incl. gradient opacity, blend modes, artboard background, groups/solos, trim paths, clipping, animations with named easings, loop modes). Paint objects are resolved by parentId, so editor-authored files (paints deferred to the stream tail) decompile correctly. Use it to study professional files as few-shot examples, or to remix them — art AND hand-tuned animation tracks — into new scenes (decompile → edit spec → riv_create; see samples/night-delivery). Object types outside the writer's coverage are counted in 'skipped', not silently dropped. Note: community/marketplace files are CC BY 4.0 — keep attribution.
- **riv_create** — Create a working .riv animation file from scratch (no Rive editor needed) and validate it with the official runtime. Returns a rendered preview frame.
For non-flat, non-"AI placeholder" quality (gradients, organic bezier curves, proper easing, springy motion), read the "rive-design-guidelines" prompt this server exposes before designing a non-trivial scene.
Scene spec example:
{
  "artboard": {"name":"Demo","width":400,"height":300},
  "backgroundColor": "#1a1a2e",
  "shapes": [
    {"id":"box","type":"rect","x":120,"y":150,"width":80,"height":80,"cornerRadius":12,"rotation":0,"opacity":1,
     "fill":{"color":"#e94560"},"stroke":{"color":"#fff","thickness":3}},
    {"id":"ball","type":"ellipse","x":280,"y":150,"width":70,"height":70,
     "fill":{"gradient":{"type":"linear","stops":[{"color":"#00d9ff"},{"color":"#0066ff"}]}}},
    {"id":"tri","type":"polygon","x":200,"y":100,"points":[{"x":0,"y":-40},{"x":35,"y":20},{"x":-35,"y":20}],"fill":{"color":"#ffd700"}}
  ],
  "animations": [
    {"name":"spin","fps":60,"duration":60,"loop":"loop","tracks":[
      {"target":"box","property":"rotation","keyframes":[{"frame":0,"value":0},{"frame":60,"value":360,"easing":"linear"}]},
      {"target":"ball","property":"y","keyframes":[{"frame":0,"value":150},{"frame":30,"value":80,"easing":"ease-out"},{"frame":60,"value":150,"easing":"ease-in"}]}
    ]}
  ],
  "stateMachine": {"name":"SM","inputs":[{"name":"go","type":"bool"}],
    "states":[{"name":"spinning","animation":"spin"}],
    "transitions":[{"from":"entry","to":"spinning","condition":{"input":"go"}}]}
}
Character animation (images/groups/mesh):
{
  "groups": [{"id":"rig","x":300,"y":200}],
  "images": [{"id":"chara","pngPath":"./cat.png","x":0,"y":0,"scale":0.25,"parent":"rig",
    "mesh":{"columns":6,"rows":6}}],
  "animations": [{"name":"idle","duration":240,"loop":"loop","tracks":[
    {"target":"rig","property":"y","keyframes":[{"frame":0,"value":200},{"frame":120,"value":195,"easing":"ease-in-out"},{"frame":240,"value":200,"easing":"ease-in-out"}]},
    {"target":"chara#v0_3","property":"x","keyframes":[{"frame":0,"value":0},{"frame":120,"value":40,"easing":"ease-in-out"},{"frame":240,"value":0,"easing":"ease-in-out"}]}
  ]}]
}
- images[].pngPath: PNG file embedded into the .riv. mesh enables vertex deformation; vertices addressed as "<imageId>#v<row>_<col>" (row 0 = top), coordinates in the image's natural pixel space centered at origin. Mesh vertex tracks support x/y only.
- groups are Nodes usable as parents (parent) of shapes/images for rig hierarchies and pivots; animatable like shapes.
- transitions support exitTimeMs (play source animation this long before transitioning).
Motion presets — PREFER these over hand-authored keyframes (professionally tuned amplitudes/easings, ~10x fewer tokens):
"animations":[{"name":"intro","duration":90,"presets":[
  {"preset":"pop-in","target":"logo"},
  {"preset":"rise-in","targets":["c1","c2","c3"],"at":12,"stagger":4},
  {"preset":"float","target":"logo"}
],"tracks":[]}]
Available: fade-in rise-in drop-in slide-in pop-in bounce-in | fade-out sink-out slide-out pop-out | pulse heartbeat tada shake wobble | breathing float sway spin glow-pulse blink(for eyelid overlays). Options: at(start frame), stagger(frames between targets), intensity(0.25-3), direction(left|right|up|down), cycleSeconds. Ambient presets (breathing..blink) span the whole animation seamlessly. A preset and a manual track must not drive the same target+property.
Pro features: stroke.trim {start,end,mode} + trimStart/trimEnd tracks (draw-on effect), shapes[].clipBy (mask via an invisible shape), groups[].solo+active + soloActive track with keyframes[].ref (pose/mouth switching), constraints [{type:"followPath",item,path}] + followDistance track 0-1 (motion along a path), open paths (closed:false), multi-contour shapes (subpaths), stroke cap/join.
"imports":[{"spec":"logo.scene.json","x":200,"y":150,"scale":0.8}] places riv_import_svg / riv_asset_search fragments under a wrapper group (id = file basename) — animate the wrapper or individual shape ids. PREFER imported real vector art over drawing with primitives for anything illustrative.
Recommended flow: riv_design_tokens → (riv_import_svg / riv_asset_search for artwork) → riv_create (token values + presets + imports) → riv_critique → fix → re-critique.
Shape z-order: later in array = on top; images render above shapes. properties for tracks: x,y,rotation(deg),scaleX,scaleY,opacity(0-1),width,height,fillColor(needs "color" in keyframes). Colors: #RRGGBB or #AARRGGBB. rotation in degrees. Easings include emphasized-decel (enters) / emphasized-accel (exits).
Audio: "audio":[{"id":"beep","path":"./beep.wav"}] embeds a WAV/MP3/FLAC file (path resolved relative to cwd, or pass bytes directly). "events":[{"id":"beepEvent","type":"audio","audio":"beep"}] declares an AudioEvent bound to that clip. Trigger it either from a state machine state ("states":[{"name":"s1","fireEvent":"beepEvent"}]) or at specific frames inside a timeline via animations[].events: {"name":"anim1","duration":60,"tracks":[...],"events":[{"event":"beepEvent","frame":0},{"event":"beepEvent","frame":30}]}. NOTE: playback support depends on the runtime — this server's own preview (a Canvas2D-based renderer) does not play audio, so rendered PNG/GIF/video previews and riv_studio will stay silent even though the AudioAsset/AudioEvent are written correctly and will play in a GPU-backed Rive runtime (WebGL/Skia, e.g. rive.app or the production player).
- **riv_edit** — Modify an existing .riv (lossless roundtrip): set any property, change named text runs, delete objects (with automatic subtree + reference remapping), or edit keyframes on an existing animation (op=setKeyframes). Use riv_dump to find object indices/names. Renders a preview of the result.
setKeyframes: target an animated object via index/name(+type), give 'animation' (LinearAnimation name) and 'property' (x/y/rotation/scaleX/scaleY/opacity/width/height — rotation in degrees), then 'keyframes' (array of {frame,value,easing}). 'mode': replace (default, swaps the whole track) | add (appends keyframes, creating the track if absent) | remove (deletes keyframes matching the given frame numbers; keyframes[].value/easing are ignored).
- **riv_optimize** — Shrink a .riv without changing its visual output: remove unreferenced objects (dangling easing interpolators, fired-events nothing points to, empty keyframe tracks left over from prior edits) and thin redundant keyframes on strictly-linear-interpolation runs within a tolerance. Only runs where every segment is linear are touched — any run touching hold/cubic easing is left alone, so no easing gets shifted (see keyed_property.cpp semantics: a KeyFrame's interpolationType applies to the segment going INTO the next frame). Colors and id-keyframes (soloActive) are never thinned, only numeric (KeyFrameDouble) tracks. All steps are opt-in booleans (default: all on) and idempotent/safe to run repeatedly. Use dryRun=true to see the removal/thinning plan without writing anything. Run riv_lint afterwards if in doubt.
- **riv_slice_image** — Cut polygon regions out of a character PNG for parts-based rigging (cutout animation). Writes each part as <name>.png plus base.png (source with parts erased) into outDir, and returns each part's bbox for placement. Use with riv_create: images per part + groups as pivots.
- **riv_rig_character** — One call: character PNG -> fully rigged .riv with cutout parts (ears/tail via polygons), 2-bone head-tilt mesh (seamless), vector eyelid blink, idle + happy animations, and a state machine with a 'happy' trigger. Returns a preview. Fine-tune afterwards with riv_edit or riv_studio.
- **riv_diff** — Structural diff between two .riv files: type count changes and per-object property differences.
- **riv_render_video** — Render a .riv animation (or state machine) to a real-time WebM video using canvas.captureStream() + MediaRecorder (VP9, falls back to VP8/generic webm). Default duration is one loop of the animation (2s for a bare state machine or when the animation's length can't be determined).
- **riv_render_sprites** — Render N evenly-spaced frames of a .riv animation/state machine into a single grid sprite sheet PNG (columns = ceil(sqrt(N))). Writes the PNG plus a JSON metadata file (cellW/cellH/cols/rows/count/fps) alongside.
- **riv_batch_render** — Render a list of jobs — each a single .riv (rivPath) or a glob of .riv files (glob) — to png/gif/apng/webm/sprites, sequentially reusing the same headless Chromium page (no parallel pages). Built for CI/scripts: call this tool repeatedly from your pipeline instead of expecting a live watch mode — none is provided, since MCP's request/response model doesn't fit a background file watcher. 'defaults' holds options shared across every job; each job's own fields override them. One job's failure does not stop the batch — every job (and every file a glob expands to) gets its own success/error/outPath/durationMs entry in the returned report.
- **riv_extract_assets** — Extract embedded image/font/audio asset binary contents (ImageAsset/FontAsset/AudioAsset + FileAssetContents pairs) from a .riv file to disk, with the file extension inferred from magic bytes (PNG/JPEG/WEBP/TTF/OTF/WOFF/WOFF2/GIF). Externally-referenced (non-embedded) assets are skipped.
- **riv_visual_diff** — Render the same artboard/animation/time from two .riv files under identical conditions (forced to the same output size) and compute a thresholded per-pixel visual diff. Returns match rate, differing pixel count, and a diff visualization PNG (differing pixels in red, matching pixels dimmed).
- **riv_ab_compare** — Render the same artboard/animation/state-machine from two .riv files under identical conditions and composite them side by side (horizontal or vertical) into a single GIF/APNG for human review — e.g. a rig before/after an edit, or two design variants. 'A: <file>' / 'B: <file>' labels are burned into each frame by default. If the two files' animation lengths differ, the shorter one holds on its final frame once it ends. Different from riv_visual_diff: that tool computes a per-pixel numeric diff of the SAME thing rendered two ways (for regression testing); this tool is for eyeballing two DIFFERENT things playing side by side (for design review), not measuring a delta.
- **riv_studio** — Start a local web UI (Rive-editor-like 3-pane layout) for live-previewing and editing a .riv file: hierarchy tree + click/drag selection on canvas + inspector (position/size/color/text edits apply live), timeline with keyframe markers, hot reload on file change, auto-generated state machine input controls, event log, and (with scenePath) direct scene-JSON editing. The UI also has an 'Instructions for AI' box — fetch those with riv_studio_notes. Re-running riv_create/riv_edit on the watched file updates the browser instantly. Only one studio runs at a time.
- **riv_studio_notes** — The Studio web UI's Agent panel is a two-way chat. Use this tool for both halves of it.
1) READ: call with no `reply` to fetch the messages the user typed (consumes the queue; the Studio shows them as picked up). Trigger on 'check the studio notes' / 「スタジオの指示を確認して」, or after opening riv_studio when the user mentions they left notes. Act on each instruction — usually riv_edit or riv_create on the watched file, which hot-reloads the browser.
2) REPLY: after doing the work, call again with `reply` set to a short summary of what you changed (and anything you could not do). It appears as your message in the same chat. ALWAYS reply — otherwise the user is left staring at the Studio with no idea whether you acted. Both can be done in one call: pass `reply` together with the read to answer and pick up anything new at the same time.
- **riv_ui_detect** — Find the rectangles, text runs and images in a UI screenshot or design comp. Returns a nested element tree with rects, corner radii and fill colours, plus a numbered overlay PNG. Coordinates come back in the source resolution but are recovered from a downscaled analysis, so expect a pixel or two, and corner radii within about a pixel. Each element carries renderMode ("vector-panel" | "raster" — how it would be reconstructed; flat fills are test-rendered and turned into crops when more than 2% of their visible pixels would differ, the measured share is returned as renderRisk) and semanticHint ("panel" | "text" | "image" | "line" — what it looks like) as independent fields. Look at the overlay, give each element a role, and pass the result to riv_ui_prototype to get an animated .riv. This is geometry only — it does not know a button from a card. If you have the vector source, pass svgPath instead of imagePath: nothing is estimated, the element tree is the SVG's own group nesting, non-rectangular artwork comes through as "vector-shape" with its real bezier vertices, <text> becomes "vector-text" (editable Rive text — the bundled Inter is substituted unless you pass fonts, and a run whose glyphs are missing is baked as a picture instead, always with a warning), embedded <image> data comes through as its own pixels, and Figma layer names arrive as roleHint.
- **riv_ui_prototype** — Take the elements from riv_ui_detect, assign each one a role, and get back a working .riv: every element becomes a shape or an image asset, each gets an entrance appropriate to its role, and buttons and cards get hover and press states. Roles: background, nav, header, card, panel, button, fab, text, icon, image, chart, list-item, badge, divider, avatar, input. Elements you leave unassigned animate as a generic panel. Pass the same imagePath (or svgPath), minArea and maxElements you gave riv_ui_detect, or the ids will not line up. With svgPath no screenshot is embedded, every element stays editable, and the file reproduces the SVG; its <text> becomes real Rive text you can re-type at runtime, and its embedded <image> data becomes an image asset. figmaUrl fetches the same thing straight from Figma, and needs FIGMA_TOKEN.
- **riv_setup** — One-time setup: copies the bundled `rive-design-guidelines` skill (the mandatory tokens → pro-asset ingestion → presets → critique workflow, asset-source registry, icon-animation recipes and craft rules) into the client's skills directory so it auto-triggers on future Rive work — .claude/skills/ in the current project (scope=project, default) or ~/.claude/skills/ for all projects (scope=user). Idempotent: re-running updates the skill to this server version's copy. Recommended on first use of this server in a new environment; clients without skill support can read the same content via the rive-design-guidelines MCP prompt instead.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "rive-mcp": {
    "command": "npx",
    "args": ["-y","rive-mcp-server"]
  }
}
```

## Documentation

## What rive-mcp MCP server does

Rive animation work can be performed directly against `.riv` files: create scenes from JSON, make lossless edits, inspect internal structure, render previews, and compare revisions. `riv_create` produces a validated animation file and preview without requiring the Rive editor. Scene specifications can include shapes, gradients, text, images, groups, mesh deformation, animations, state machines, events, audio assets, constraints, clipping, trim paths, and motion presets.

Existing files can be studied with `riv_inspect`, `riv_dump`, and `riv_decompile`. Decompilation turns supported artwork and animation tracks into an editable scene specification, while inspection also exposes state machines, animation metadata, and Data Binding structures such as ViewModels, resolved instances, enums, converters, and bind wiring.

## How it works

The server runs locally and uses the official Rive runtime through `@rive-app/canvas-advanced` WASM in headless Chromium for rendering. Rendered output can be returned inline or written to disk, depending on the tool. State machines can be exercised step by step by setting or firing inputs, advancing time, observing transitions, and optionally capturing frames.

A typical creation workflow starts with `riv_design_tokens`, then imports artwork with `riv_import_svg`, `riv_asset_search`, or `riv_lottie_import`, and passes the resulting material to `riv_create`. `riv_critique` produces filmstrip and onion-skin images, motion measurements, lint results, and a seven-axis review checklist for an iterative render-and-revise process.

## Tools and capabilities

- Find, inspect, dump, lint, decompile, diff, optimize, and extract assets from `.riv` files.
- Render frames, GIFs, APNGs, WebM videos, and sprite sheets, including batch jobs over files or globs.
- Create and edit animations, state machines, text, keyframes, embedded assets, audio events, and character rigs.
- Import SVG paths, Iconify icons, Lottie scene fragments, and PNG-based character parts.
- Start a local Studio with hierarchy, canvas, inspector, timeline, hot reload, state-machine controls, and an AI notes channel.
- Generate React, Vue, Svelte, plain JavaScript, or Flutter integration code using names found in the actual file.
- Compare files visually or structurally, including labeled side-by-side animation comparisons.

## Limitations and notes

Audio assets and events can be written into `.riv` files, but the server's Canvas2D-based previews do not play audio. Playback requires a GPU-backed Rive runtime such as WebGL or Skia.

SVG import does not cover text, images, filters, or masks. Lottie import reports unsupported text layers, masks, track mattes, repeaters, merge paths, expressions, time-remapped precomps, and some morphing features rather than silently including them. `riv_asset_search` requires network access to Iconify's API.

Batch rendering is request-driven and has no background watch mode. Studio permits only one running instance at a time. Community or marketplace files handled through decompilation are under CC BY 4.0 and require attribution.

_Full upstream README: https://allmcps.com/mcp/rive-mcp/readme_

