Control a running Cascadeur instance from external tools (scripts, or an AI agent like Claude) using a file-based bridge — no sockets, no PowerShell, antivirus-friendly.
You add a single command to Cascadeur's menu (Commands → MCP → Start Bridge). While it runs, an external "driver" writes JSON command files and reads JSON responses, executing live against Cascadeur's csc Python API. Useful for automating rig/scene setup (fixing controllers, adding cameras, scaling bones, running arbitrary csc code) while you focus on the creative work.
Tested with Cascadeur 2026.1.2 (Windows). The
cscPython API is required (available in all editions, including Basic).
The bridge runs a loop on Cascadeur's main thread (started from a menu command). It polls a command file, executes the request, and writes a response file.
Two non-obvious constraints shaped this design:
- Background Python threads are starved after a Console
Executereturns — a pure background socket server never gets scheduled. So the bridge must run on the main thread (the UI shows "Not Responding" while it runs — this is normal; it returns onstopor after a timeout). - A socket client built as a PowerShell one-liner (
-ExecutionPolicy Bypass+TcpClient) trips Windows Defender'sTrojan:Win32/ClickFixheuristic. A plain file exchange avoids both the listening socket and the flagged client entirely.
[driver] --writes--> io/casc_cmd.json --polled by--> [Start Bridge loop] --csc API
[driver] <--reads--- io/casc_resp.json <--written by-- [Start Bridge loop]
- Put this folder somewhere stable, e.g.
%USERPROFILE%\Documents\CascadeurMCP. - Register the
mcp_commandspackage with Cascadeur by editing the user settings file:%LOCALAPPDATA%\Nekki Limited\Cascadeur\settings.json- Add this folder's absolute path to
Python.Path, and"mcp_commands"toPython.Commands(seesettings.snippet.json). - The file may be read-only (
Rattribute) and is locked while Cascadeur is open — close Cascadeur, runattrib -ron it, edit, then reopen.
- Add this folder's absolute path to
- In Cascadeur do Reload scripts (or restart).
Commands → MCP → Start Bridgeshould now appear.
The io/ folder (created at runtime next to this package) holds the transient command/response/log files and is git-ignored.
- In Cascadeur: Commands → MCP → Start Bridge. The UI freezes (expected). It auto-closes after 240 s, or when it receives a
stop. - From your driver, write
io/casc_cmd.jsonwith an incrementingid:{ "id": 1, "op": "fix_preset", "arg": "arms_free" } - Read
io/casc_resp.jsonuntil itsidmatches:{ "id": 1, "ok": true, "result": { "preset": "arms_free", "fixed_count": 27, "free_count": 16 } }
Minimal bash driver (write command, poll for matching response):
DIR="$HOME/Documents/CascadeurMCP/io"
send() { # send <id> <op> <arg>
printf '{"id": %s, "op": "%s", "arg": "%s"}' "$1" "$2" "$3" > "$DIR/casc_cmd.json"
for i in $(seq 1 80); do
sleep 0.2
r=$(cat "$DIR/casc_resp.json" 2>/dev/null)
case "$r" in *"\"id\": $1"*) echo "$r"; return;; esac
done
}
send 1 ping ""
send 2 fix_preset arms_free
send 99 stop ""| op | arg | does |
|---|---|---|
ping |
– | health check → "pong" |
info |
– | scene name, current frame, animation boundary |
get_frame |
– | current frame |
set_frame |
frame number | set current frame |
add_camera |
name (optional) | create a camera object |
fix_preset |
arms_free | all | none |
toggle controller fixation: arms_free fixes everything except the arm chain (clavicle/upperarm/lowerarm/hand), all fixes everything, none frees everything |
py |
python code | exec arbitrary csc code; captured stdout is returned. Locals: csc, app, view_scene, domain |
stop |
– | close the bridge (unfreezes Cascadeur) |
The py op is the escape hatch — anything not covered by a built-in op can be done with live csc code, and frequently-used logic can be promoted to a permanent op (then Reload scripts).
- Main-thread freeze: the UI is unresponsive while the bridge runs. Send
stopas soon as your batch is done. - Reversible: all built-in ops are reversible in Cascadeur (e.g.
fix_preset none, delete the camera, undo). - Safety: the bridge only reads/writes files inside its own
io/folder and runs code you send it. Review before exposing it to anything untrusted.
MIT