cavalry-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@cavalry-mcpcreate a 1920x1080 rectangle layer and set its fill color to #101828"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
cavalry-mcp
Low-token Cavalry automation through Stallion. Build complete motion rigs in one atomic script, use procedural presets, or bypass MCP schemas entirely with the CLI.
Agent <--MCP/CLI--> cavalry-mcp <--POST /post + GET /get--> Stallion <---> CavalryThree-tool core
Only these tools are exposed by default:
Tool | Purpose |
| Batched JavaScript with |
| Bounded id/name/niceName/type summaries for |
| One-shot procedural rigs with custom JSON parameters |
const title = _mg.text("MOTION", 110, "#FFFFFF");
const rig = _mg.subMesh(title, 1, 8);
_mg.kf(title, "scale", [[0, 0], [30, 100]]);
return { title, ...rig };Set ENABLE_LEGACY_TOOLS=true to restore the original granular tools. They are intentionally off by default to minimize MCP schema tokens and network round-trips.
Related MCP server: cavalry-mcp
Zero-MCP CLI
node bin/stallion-cli.mjs -e 'return _mg.text("FAST", 96);'
node bin/stallion-cli.mjs -f ./rig.js
node bin/stallion-cli.mjs -p kinetic_text '{"text":"HELLO"}'
node bin/stallion-cli.mjs --selInstall the package to expose the stallion command. Run npm run build after changing source because the CLI imports dist/.
Procedural presets
The registry ships 120 presets across 14 categories — a complete SaaS motion-graphics library. Every preset is a self-contained rig executed as one isolated IIFE inside api.startUndoGroup("AI Motion Batch") / api.endUndoGroup() with try/finally. The script returns a map of role → layer ID plus preset: "<id>", so you can keep animating the pieces it built.
# | Category | Label | Presets |
1 |
| Hero Typography & Messaging | 5 |
2 |
| UI Components & Product Mockups | 5 |
3 |
| Data Visualization & KPI | 5 |
4 |
| Backgrounds, Transitions & Camera | 5 |
5 |
| AI Agents, LLMs & Copilot | 10 |
6 |
| Developer Tools, Code & Terminal | 10 |
7 |
| Multiplayer Collaboration & Presence | 10 |
8 |
| Workflow Automation & Node Graphs | 10 |
9 |
| Fintech, Payments & Billing | 10 |
10 |
| Security, Auth & Identity | 10 |
11 |
| Cloud, DevOps & Infrastructure | 10 |
12 |
| Voice, Audio & Video | 10 |
13 |
| Onboarding & Product-Led Growth | 10 |
14 |
| Social Proof & Call-to-Action | 10 |
node bin/stallion-cli.mjs --list # all 120 presets
node bin/stallion-cli.mjs --list fintech_billing # one category
node bin/stallion-cli.mjs -p payment_card_checkout '{"amount":"$99.00","accentColor":"#22D3EE"}'From MCP, call cavalry_run_preset with { "preset": "payment_card_checkout", "params": { ... } }. Presets are stored as category packs in src/presets/packs/cat01…cat14, composed from shared factories in src/presets/rig_builders.ts, and can also be driven programmatically via compilePreset(id, params) / listPresets(category?) from src/presets/cavalry_snippets.ts (the lightweight listing keeps the three-tool MCP schema small).
Every preset runs with default {} parameters. Parameters declare types string, int, double, bool, color (hex string) and json (object/array). Accepted aliases: bento_grid and spring_card → bento_cards, counter_rig → number_counter, bg_grid → dot_matrix_bg.
Categories 9–14 and presets 59–60 extend the original 58-preset brief (its spec stopped at preset 58). They follow the same conventions — _rb factories, verified Cavalry 2.8 attribute paths, floor-pinned bars, one guarded Undo group — and their layouts/parameters were designed to be consistent with the brief rather than transcribed from it.
Cavalry and _mg TypeScript declarations live in types/cavalry.d.ts; repository-specific automation rules are in AGENTS.md and .cursorrules.
Prerequisites
Cavalry 2.8+ with the Stallion script enabled: Scripts > Stallion (must be re-started each Cavalry session)
Node.js >= 18.17
Install
git clone https://github.com/akspro9866-art/cavalry-mcp.git
cd cavalry-mcp
npm install
npm run buildConfigure in ZCode
Add to ~/.zcode/cli/config.json:
{
"mcp": {
"servers": {
"cavalry": {
"command": "node",
"args": ["<path-to>/cavalry-mcp/dist/index.js"]
}
}
}
}Claude Desktop / Cursor
{
"mcpServers": {
"cavalry": {
"command": "node",
"args": ["<path-to>/cavalry-mcp/dist/index.js"]
}
}
}Tools appear as mcp__cavalry__<tool_name>.
Environment variables (all optional)
Variable | Default | Purpose |
|
| Stallion base URL |
| empty | Optional bearer token matching |
|
| Legacy URL configuration |
|
| Abort timeout for every HTTP request |
|
| Overall structured-result wait; increase for slow renders |
| (legacy) | Sets both timeouts at once |
|
| Legacy fallback result file |
|
| Restore the original granular MCP tools |
Legacy tools (ENABLE_LEGACY_TOOLS=true)
Scene building & data
Tool | Notes |
| Reachability check + Cavalry version |
| Many ops in one round trip — see below |
| Arbitrary JS; assign |
| Returns the new layer ID (e.g. |
|
|
| Returns the value |
| Structured JSON: id, type, name, visible, selected, position, in/out, parent |
| Every attribute path on a layer (+ optional definitions) — the dictionary that ends attribute guessing |
| Full wiring readback: incoming connections per attribute + outgoing connections per attribute and |
| Delete verifies what was actually removed |
|
|
| |
| Z-order without a second layer ID: forward / front / backward / back (selection-safe) |
| local (default) or world space |
| Image/sequence/video/audio → asset + layer IDs |
| |
| Every layer type in this Cavalry build ( |
| reset / freeze / centrePivot |
Animation
Tool | Notes |
| Single keyframe or a whole curve ( |
| Edit EXISTING animation: delete keyframes at frames, wipe an attribute's (or the whole layer's) animation, set/clear per-keyframe velocity |
| Schema-validated enum of the 20 real easing names |
| Keyframe frames per attribute |
| Presets in one call: |
| Set/read a per-attribute JavaScript expression (evaluated every frame) |
Style & color
Tool | Notes |
| One-call gradient from hex stops ( |
| Harmonious palettes: monochromatic, analogous, complementary, triadic, goldenRatio, … |
Composition & timing
Tool | Notes |
| resolution, fps, frame range, current frame |
| width/height, fps, inFrame/outFrame |
| list / create / setActive comps, list a comp's layers (optionally by type), preCompose, new scene (confirm-gated) |
| |
| play / stop the timeline so the user can watch |
| Trim in/out points, or slide a layer by N frames |
| Stack order and hierarchy |
Render & export
Tool | Notes |
| Renders and returns the image inline (set |
| N frames sampled across the timeline → one contact-sheet image, returned inline |
| Starts a background render-queue video render of the active comp |
| Manage renders |
| Save As verified by watching the file on disk |
| Experimental — feature-detected, clear error if this Cavalry build lacks it |
Batch example
[
{ "op": "create", "layerType": "basicShape", "name": "BG", "as": "bg" },
{ "op": "set", "layerId": "$bg", "attributes": { "material.materialColor": "#101828", "generator.dimensions": [1920, 1080] } },
{ "op": "create", "layerType": "textShape", "name": "Title", "as": "title" },
{ "op": "set", "layerId": "$title", "attributes": { "fontSize": 120, "text": "HELLO" } },
{ "op": "keyframe", "layerId": "$title",
"keyframes": [
{ "frame": 0, "attributes": { "position.y": -200, "opacity": 0 } },
{ "frame": 30, "attributes": { "position.y": 0, "opacity": 100 } }
] },
{ "op": "easing", "layerId": "$title", "attrPath": "position.y", "frame": 0, "easingType": "SpringOut" },
{ "op": "order", "layerId": "$title", "to": "front" },
{ "op": "gradient", "layerId": "$bg", "attrPath": "generator.gradient", "colors": ["#101828", "#2d3a8c"] },
{ "op": "expression", "layerId": "$title", "attrPath": "position.x", "expression": "value * 2" },
{ "op": "timing", "layerId": "$bg", "inFrame": 0, "outFrame": 90 }
]One tool call builds the whole scene (a per-op script would cost ~1 s per step in bridge latency).
Tips
Renders are async inside Cavalry: the PNG reflects the scene state when the render completes. Make scene changes and renders in separate tool calls.
Avoid granular request loops: batch scene work into one
cavalry_run_scriptor CLI execution and use_mg/procedural nodes instead of per-layer keyframe spam.api.saveSceneAstears down the Stallion script context — after a Save As you must re-run Scripts > Stallion before further tool calls.Layer IDs are strings like
textShape#3, numbered per type across the scene.cavalry_render_videooutput format follows the render queue item's settings — configure defaults once in Cavalry's Render window;outputPathsets the item's filename on a best-effort basis.Reading the Cavalry scripting docs helps a lot: https://cavalry.studio/docs/tech-info/scripting/api-module
Development
npm install
npm run build # tsc -> dist/
npm test # unit tests + bridge integration against a mock Stallion + full MCP e2eThe test suite runs the real server against an in-memory MCP client and a mock Stallion (an HTTP server executing scripts in a node:vm sandbox with a modelled api), so bridge behavior — seq matching, the write-failure retry, queue serialization, timeouts — is covered without Cavalry installed. test/library.test.ts additionally compiles and executes all 120 presets with defaults and typed overrides against the mock bridge. CI runs build + tests on Linux and Windows.
Credits
kacperchlebowicz/Cavalry-mcp — the original Claude Desktop version this project rebuilt
scenery-io/stallion — the VSCode/Cavalry scripting bridge this server talks to
Scene Group — Cavalry
License
MIT
Available Tools
3 toolscavalry_inspectA
Inspect compact layer id/name/niceName/type summaries for the selection or active composition roots.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | selection |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden. "Inspect" and "summaries" correctly signal a non-mutating, read-only operation and pre-declare the returned fields (id/name/niceName/type), but nothing is said about permissions, cost, or behavior when nothing is selected or no composition is active.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the verb and the returned payload, with the scope qualifier at the end. No filler and nothing that could be cut.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-param read tool with no output schema, the description names the exact fields returned and the two scopes it can inspect, which is enough to call it correctly. Only the empty-selection/no-active-composition edge case is unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the single parameter is an enum whose two values are explicitly mapped by the phrase "selection or active composition roots," so an agent can choose the default or override with intent. The description effectively compensates for the undocumented schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Inspect) and resource (compact layer id/name/niceName/type summaries) plus the scope it operates on (selection or active composition roots). It implicitly separates itself from cavalry_run_script and cavalry_run_preset, which execute things rather than read layer metadata, though it never names those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"for the selection or active composition roots" implies the situations where the tool is relevant, but there is no explicit when/when-not guidance and no direct routing to or away from cavalry_run_script and cavalry_run_preset. Usage has to be inferred from the scope phrase.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cavalry_run_presetC
Build a parameterized procedural motion rig in one atomic Cavalry execution.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| params | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully says the build happens in one atomic execution, but it does not disclose mutation side effects, required Cavalry state, failure behavior, idempotency, or what is returned after the rig is built.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no wasted words. It is appropriately concise, though the extreme terseness contributes to the missing usage and parameter details elsewhere.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a complex mutation tool with a large enum, a free-form nested params object, no annotations, and no output schema. One sentence stating that it builds a parameterized rig is not enough to tell an agent how to invoke it correctly or what to expect from the atomic execution.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, but it only says the rig is 'parameterized'. It does not explain the 118-value name enum, what the free-form params object can contain, how params override preset defaults, or whether any params are required beyond name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Build a parameterized procedural motion rig' in 'one atomic Cavalry execution'. It is clear what the tool does and implies preset-driven rig creation, but it does not explicitly differentiate itself from cavalry_run_script or cavalry_inspect.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no exclusions, and no mention of the sibling tools cavalry_run_script or cavalry_inspect. The agent is left to infer that this tool should be chosen when a named preset is desired rather than a custom script.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cavalry_run_scriptB
Run batched Cavalry JavaScript with _mg helpers and one Undo group. Return a value for JSON readback.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose two real traits: all effects collapse into one Undo group (atomicity), and a returned value is read back as JSON (serialization requirement). It says nothing about permissions, error/failure behavior, whether the script can leave partial state on failure, or what _mg helpers actually are.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the operation and followed by the two constraints that matter. No filler, though the phrasing is terse enough to be slightly cryptic.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter scripting tool with no annotations or output schema, the description covers the return path ('JSON readback') and undo semantics, which is more than most. Gaps remain around the _mg helper surface and failure behavior, which matter for arbitrary code execution.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single `code` parameter has 0% schema description coverage, so the description must compensate. It does add guidance — the code may use _mg helpers and should return a JSON-serializable value — but does not clarify the string format, expected structure, or any length/context constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb and resource: run batched Cavalry JavaScript. Adds the distinguishing traits (with _mg helpers, a single Undo group), which separates it from a plain script runner. It does not explicitly contrast with cavalry_inspect or cavalry_run_preset, so sibling differentiation is only implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No statement of when to use this rather than cavalry_run_preset or cavalry_inspect, and no prerequisites or exclusions. 'Batched' hints that this suits multiple operations, but the agent must infer that from a single adjective.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v3.0.0- First observed
cavalry_inspect - First observed
cavalry_run_preset - First observed
cavalry_run_script
TDQS
Scored across 3 tools
cavalry_inspect is clearly the read path, while cavalry_run_script and cavalry_run_preset both execute code and could initially be confused. The descriptions resolve this (preset = one atomic parameterized rig build, script = general JS escape hatch), so boundaries are workable but not perfectly crisp.
All three share a consistent cavalry_ prefix and use verb-style names (run_script, run_preset, inspect). The only minor deviation is that inspect has no object noun while the other two follow verb_noun, but the pattern remains readable.
Three tools is on the lean side, but the design is deliberate: one general execution tool, one readback tool, one high-level preset builder. Each earns its place rather than being a thin, trivial surface.
The general script runner plus inspect covers most read/write workflows, but there is no discovery tool for available presets, _mg helper documentation, or broader scene/composition enumeration beyond selection and roots. Agents must guess at APIs, which will cause some dead ends.
Maintenance
Related MCP Connectors
Build editable 3D scenes, direct characters and cameras, and export AI video references with MCP.
An MCP connector for Adobe After Effects. Real, editable layers and keyframes, not scripts.
- CueFrameDeprecatedai.cueframe.api
Compose, edit and render video through CueFrame’s hosted x402 MCP endpoint: content-aware reframing, word-timed captions and motion graphics. Paid tool calls require an x402-capable client and wallet payment. For OAuth browser sign-in, use the CueFrame OAuth connector.
OSC ↔ MIDI bridge — 986 synthesizers and DAWs. A MIDI MCP and OSC MCP for controlling them.
Related MCP Servers
- AlicenseAqualityFmaintenanceEnables natural language control of Cavalry animation software for creating layers, setting attributes, keyframing, rendering frames, and more via an MCP server.2131MIT
- FlicenseBqualityDmaintenanceMCP server for driving Cavalry's 2D motion-graphics engine from LLMs, enabling scene creation and animation via natural language.283-
- AlicenseBqualityDmaintenanceEnables AI assistants to control Cavalry, a procedural 2D motion graphics application, through natural language commands for creating and animating scenes.182MIT
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to control Cavalry motion graphics projects through its local JavaScript API, supporting scene and layer inspection, creation, editing, keyframing, expressions, saving, and rendering with validated structured results.MIT