How to Generate UI Animations with Cursor and Exode MCP
Cursor UI animation work goes through the Exode MCP server: add claude-exode-mcp to .cursor/mcp.json as a stdio server, reload Cursor, and ask its agent for the motion in plain language. Cursor then calls Exode tools to add the objects, keyframes, springs, inputs and transitions to your .exode file, and you review the timing in the ExodeUI editor before exporting.
This guide is about producing animation in Cursor, not about installing the server. If the connection itself is failing, the setup walkthrough covers the mcp.json entry and the reload step.
The short version: Cursor is good at the part where you describe a state machine and it writes the graph. It is not good at judging how the easing feels, because it cannot see the result. Plan for one review pass in the editor.
Add the Exode server to Cursor
Cursor reads custom servers from mcp.json, either project-level at .cursor/mcp.json or through the Customize page in the app. A local command server uses type "stdio" with a command and args. The entry for Exode runs npx with the claude-exode-mcp package.
After saving, reload Cursor and confirm that the exode server shows its tools. If the entry is there but the tools are not, the usual cause is a missing or outdated Node.js, so that npx cannot start the package.
{
"mcpServers": {
"exode": {
"type": "stdio",
"command": "npx",
"args": ["-y", "claude-exode-mcp"],
"env": { "WORKSPACE_ROOT": "/Users/you/projects/motion" }
}
}
}Ask for the animation, not the code
Cursor defaults to writing React or CSS, because that is what most of its context is. If you want motion in the .exode file, say so in the first sentence and name the file. Something like "in artboards/card.exode, add an entrance for the card" is clearer than "animate this card".
Name the parts that decide the shape of the animation: what moves, which states exist, which input drives them, and how it should feel. Numbers are useful for the spring, but they are easier to tune later than to guess correctly.
A prompt that produces a usable animation
This prompt gives the agent an object, two states, one input and a feel. Those are things the Exode tools can express, so Cursor has somewhere to put each instruction.
In artboards/pricing-toggle.exode, take the object named PlanCard.
Add a boolean input "isYearly".
Create two states, Monthly and Yearly.
When isYearly becomes true, switch to Yearly; when false, back to Monthly.
On the card, animate a 12px upward shift with a spring that overshoots
a little and settles — snappy, not bouncy. Keep the existing press behaviour.Behind that prompt, Cursor will typically call add_input for the boolean, create two states, wire add_transition with a condition on the input, and create_spring_animation or animate_properties for the movement. You can watch the calls in the agent panel, which is also the fastest way to learn what the server can do.
Review the result in the editor
Open the .exode file in ExodeUI. Play the transition and look at three things: whether the overshoot reads as intentional, whether the timing matches the rest of the product, and whether the states are reachable in every combination of inputs.
Two tools help before you open anything: validate_artboard checks cross-references such as transitions that point at missing states, and lint_artboard finds structural problems and can fix some of them. Asking Cursor to run them is faster than hunting for a broken reference by hand.
- Ask for validate_artboard on the file whenever you add states or transitions.
- Ask for lint_artboard with autoFix when a transition does nothing.
- Ask for get_artboard_summary to see what the agent actually built, in one screen.
Ship it
When the motion is right, export_react_code gives you a self-contained React component. For other targets, the same .exode file plays through the runtime packages for Vue, Svelte, Angular, Solid, React Native, SwiftUI and Flutter, so the animation is not rewritten per platform.
If the export is going into a Next.js app, keep the canvas in a client component. The export itself does not know about your routing or your server components.
When Cursor is the wrong tool
If the animation is a one-off hover effect that lives entirely in code, a CSS transition or Framer Motion is less machinery. Cursor can write that without any MCP server, and you will not maintain a second file.
If the work has to be tuned by a designer who does not use Cursor, the editor is the better surface. Use Cursor for the structural pass, the states and the wiring, and let the designer own the curves.
Rive documents its own MCP server for its editor. If your team already builds in Rive, connecting that one makes more sense than moving the work.
Frequently asked questions
We make ExodeUI and its MCP server. Treat what an agent produces as a draft, the same way you would treat code from a new teammate.
ExodeUI runs in the browser and on desktop. One .exode file plays in React, Vue, Svelte, Angular, Solid, React Native, SwiftUI and Flutter.