maestro-cli) for sending messages to agents, browsing sessions, running playbooks, managing settings, and controlling resources from the command line, cron jobs, or CI/CD pipelines. The CLI requires Node.js (which you already have if you’re using Claude Code).
Installation
The CLI is bundled with Maestro as a JavaScript file. Create a shell wrapper to run it:Usage
Global Flags and Exit Codes
Two flags work on every command:
Commands exit with a standardized code so scripts and CI can branch on the failure class:
Sending Messages to Agents
Send a message to an agent and receive a structured JSON response. Supports creating new sessions or resuming existing ones for multi-turn conversations.success is false and an error field is included:
For desktop-handoff workflows (route the message through a desktop tab, return an addressable tab id, etc.) use
maestro-cli dispatch instead.
Error codes: AGENT_NOT_FOUND, AGENT_UNSUPPORTED, <AGENT>_NOT_FOUND (e.g. CLAUDE_CODE_NOT_FOUND, CODEX_NOT_FOUND), MAESTRO_NOT_RUNNING, COMMAND_FAILED.
Supported agent types: any installed provider - claude-code, codex, opencode, factory-droid, copilot-cli, hermes, pi, qwen3-coder, omp.
Messages that start with a dash
Messages whose first character is a dash (em-dash-, en-dash -, double-dash --, minus -) collide with option parsing and will be rejected as unknown flags. Use the standard -- end-of-options separator so the message is passed verbatim:
-- is treated as positional, so any flags you need must come before the separator. For send that’s -s, -r, -t (-t is the boolean focus flag here); for dispatch it’s -t/--tab, --new-tab, -f.
Dispatching to a Desktop Tab
dispatch hands a prompt to an agent in the running Maestro desktop app and returns the tab/session id, so callers can address the same tab on follow-up calls without holding a persistent channel. Use this for orchestration use cases (Cue pipelines, external bots, multi-step automations).
sessionId and tabId are the same value, duplicated so polling consumers can use either name:
Error codes:
INVALID_OPTIONS, AGENT_NOT_FOUND, FORCE_NOT_ALLOWED, MAESTRO_NOT_RUNNING, SESSION_NOT_FOUND, NEW_TAB_NO_ID, COMMAND_FAILED. NEW_TAB_NO_ID fires when the desktop app acknowledges --new-tab without returning a tab id, leaving callers nothing to chain follow-up dispatches against. Requires the Maestro desktop app to be running.
Listing Sessions
Browse an agent’s session history, sorted most recent to oldest. Supports pagination with limit/skip and keyword search.
JSON output includes full session metadata:
claude-code agents.
Session Inspection
Inspect open AI tabs across the running Maestro desktop app and read their conversation history. Pairdispatch --new-tab (writes, returns a tabId) with session show <tabId> (reads, supports --since and --tail) to build a stateless poll loop without owning a persistent connection - used by Maestro-Discord and Cue follow-ups.
Both verbs talk to the running desktop over the same WebSocket as dispatch. There is no on-disk fallback: if the app is not running, the CLI exits with code MAESTRO_NOT_RUNNING.
List Open Tabs
Flatten every open AI tab across every Maestro agent into addressable entries:state (busy / idle), star (★ if starred), tabId, agent name + id, tab name, createdAt (relative). One tab per line so the output pipes cleanly into grep, awk, etc.
JSON envelope:
tabIds with jq: maestro-cli session list --json | jq '.sessions[].tabId'.
Show Conversation History
Print a tab’s conversation log, with optional cursor (--since) and cap (--tail) filters applied desktop-side so the wire payload stays small even on long conversations.
JSON shape:
role is a coarse classification (user | assistant | system | tool | thinking | error | unknown) so conversational consumers can branch on intent; the raw source is preserved alongside for callers that need to discriminate further. ISO timestamps are emitted verbatim so a messages[-1].timestamp from one call can be fed directly back into --since on the next.
Error codes: MISSING_TAB_ID, TAB_NOT_FOUND, INVALID_OPTION, MAESTRO_NOT_RUNNING, COMMAND_FAILED. All errors are emitted as { "success": false, "error": "...", "code": "..." } with exit code 1.
Creating, Updating, and Removing Agents
Create, mutate, or delete agents directly from the command line. Requires the Maestro desktop app to be running.update-agent mutates an existing agent in place, writing the same live desktop Session the Edit Agent modal edits (not the per-agent config store that settings agent set writes). Read the current values back with maestro-cli show agent <id> --json.
The group update reuses the same write path as drag-and-drop in the Left Bar. The cwd update only moves the UI-facing working directory (cwd/fullPath) - projectRoot is preserved so historical provider sessions stay addressable, which keeps prior conversation history attached when you relocate an archived project folder. Stop the agent before changing its cwd or SSH config; the underlying PTY’s working directory and spawn target are fixed at launch time, so the renderer refuses those updates while the process is alive and surfaces the reason on stderr. The remaining settings (nudge, messages, model, effort, env, token source, etc.) are spawn-time values and apply on the next launch, so they are accepted even while the agent is running.
For text fields, passing an empty string (for example --nudge "") clears the field. --env replaces the environment map with the provided pairs; --clear-env empties it. --context-window 0 (or none) clears the context-window override. --token-source only carries meaning for Claude Code agents: api uses claude --print (per-token API credit), tui drives the maestro-p TUI (Max-plan quota), and dynamic starts on the TUI and falls back to API when a usage window hits its limit. The tui and dynamic modes need the maestro-p helper on PATH; it is bundled locally, but for SSH remotes it must be installed on the remote host. See Provider Notes.
The flag table below covers
create-agent:
Creating and Removing Groups
Manage Left Bar groups from the command line. Requires the Maestro desktop app to be running. Use a group ID withcreate-agent -g or update-agent --group to place agents into it, and update-agent --group none to move an agent back out.
remove-group refuses a non-empty group unless you pass --force, so you don’t accidentally scatter a populated group. Group IDs support partial-ID resolution.
create-group flags:
remove-group flags:
Creating Worktree Agents
Branch a new agent off an existing parent agent into its own git worktree, without an Auto Run playbook. This mirrors the desktop “create worktree” flow: the parent agent must already exist in the running app, the desktop creates the worktree on disk and a child session linked to the parent, then hands back the new agent’s ID.--message is delivered to the new agent as a plain prompt (not an Auto Run loop) on the same connection, addressed by the ID the desktop just returned. Both --agent and --branch support the usual partial-ID resolution.
Driving the Workspace (Focus, Mode, Tabs)
Steer the desktop UI itself: focus an agent, flip an agent between AI and terminal mode, and manage an agent’s AI tabs. These mirror clicking around the app and require the desktop app to be running.maestro-cli session list. tab new returns the new tab’s ID (printed, or in the JSON payload with --json).
Listing Resources
Running Playbooks
Goal-Driven Auto Run
Spec-Driven runs (theplaybook command above) work through a checklist of documents. Goal-Driven runs instead pursue a single free-text objective: each iteration spawns a fresh agent that makes one increment of progress, reports how far along it is, and exits, repeating until the goal is reached, a deadlock is declared, the iteration limit is hit, or progress stalls.
The run writes an immediate “started” history entry (recording the goal and exit criteria), one entry per iteration, and a final summary with the stop reason and final progress. Goal-Driven runs honor the same per-agent SSH remote and model/effort/args overrides as
playbook, and refuse to start if the agent is already busy in the desktop app or another CLI instance.
JSON event stream: goal_start, goal_iteration_start, goal_iteration_complete (carries progress, rationale, complete, deadlock), and goal_complete (carries success, exitReason, finalProgress, iterations).
Running Documents Without a Playbook (run-doc)
run-doc runs one or more Auto Run .md documents directly, without saving a playbook first. Like playbook, it runs headlessly - it spawns the target agent itself and streams events, so it works whether or not the Maestro desktop window is open. This is the reliable way to execute a document an agent just wrote.
run-doc accepts the same execution flags as playbook (--dry-run, --no-history, --json, --debug, --verbose, --no-synopsis, --wait) plus --prompt, --loop, --max-loops, and --reset-on-completion. When no --prompt is given it uses the default Auto Run prompt.
playbookvsrun-docvsauto-run --launch: useplaybook <id>for a saved playbook andrun-doc <docs>for raw documents - both run headlessly with no desktop dependency.auto-run --launchinstead hands the run to the running desktop app (needed only when you want the run to appear and be controlled in the desktop UI).
--agentaccepts a name: the-a, --agentflag on these commands resolves an agent by ID (full or partial) or by display name. This lets a group-chat participant target itself with--agent "<its name>".
Prompt Customization
The CLI uses the same core system prompts as the desktop app. When you customize prompts via Settings → Maestro Prompts, those customizations are stored incore-prompts-customizations.json in the Maestro data directory and are automatically picked up by the CLI during playbook runs.
The prompts most relevant to CLI playbook execution are:
To customize these prompts, either use the desktop app’s Maestro Prompts tab or edit the JSON file directly:
Reading Prompts (prompts list / prompts get)
The CLI exposes Maestro’s prompt registry directly so other agents can self-fetch reference material on demand. Parent prompts can use the {{REF:name}} directive (see Prompt Customization → Include Directives) to expand into a one-line pointer; the agent then runs prompts get to retrieve the full content.
prompts get returns the same content the desktop app would deliver, so customizations made via Settings → Maestro Prompts are reflected immediately. Bundled include fragments use a leading underscore in their id (e.g., _maestro-cli, _history-format); standalone prompts do not.
Managing Settings
View and modify any Maestro configuration setting directly from the CLI. Changes take effect immediately in the running desktop app - no restart required.
Categories: appearance, editor, shell, notifications, updates, logging, web, ssh, file-indexing, context, document-graph, stats, accessibility, integrations, onboarding, advanced, internal.
Theme and Encore Features
Ergonomic, validated wrappers over the underlying settings, for the customizations users most often ask for by voice. Unlikesettings set (which writes the settings file), these route through the running desktop app, so the change applies live. The app must be running.
directorNotes, usageStats, symphony, maestroCue. Friendly aliases are accepted (for example group-chat for symphony, cue for maestroCue).
Custom Theme Palette
set-theme only switches between built-in themes. The theme command group manages the user-configurable Custom theme palette (the same two settings the in-app Custom Theme Builder edits: customThemeColors and customThemeBaseId). Activate the result with set-theme custom.
theme show and theme export read the on-disk settings store directly (no running app required); theme import and theme set apply live through the running desktop app. Imports are validated the same way as the in-app importer: every required color key must be present and every value must be a valid CSS color.
Managing Agent Configuration
Each agent (Claude Code, Codex, OpenCode, Factory Droid) can have its own configuration for custom paths, CLI arguments, environment variables, and model overrides.settings agent set writes the per-agent-type configuration store (defaults applied to newly created agents and headless CLI spawns). To change the settings of a specific existing agent shown in the Left Bar - its nudge message, model, env vars, Claude token source, and so on - use update-agent instead, which writes that agent’s live desktop Session.
Common agent config keys:
Settings and agent config changes made via the CLI are automatically detected by the running Maestro desktop app. The app watches for file changes and reloads immediately - it’s as if you toggled the setting in the Settings modal yourself.
Managing SSH Remotes
Create, list, and remove SSH remote configurations. These commands read and write directly to the Maestro settings file - no running desktop app required.SSH remote changes made via the CLI are detected by the running Maestro desktop app through file watching, just like settings changes.
Partial IDs
All commands that accept an agent ID, group ID, or SSH remote ID support partial matching. You only need to type enough characters to uniquely identify the resource:JSON Output
By default, commands output human-readable formatted text. Use--json for machine-parseable output:
send command always outputs JSON (no --json flag needed).
Desktop Integration
Commands for interacting with the running Maestro desktop app. These are especially useful for AI agents to trigger UI updates after creating or modifying files.Open a File
Open a file as a preview tab in the Maestro desktop app. Without--agent, the owning agent is auto-detected by which agent’s working directory the file lives in (longest-prefix match, most-recently-active wins on ties). Pass --agent <id> to target an explicit agent - the file must live inside that agent’s cwd. Pass --no-switch to skip switching the Maestro UI to the resulting agent/tab.
Open a Browser Tab
Open a URL as a browser tab in the Maestro desktop app. Onlyhttp(s) URLs are accepted; scheme-less inputs like localhost:3000 or example.com:8080 are auto-prefixed with https://.
Open a Terminal Tab
Open a fresh terminal tab in the Maestro desktop app. The working directory must resolve inside the target agent’scwd; paths outside it are rejected.
Refresh the File Tree
Refresh the file tree sidebar after creating multiple files or making significant filesystem changes:Refresh Auto Run Documents
Refresh the Auto Run document list after creating or modifying auto-run documents:Notifications
Surface notifications in the running desktop app from any script, hook, or agent. Two delivery modes are available, both built on the same five-color design language so they feel unified:- Toast - persistent notification that lands in the toast queue (top-right). Auto-dismisses by default. Use this when you want the user to see a result they may want to act on later, when an OS notification should also fire, or when the message benefits from being clickable to jump to a specific agent. Toasts can be made sticky with
--dismissibleso they require an explicit click to dismiss - use this for messages the user must acknowledge. - Center Flash - momentary, single-slot center-screen confirmation that auto-dismisses (default 1.5s, max 5s). Use this for “I did the thing” feedback for a user-initiated action - clipboard acks, quick status nudges, brief success notes. Only one flash is visible at a time; firing a new one replaces the active one.
Color palette (shared by both)
Both commands accept--color, one of five canonical values:
Pick
theme when you don’t have an opinion - the flash/toast will visually match whatever theme the user is running.
Toasts
The body-click hierarchy is:
--open-file / --open-url (mutually exclusive) > --agent (+ optional --tab). --action-url is independent - it renders a separate inline link button and does not affect the body click.
Center Flash
Caps and dismissibility
External (CLI/web) callers are capped to 5 seconds for Center Flash and 60 seconds for Toast. The cap exists so external scripts can’t stick a permanent overlay on the user. The only way to leave a notification on screen indefinitely is--dismissible on a toast - there is no equivalent for Center Flash (it is, by design, momentary).
Both commands support --json for scripting. Toasts respect the user’s notification settings (audio feedback, OS desktop notifications) configured in the app.
Configuring Auto-Run
Set up and optionally launch an auto-run session with one or more markdown documents. Documents must be.md files containing - [ ] checkbox tasks.
Worktree mode reuses the desktop app’s Auto Run pipeline: the app creates the
worktree (or reuses an existing one on the same repo), checks out the requested
branch, dispatches the agent inside the worktree, and - when
--create-pr is
set - runs gh pr create once the batch completes. See
Git Worktrees for more on worktree behavior.
Controlling a Running Auto Run
Once an Auto Run is going, these commands stop it or recover it from an error pause - the counterpart to launching withauto-run --launch. They require the desktop app to be running.
reset-auto-run-tasks is relative to the agent’s Auto Run folder; absolute paths and .. traversal are rejected.
Checking Status
Check if the Maestro desktop app is running and reachable:Diagnosing Problems (doctor)
When a command isn’t working, doctor runs a checklist covering the most common causes in one shot: the desktop app reachable, the running build’s version vs. this CLI’s, whether the running app understands newer commands, and whether configured SSH remotes are well-formed.
Shell Completions
Generate a completion script for your shell and source it:maestro-cli reference (Markdown or --format json); docs/cli-reference.md is generated from it via npm run gen:cli-reference.
Cue Automation
Interact with Maestro Cue subscriptions directly from the command line.Listing Subscriptions
List all Cue subscriptions across all agents:Triggering a Subscription
Manually trigger a Cue subscription by name, bypassing its normal event conditions:
The
--prompt flag is especially useful for cli.trigger subscriptions, where the prompt text is available in the subscription’s template as {{CUE_CLI_PROMPT}}.
Examples:
Director’s Notes
Director’s Notes is an Encore feature (encoreFeatures.directorNotes) that builds a unified history view across every agent in your fleet, plus an AI-generated synopsis of recent activity.
synopsis requires the desktop app to be running; history reads from disk and works offline. If encoreFeatures.directorNotes is disabled, enable it first with maestro-cli settings set encoreFeatures.directorNotes true.
Publishing Session Transcripts to Gists
Publish an agent’s session transcript to a GitHub gist so you can share it with collaborators or attach it to a bug report. Routes through the running Maestro desktop app (which holds the live transcript) and uses the user’s authenticatedgh CLI under the hood.
Output is JSON with the gist URL on success:
gh to be authenticated (gh auth login). Error codes: AGENT_NOT_FOUND, MAESTRO_NOT_RUNNING, GIST_CREATE_FAILED.
Scheduling with Cron
Agent Integration
Maestro agents are automatically informed aboutmaestro-cli through the system prompt. Each agent receives the platform-appropriate CLI invocation command via the {{MAESTRO_CLI_PATH}} template variable, which resolves to the full node "/path/to/maestro-cli.js" command for the current OS.
This means agents can:
- Read settings to understand the current Maestro configuration
- Change settings on behalf of the user (e.g., “switch to the nord theme”, “increase font size”)
- Manage agent configs (e.g., “set the Codex context window to 128000”)
- List resources like agents, groups, and playbooks
- Open files in the Maestro file preview tab
- Refresh the file tree after creating or modifying files
- Configure and launch auto-runs with documents they create
- Send messages to other agents for inter-agent coordination
- Discover Cue subscriptions with
cue listand trigger automation pipelines withcue trigger
settings list -v to discover available settings with descriptions, giving them full context to reason about configuration changes.
Requirements
- At least one AI agent CLI must be installed and in PATH (Claude Code, Codex, or OpenCode)
- Maestro config files must exist (created automatically when you use the GUI)