Command Line Interface
Visibox ships with a visibox command-line tool for controlling a running Visibox from your shell. It is a lighter alternative to the AI Assistants integration for quick one-offs, shell aliases, scripting, and hotkey tools.
The CLI is a thin wrapper over the same HTTP REST API the Stream Deck plugin and the MCP server use, so anything the CLI can do, any other client can too.
Installation
Install the CLI from inside Visibox:
- Choose Install CLI Tool… (on Mac, from the Visibox menu; on Windows, from the File menu).
- Visibox installs the command and shows you where it landed. Open a new terminal and run
visibox health(Mac, or Windows from Command Prompt or PowerShell) orvisibox.cmd health(Windows from Git Bash or WSL) to confirm it is working.
To remove it later, choose Install CLI Tool… again. Visibox detects that it is already installed and offers an Uninstall option.
Where it lands
| Platform | Install path | Invoke as |
|---|---|---|
| macOS | /usr/local/bin/visibox | visibox |
| Windows | %LOCALAPPDATA%\Visibox\bin\visibox.cmd | visibox or visibox.cmd |
On macOS, /usr/local/bin is already on your $PATH, so visibox works in any shell. You may be asked for your password, since writing there needs administrator rights.
On Windows, Visibox adds %LOCALAPPDATA%\Visibox\bin to your user PATH. In Command Prompt and PowerShell, type visibox and Windows resolves it to visibox.cmd automatically. In Git Bash, WSL, or another Unix-style shell on Windows, type visibox.cmd explicitly, because those shells do not do that resolution. To shorten it in bash, add alias visibox=visibox.cmd to your ~/.bashrc.
The installed command is a small wrapper that runs the CLI out of the Visibox app itself, so there is no separate runtime to install.
You may need to open a new terminal window, or reload your shell profile, after installing so the command is on your PATH.
Quick Start
# Is Visibox running?
visibox health
# What's playing?
visibox status
# Control playback
visibox play
visibox stop
visibox next
visibox prev
Connection and Authentication
By default the CLI connects to http://127.0.0.1:17736 on your local machine, and localhost connections skip authentication. There is nothing to configure for scripting your own Visibox.
To reach a Visibox on another machine you need a pairing token. See Remote Pairing for how to pair, then pass the token with a flag or an environment variable:
| Flag / Variable | Purpose |
|---|---|
--host <host> / VISIBOX_HOST | Host to connect to. |
--port <port> / VISIBOX_PORT | Port. Default 17736. |
--token <token> / VISIBOX_TOKEN | Pairing token for remote connections. |
The CLI also reads a token from ~/.visibox/mcp-token if it is there, the same file the MCP server uses, so if MCP already works then the CLI does too.
The default port changed in Visibox 6.0. Visibox 5.x used 51736. Update any script that names the port.
Counting from One
Song and Clip indices are one-based by default, matching the numbers the Controller shows. visibox play-clip 1 plays the first Clip.
This is the opposite of the API, which is zero-based. The CLI takes the friendlier default because a person is typing it.
To switch, use --zero-based on a single command, set VISIBOX_INDEX_BASE=0, or make it permanent:
visibox config set index-base 0
--one-based and --zero-based cannot both be given at once.
Playback
| Command | What it does |
|---|---|
visibox play | Start playback. |
visibox stop | Stop playback. |
visibox pause | Pause. |
visibox resume | Resume. |
visibox next | Next Clip. |
visibox prev | Previous Clip. |
visibox random | A random Clip from the active Song. |
visibox next-song | Next Song. |
visibox prev-song | Previous Song. |
visibox restart | Restart the current Clip. |
visibox stop-all | Stop all playing Clips. |
visibox play-toggle | Toggle play and stop. |
visibox pause-toggle | Toggle pause and resume. |
visibox play-clip <index> | Play the Clip at that position. |
visibox release-clip <index> | Release the Clip at that position. |
visibox song <index|id> | Switch to a Song by position or ID. |
visibox trigger <clipId> | Trigger a Clip, respecting retrigger behavior. |
visibox release <clipId> | Release a Clip by ID. |
visibox seek <clipId> <percent> | Seek within a Clip, 0 to 100. |
play-clip and release-clip both take -s, --song <songId> to work on a Song other than the active one.
A few commands take a flag for the optional part of the action:
| Command | Flag | Effect |
|---|---|---|
next, prev | --any-song | Cross into the next or previous Song. |
random | --any-song | Pick from every Song, not only the active one. |
next-song, prev-song | --no-stop | Leave playing Clips running while the Song changes. |
song | --stop-playing <true|false> | Whether switching Songs stops playback. Default true. |
trigger | --activate-song <true|false> | Whether triggering a Clip selects its Song. Default true. |
For any API action without a command of its own, use action:
visibox action RECORD_TOGGLE now
visibox action TRIGGER_CLIP_IN abc123 --velocity 90
action takes the action name, then its parameters in order. --velocity <n> sets a trigger velocity from 0 to 127. Indices follow your index-base setting, like play-clip.
song works out for itself whether you gave it a position or an ID. Force the reading with --index <n> or --id <id> if a Song ID of yours happens to be all digits.
Real-Time Control
| Command | What it does |
|---|---|
visibox controls | List the Project’s Controls, their letters and their names. |
visibox control <letter> <value> | Set a Control by its letter, 0 to 1. Percentages work: 50%. |
visibox targets [--clip <id>] | List the Targets a Control can bind to, with their IDs. --clip lists one Clip’s Targets. |
visibox param <targetId> <value> | Set a bound parameter directly by its Target ID, skipping Controls. |
controls also shows each Control’s current value when Visibox has one. control and param both accept negative values, for example visibox control A -0.5.
param takes the value in the Target’s own units, not 0 to 1. visibox targets --json shows each Target’s range and unit. A percentage such as 50% maps onto that range instead.
See Real-Time Control for what Controls and Targets are.
Releasing a Clip
release and release-clip are the note-off half of a held button, new in 6.0. They stop a Clip that is in Gate launch mode and do nothing to a Clip in any other launch mode.
That makes them safe to fire unconditionally, which is what a hotkey tool wants:
# on key down
visibox play-clip 3
# on key up
visibox release-clip 3
System
| Command | What it does |
|---|---|
visibox fullscreen | Toggle the Output window full screen. |
visibox mute | Toggle output mute. |
visibox volume <0-100> | Set the master output level. |
visibox panic | Emergency reload. Restart all Visibox windows. |
visibox undo | Undo the last project edit. |
visibox redo | Redo the last undone project edit. |
fullscreen and mute flip the current state. Add on or off to set it instead: visibox mute on mutes, visibox mute off unmutes, and visibox fullscreen on goes full screen.
Query
| Command | What it returns |
|---|---|
visibox health | Whether Visibox is running and reachable. |
visibox status | The active project and playback state. |
visibox app-state | Full screen, mute, volume, the audio settings, the render caps, the Output’s transform and targets, the OSC port, camera preconnect, and the MIDI inputs. |
visibox projects | All open projects. |
visibox recent | Recently opened projects, with their paths. |
visibox project [id] | Detail for a project. Defaults to the active one. |
visibox summary | Names and counts for a project, as JSON. |
visibox playstate | What is playing in a project, as JSON. |
visibox songs | Songs in the active Project. Songs in the active Setlist are numbered; any others follow, unnumbered. |
visibox clips <songIndexOrId> | Clips in a Song. A number counts Songs in the active Setlist. |
visibox clip <ids...> | One or more Clips by ID, as JSON. |
visibox effects | Effects the Project uses, as JSON. |
visibox visualizers | Visualizers the Project uses, as JSON. |
visibox presets | Available Visualizer and Effect presets. |
visibox preset <kind> <id> | One preset with its data, as JSON. |
visibox preset-controls <kind> <id> | The adjustable controls a preset exposes. |
visibox preset-validate <kind> <file> | Check a preset file without saving it. |
visibox cameras | Connected cameras and video inputs. |
visibox audio-devices | Audio output and input devices. |
visibox version | CLI, app, and API versions from the running Visibox. |
presets takes -k, --kind <effect\|visualizer> and -s, --source <app\|user\|plugin> to narrow the list, and --include-data to include each preset’s full data. effects and visualizers take --ids <a,b> to pick some, and --include-data as well. <kind> is effect or visualizer.
preset-validate prints whether the preset is valid, then any errors and warnings, and exits 1 when it is not. audio-devices marks the current device with * and shows each device’s ID, which the audio:set-output-device and audio:set-default-input edits take. ASIO outputs are listed but cannot be selected over the API.
visibox --version is different: it prints the CLI’s own version without contacting Visibox.
Editing
A single edit command dispatches any edit the API supports:
visibox edit song:update-title --param songId=abc123 --param title="New Title"
visibox edit clip:delete --param clipId=xyz789
Run visibox edit list to print every available edit name, grouped by kind. Running visibox edit with no name does the same thing.
To see what one edit takes:
visibox edit song:set-timeline --describe
For nested parameters, pass the whole object at once instead of repeating --param:
visibox edit clip:update-options --params-json '{"clipId":"xyz789","options":{"speed":1.5}}'
App-wide settings go through edit too, with no Project needed:
visibox edit render:set-caps --param resolutionCap=1080 --param frameRateCap=60
visibox edit output:set-transform --param rotation=90 --param flip=horizontal
visibox edit output-target:set-enabled --param targetId=<id> --param enabled=true
visibox app-state shows the current values and each Output target’s ID. The API lists every app settings edit.
A --param value that parses as JSON is coerced, so --param volume=0.5 sends a number and --param mute=true sends a boolean.
Edit parameters are always zero-based, whatever your index-base setting is.
JSON Output
Append --json to any command for machine-readable output instead of formatted text. This is the right mode for piping into jq, grep, or another script:
visibox status --json | jq '.project.name'
visibox songs --json | jq -r '.[].title'
With --json, errors go to standard error as JSON too, so a script can tell an application error from a connection failure without parsing prose.
Targeting a Specific Project
Most commands default to the active Project. Use --project <id> to target another:
visibox songs --project abc123
visibox play --project abc123
Global Options
| Option | Description |
|---|---|
--json | Output raw JSON instead of formatted text. |
--host <host> | Visibox host. Default 127.0.0.1. |
--port <port> | Visibox port. Default 17736. |
--token <token> | Auth token for remote connections. |
--project <id> | Target Project ID. Defaults to the active Project. |
--timeout <ms> | Request timeout in milliseconds. Default 5000. |
--one-based | Treat Song and Clip indices as one-based. This is the default. |
--zero-based | Treat Song and Clip indices as zero-based. |
--version | Print the CLI version and exit. |
Configuration
visibox config reads and writes preferences in ~/.visibox/config.json:
visibox config get
visibox config get index-base
visibox config set index-base 0
index-base is the only key, and it takes 0 or 1.
Exit Codes
| Code | Meaning |
|---|---|
0 | Success. |
1 | Application error. Visibox returned an error, or refused the action. |
2 | Connection error. Visibox is not running or is unreachable. |
Exit codes make the CLI friendly to shell scripts: check $? or chain with && and \|\| like any other Unix tool.
As of 6.0, an action Visibox refuses exits 1 rather than 0. A script that checked only for a connection failure now catches a refused action too.
Examples
The examples below are written for bash (macOS, Linux, WSL, Git Bash). On Windows, run them from Git Bash or WSL, or translate the loops and jq pipelines to PowerShell. In Git Bash, substitute visibox.cmd for visibox.
# Fire off a panic reload from a Stream Deck button, keyboard shortcut tool, or hotkey app
visibox panic
# Rotate through songs on a timer (for example, in a soundcheck script)
for i in 1 2 3 4 5; do
visibox song $i
sleep 30
done
# Dump a set list for a show document
visibox songs --json | jq -r '.[] | "\(.index). \(.title)"'
# Trigger the first Clip of every Song in sequence (hands-off preview)
visibox songs --json | jq -r '.[].id' | while read songId; do
visibox song "$songId"
visibox play-clip 1
sleep 15
done
# Bail out of a script if Visibox isn't running
visibox health || { echo "Visibox is not running"; exit 1; }
The CLI, the Stream Deck plugin, and AI Assistants are three ways to reach the same API. Reach for the CLI when you want scripting or shell-speed control, the Stream Deck for physical buttons, and an AI assistant when you want to drive Visibox with natural language.