使用说明
Resolume MCP
An MCP server for Resolume Arena and Avenue. Exposes 209 tools covering composition control, playback, Advanced Output management, and show recovery — so AI assistants can operate Resolume via REST, WebSocket, and OSC.
Built for live production. Pairs with grandMA2 MCP, MADRIX MCP, Companion MCP, and Beyond MCP for full AI-driven show control.
What it does
| Area | What you get |
|---|---|
| Composition control | Layers, clips, columns, groups, decks — get snapshots, trigger playback, manage media, batch operations |
| Advanced Output | Screen and slice management via both REST API and XML inspection. Backup, diff, rename, reroute, warp alignment |
| Playback & monitoring | Transport control, parameter subscriptions, state polling, show-readiness audits |
| Effects | Add, remove, move, rename effects across composition, layer, group, and clip scopes |
| Safety | 20 destructive operations gated behind confirm_destructive=True, plus path-based gating on the generic REST/WebSocket/OSC tools. Host allowlist. Atomic XML writes |
Quick start
# Clone and install
git clone https://github.com/drohi-r/resolume-mcp && cd resolume-mcp
uv sync
# Run the server (connects to Resolume on localhost:8080)
uv run python -m resolume_mcp
Make sure Resolume Arena or Avenue is running with the REST API enabled (Preferences → OSC/HTTP → HTTP API).
For remote control:
- use LAN or WireGuard, not the public internet
- set
RESOLUME_HOSTto the remote machine - include that host in
RESOLUME_ALLOWED_HOSTS
Configuration
The server reads configuration from environment variables. All have sensible defaults for local development.
| Variable | Default | Description |
|---|---|---|
RESOLUME_HOST |
127.0.0.1 |
Resolume instance IP |
RESOLUME_HTTP_PORT |
8080 |
HTTP API port |
RESOLUME_OSC_PORT |
7000 |
OSC listener port |
RESOLUME_ALLOWED_HOSTS |
127.0.0.1,localhost,::1 |
Comma-separated allowlist for target hosts. Set * to allow any. |
RESOLUME_USE_HTTPS |
false |
Use HTTPS for API calls (true, yes, 1) |
RESOLUME_DOCUMENTS_ROOT |
~/Documents/Resolume Arena |
Resolume documents path |
RESOLUME_ADVANCED_OUTPUT_XML |
~/Documents/Resolume Arena/Preferences/AdvancedOutput.xml |
Advanced Output XML path |
RESOLUME_SLICES_XML |
~/Documents/Resolume Arena/Preferences/slices.xml |
Slices XML path |
Architecture
graph TD
A["Resolume MCP Server<br/><code>resolume_mcp</code><br/>209 tools · safety gate"] --> B
A --> C
A --> D
B["REST Client<br/>Composition · clips · layers · effects"] --> E
C["WebSocket Client<br/>Parameter subscriptions · state polling"] --> E
D["OSC Client<br/>Transport control"] --> E
E["Resolume Arena / Avenue<br/>HTTP API on port 8080"]
F["Advanced Output Engine<br/>XML inspection · atomic writes · backup"] -.-> A
G["Safety Gate<br/>20 destructive ops + generic-tool path gate"] -.-> A
style A fill:#1a1a2e,stroke:#9B59FF,color:#fff
style B fill:#1a1a2e,stroke:#9B59FF,color:#fff
style C fill:#1a1a2e,stroke:#9B59FF,color:#fff
style D fill:#1a1a2e,stroke:#9B59FF,color:#fff
style E fill:#1a1a2e,stroke:#0f3460,color:#fff
style F fill:#0f3460,stroke:#0f3460,color:#fff
style G fill:#0f3460,stroke:#0f3460,color:#fff
Claude Desktop
Add this to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"resolume": {
"command": "uv",
"args": ["run", "--directory", "/path/to/resolume-mcp", "python", "-m", "resolume_mcp"],
"env": {
"RESOLUME_HOST": "127.0.0.1",
"RESOLUME_HTTP_PORT": "8080",
"RESOLUME_ALLOWED_HOSTS": "127.0.0.1,localhost,::1"
}
}
}
}
VS Code / Cursor
Add to .vscode/mcp.json in your project:
{
"servers": {
"resolume": {
"command": "uv",
"args": ["run", "--directory", "/path/to/resolume-mcp", "python", "-m", "resolume_mcp"],
"env": {
"RESOLUME_HOST": "127.0.0.1",
"RESOLUME_HTTP_PORT": "8080",
"RESOLUME_ALLOWED_HOSTS": "127.0.0.1,localhost,::1"
}
}
}
}
Codex
Create a codex.json MCP config file:
{
"mcpServers": {
"resolume": {
"command": "uv",
"args": ["run", "--directory", "/path/to/resolume-mcp", "python", "-m", "resolume_mcp"],
"env": {
"RESOLUME_HOST": "127.0.0.1",
"RESOLUME_HTTP_PORT": "8080",
"RESOLUME_ALLOWED_HOSTS": "127.0.0.1,localhost,::1"
}
}
}
}
Then run Codex with:
codex --mcp-config codex.json
Skills
The server includes 7 operator skills — structured workflows for common live-show scenarios:
| Skill | When to use |
|---|---|
playback-prep-and-busking |
Preparing Resolume for a live run or operator handoff |
advanced-output-setup |
Setting up screens, slices, and routing for a show |
output-routing-festival |
Fast rerouting for festival or guest rig changes |
output-warp-alignment |
Aligning screen geometry and slice warping |
festival-recovery-fast |
Recovering a show under time pressure |
show-recovery-and-triage |
Diagnosing transport, output, or layer issues |
deck-control-and-inspection |
Managing deck snapshots, audits, and parameters |
Safety model
- Read operations (snapshots, audits, parameter gets): always safe, no confirmation needed
- Destructive operations (clear, disconnect, remove, new/open composition, close deck, Advanced Output restore): require
confirm_destructive=True - Generic tools (
rest_*,websocket_*,set_param,trigger_param,trigger_deck_action,osc_send): requireconfirm_destructive=Truewhen the call matches a known-destructive pattern — RESTDELETE, WebSocketremove, paths ending inclear/clearclips/disconnect-all/disconnectall,/composition/new,/composition/open, deckclose, orconnectwithfalse. This is best-effort: aseton/parameter/by-id/{id}cannot be classified. - Host allowlisting: only
127.0.0.1,localhost, and::1are permitted by default. Add LAN hosts explicitly viaRESOLUME_ALLOWED_HOSTS. Set*to allow any host. Theosc_sendhost override is checked against the same allowlist. - Advanced Output XML writes: atomic (temp file + rename) to prevent corruption
- Polling loops: crash-resilient — return last known state if Resolume becomes unreachable
How tools report results
- Every tool has a description and MCP annotations (
readOnlyHint/destructiveHint), so clients can auto-approve reads and warn before destructive calls. get_composition_summaryandget_layer_summarygive compact state (names, bypass, opacity, loaded and playing clips). The rawget_composition,list_layersandget_layerpayloads run to hundreds of KB on real shows.wait_for_resolumepolls until Arena's REST API answers after launch.source:///andeffect:///URIs are percent-encoded automatically, so display names with spaces or parentheses work.- Choice parameters are checked against their options before sending; a set that does not stick is resent once.
disconnect_clipfalls back to clearing the clip's layer when Arena ignoresconnect=false(only that clip stops; media stays).- The Documents folder is found through Windows (including OneDrive redirection);
RESOLUME_DOCUMENTS_ROOTalso moves the default XML paths. - Parameter reads come from the REST payload, one request per layer/clip/deck. WebSocket results report
bootstrap_message_countinstead of embedding Resolume's startup state. - Named
set_*tools verify by reading the value back over REST:value_before,value_after,verified. subscribe_*tools watch forduration_sseconds (max 30) on one connection and return the updates received.unsubscribe_*tools are no-ops, because subscriptions end when the call returns.- WebSocket
getwaits at most 2 s for the matching reply (reply_timed_outsays if none came); other actions are fire-and-forget. - If Resolume is unreachable, the error names the URL and what to check.
Development
# Install and sync dependencies
uv sync
# Run tests
uv run python -m pytest -v