Skip to main content
Glama

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 <---> Cavalry

Three-tool core

Only these tools are exposed by default:

Tool

Purpose

cavalry_run_script

Batched JavaScript with _mg helpers, structured readback, and one Undo group

cavalry_inspect

Bounded id/name/niceName/type summaries for selection or roots

cavalry_run_preset

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 --sel

Install 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

typography

Hero Typography & Messaging

5

2

ui_mockups

UI Components & Product Mockups

5

3

data_viz

Data Visualization & KPI

5

4

polish_camera

Backgrounds, Transitions & Camera

5

5

ai_agents

AI Agents, LLMs & Copilot

10

6

devtools_cli

Developer Tools, Code & Terminal

10

7

collab_presence

Multiplayer Collaboration & Presence

10

8

workflows_nodes

Workflow Automation & Node Graphs

10

9

fintech_billing

Fintech, Payments & Billing

10

10

security_auth

Security, Auth & Identity

10

11

cloud_devops

Cloud, DevOps & Infrastructure

10

12

voice_audio_video

Voice, Audio & Video

10

13

onboarding_plg

Onboarding & Product-Led Growth

10

14

social_proof_cta

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 build

Configure 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_URL

http://127.0.0.1:8080

Stallion base URL

STALLION_TOKEN

empty

Optional bearer token matching stallion.json

CAVALRY_HOST / CAVALRY_PORT

127.0.0.1 / 8080

Legacy URL configuration

CAVALRY_HTTP_TIMEOUT_MS

5000

Abort timeout for every HTTP request

CAVALRY_RESULT_TIMEOUT_MS

5000

Overall structured-result wait; increase for slow renders

CAVALRY_TIMEOUT_MS

(legacy)

Sets both timeouts at once

CAVALRY_RESULT_PATH

<tmpdir>/cavalry-mcp-result-<pid>.json

Legacy fallback result file

ENABLE_LEGACY_TOOLS

false

Restore the original granular MCP tools

Legacy tools (ENABLE_LEGACY_TOOLS=true)

Scene building & data

Tool

Notes

cavalry_ping

Reachability check + Cavalry version

cavalry_batch

Many ops in one round trip — see below

cavalry_run_script

Arbitrary JS; assign __result to return data

cavalry_create_layer

Returns the new layer ID (e.g. textShape#3)

cavalry_set_attribute

{"material.materialColor": "#101828"}, {"generator.dimensions": [1920, 1080]}

cavalry_get_attribute

Returns the value

cavalry_get_scene_layers / cavalry_get_selected_layers

Structured JSON: id, type, name, visible, selected, position, in/out, parent

cavalry_list_attributes

Every attribute path on a layer (+ optional definitions) — the dictionary that ends attribute guessing

cavalry_get_connections

Full wiring readback: incoming connections per attribute + outgoing connections per attribute and id — see how effects/modifiers are hooked up before rewiring

cavalry_select_layers / cavalry_delete_layers

Delete verifies what was actually removed

cavalry_duplicate_layer

api.duplicate, keeps your selection

cavalry_rename_layer

cavalry_layer_order

Z-order without a second layer ID: forward / front / backward / back (selection-safe)

cavalry_get_bounding_box

local (default) or world space

cavalry_import_asset

Image/sequence/video/audio → asset + layer IDs

cavalry_add_dynamic_attribute

cavalry_layer_types

Every layer type in this Cavalry build ([{type, name}], incl. experimental on request) — the full menu of layers/generators/deformers/modifiers/shaders

cavalry_transform

reset / freeze / centrePivot

Animation

Tool

Notes

cavalry_keyframe

Single keyframe or a whole curve (keyframes: [{frame, attributes}]) in one call

cavalry_keyframe_edit

Edit EXISTING animation: delete keyframes at frames, wipe an attribute's (or the whole layer's) animation, set/clear per-keyframe velocity

cavalry_magic_easing

Schema-validated enum of the 20 real easing names

cavalry_get_keyframes

Keyframe frames per attribute

cavalry_animate_in

Presets in one call: fadeIn, fadeUp, springUp, slideInLeft, popIn, dropBounce — keyframed relative to the layer's current position

cavalry_expression

Set/read a per-attribute JavaScript expression (evaluated every frame)

Style & color

Tool

Notes

cavalry_gradient

One-call gradient from hex stops (setGradientFromColors)

cavalry_generate_palette

Harmonious palettes: monochromatic, analogous, complementary, triadic, goldenRatio, …

Composition & timing

Tool

Notes

cavalry_get_composition_info

resolution, fps, frame range, current frame

cavalry_set_composition_info

width/height, fps, inFrame/outFrame

cavalry_compositions

list / create / setActive comps, list a comp's layers (optionally by type), preCompose, new scene (confirm-gated)

cavalry_set_current_frame / cavalry_get_current_frame

cavalry_playback

play / stop the timeline so the user can watch

cavalry_set_layer_timing

Trim in/out points, or slide a layer by N frames

cavalry_reorder_layer / cavalry_set_parent

Stack order and hierarchy

Render & export

Tool

Notes

cavalry_render_png

Renders and returns the image inline (set returnImage:false to skip)

cavalry_render_filmstrip

N frames sampled across the timeline → one contact-sheet image, returned inline

cavalry_render_video

Starts a background render-queue video render of the active comp

cavalry_get_render_queue / cavalry_cancel_render

Manage renders

cavalry_save_scene / cavalry_open_scene

Save As verified by watching the file on disk

cavalry_undo

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_script or CLI execution and use _mg/procedural nodes instead of per-layer keyframe spam.

  • api.saveSceneAs tears 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_video output format follows the render queue item's settings — configure defaults once in Cavalry's Render window; outputPath sets 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 e2e

The 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

License

MIT

Available Tools

3 tools
cavalry_inspectA

Inspect compact layer id/name/niceName/type summaries for the selection or active composition roots.

NameRequiredDescriptionDefault
modeNoselection

TDQS

A3.7/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

NameRequiredDescriptionDefault
nameYes
paramsNo

TDQS

C2.7/5.0
Behavior2/5

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.

Conciseness4/5

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.

Completeness2/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

NameRequiredDescriptionDefault
codeYes

TDQS

B3.2/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

  1. 3 tool updatesv3.0.0
    • First observedcavalry_inspect
    • First observedcavalry_run_preset
    • First observedcavalry_run_script

TDQS

B3.2/5.0

Scored across 3 tools

Disambiguation4/5

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.

Naming Consistency4/5

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.

Tool Count4/5

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.

Completeness3/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    F
    maintenance
    Enables natural language control of Cavalry animation software for creating layers, setting attributes, keyframing, rendering frames, and more via an MCP server.
    21
    31
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    Enables AI assistants to control Cavalry, a procedural 2D motion graphics application, through natural language commands for creating and animating scenes.
    18
    2
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables 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