Skip to main content
Maestro includes a CLI tool (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:
Alternatively, run directly with Node.js:

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.
The response is always JSON:
On failure, 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:
Everything after -- 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).
Output is always JSON. 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:
Currently supported for claude-code agents.

Session Inspection

Inspect open AI tabs across the running Maestro desktop app and read their conversation history. Pair dispatch --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:
Default text columns: 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:
To extract just 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 with create-agent -g or update-agent --group to place agents into it, and update-agent --group none to move an agent back out.
Removing a group never deletes the agents inside it: the desktop ungroups any members (moves them to no group) and then removes the group. 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.
The optional --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.
Find tab IDs with 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 (the playbook 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.
playbook vs run-doc vs auto-run --launch: use playbook <id> for a saved playbook and run-doc <docs> for raw documents - both run headlessly with no desktop dependency. auto-run --launch instead hands the run to the running desktop app (needed only when you want the run to appear and be controlled in the desktop UI).
--agent accepts a name: the -a, --agent flag 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 in core-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:
The file format is:

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.
Use maestro-cli settings list -v from inside an AI agent conversation to give the agent full context about every available setting and what it controls.

Theme and Encore Features

Ergonomic, validated wrappers over the underlying settings, for the customizations users most often ask for by voice. Unlike settings set (which writes the settings file), these route through the running desktop app, so the change applies live. The app must be running.
Encore feature IDs: 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.
Export files are byte-compatible with the in-app Custom Theme Builder, so a palette round-trips between the UI and CLI. 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:
If the partial ID is ambiguous, the CLI will show all matches.

JSON Output

By default, commands output human-readable formatted text. Use --json for machine-parseable output:
The 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. Only http(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’s cwd; 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 --dismissible so 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 with auto-run --launch. They require the desktop app to be running.
The filename for 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:
Returns the app version, uptime, and connection status.

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.
The version and “App handles commands” checks catch the most common gotcha: a freshly-built CLI talking to an older desktop app that’s still running. When the app is behind, new commands fail because their handlers don’t exist in the running build - rebuild and restart the desktop app. The CLI surfaces this directly: a command the running app doesn’t recognize fails fast with “The running Maestro app does not support the ’…’ command” instead of a generic timeout.

Shell Completions

Generate a completion script for your shell and source it:
The script is generated by introspecting the live command tree, so regenerating it after a CLI upgrade picks up new commands and flags automatically. The full command list is also available as 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:
Shows each subscription’s name, event type, agent, enabled status, and last trigger time.

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 authenticated gh CLI under the hood.
Output is JSON with the gist URL on success:
Requires the Maestro desktop app to be running and 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 about maestro-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 list and trigger automation pipelines with cue trigger
When a user asks an agent to change a Maestro setting, the agent can use the CLI directly rather than instructing the user to navigate the settings modal. Changes take effect instantly. The system prompt instructs agents to use 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)