Skip to content

The chorus CLI

The chorus command (published as @chorus-aidlc/chorus) does three jobs: it runs the Chorus server, configures the coding agents on your machine, and calls the Chorus MCP endpoint from the shell. Install it globally:

Terminal window
npm install --global @chorus-aidlc/chorus
chorus --version

Run chorus --help, or chorus <command> --help, for the complete flag list.

CommandWhat it does
chorusStart the Chorus server (the default with no subcommand). See Deploy with Docker.
chorus upgrade / chorus updateUpgrade the npm-global CLI; optionally refresh configured Chorus plugins with --plugins.
chorus agentsConfigure this machine’s agents — list (default), add, remove, and run (launch one).
chorus mcpNative MCP client — call a tool, print your UUID (whoami), or list callable tools.
chorus loginAuthenticate as an agent and save the connection to ~/.chorus/daemon.json.
chorus daemonKeep a runtime online so Chorus can wake it. See Operate the Chorus daemon.

From Chorus 0.20.0, use:

Terminal window
chorus upgrade # CLI only
chorus upgrade --plugins # CLI, then configured Chorus plugins
chorus update --plugins # alias of upgrade

The command works only with a global npm installation of @chorus-aidlc/chorus. It checks npm’s latest stable release, updates the active installation in the same npm prefix, and verifies the installed version. If the installed version is already current or newer, it neither reinstalls nor downgrades; --plugins still runs. Source checkouts, linked installs, and installs managed by other package managers are not supported. For an older CLI without this command, install the new release first with npm install --global @chorus-aidlc/chorus@latest.

It reads ~/.chorus/daemon.json and refreshes entries whose type is explicitly set to Claude Code, Codex, Kiro, or Pi, including those with daemon waking disabled. Each entry’s env, PATH, and custom config home determine the target. Shared destinations are updated once; distinct homes are handled separately. The command currently reads only the default file, not the path set in CHORUS_DAEMON_CONFIG_PATH.

  • Claude Code and Codex: refresh the Chorus plugin using the host’s plugin mechanism.
  • Kiro: refresh Chorus templates from the entry’s configured Chorus instance. Upgrade that server first so it serves the new templates. Conflicting instance URLs for one shared destination are reported as incomplete.
  • Pi: stable >=0.99.0 <2.0.0 uses native MCP and updates only eligible @chorus-aidlc/chorus-pi installations. Pi 0.84.4–0.98.x retains the verified pi-mcp-adapter@5.0.0 pin. Other adapter constraints and Chorus pins/ranges/tags are preserved and may leave setup or latest refresh incomplete. No update of all extensions, Pi itself, or automatic removal of an existing adapter is performed. See Pi setup and migration.

If a host CLI is installed but its Chorus plugin is missing, the command installs the plugin. It preserves registrations and credentials and does not install or upgrade the host CLI. Before changing a config file, it saves a copy as <file>.chorus-upgrade.bak (overwritten by the next upgrade).

offline or unknown entries (including the default OpenCode, OpenClaw, and dsh records), and hosts missing from the entry’s PATH, are skipped and reported as INCOMPLETE. For those hosts, follow the setup or upgrade steps in Agent platforms.

The command runs without prompts. Exit code 0 means all requested work completed; 1 means failure or an incomplete target. A missing daemon file or an empty agent list counts as success, with nothing to refresh; an unreadable or malformed file is a failure. If the CLI update fails, no plugins are refreshed. A failure on one plugin does not stop later targets, and completed updates are kept (there is no automatic rollback).

The npm install step streams its progress and has no timeout. If it fails, inspect the reported npm error; for EACCES or EPERM, use a user-owned Node installation or have the system npm prefix updated by its administrator. Chorus does not elevate privileges. After an update, start new agent sessions and run chorus daemon restart when convenient. Active sessions and the daemon are not restarted automatically.

chorus agents add is the one command that connects a machine’s coding agents to Chorus. It detects the agents you already have installed, installs each one’s Chorus plugin through that agent’s own plugin mechanism, and captures your Chorus URL and agent key once into ~/.chorus/daemon.json. For Claude Code, Codex, Hermes, and DeepSeek Harness it also writes the credential into that agent’s own configuration, so interactive sessions authenticate with no manual environment setup (see Where the credential goes).

Terminal window
chorus agents add # interactive: detect, pick, configure
chorus agents add --all --yes # configure every detected agent, no prompts
chorus agents add --agents claude,codex \
--url https://chorus.example.com --api-key cho_xxx

Setup can be rerun to add agents or refresh credentials. Supported agents are Claude Code, Codex, Kiro, Pi, OpenCode, OpenClaw, Hermes, and DeepSeek Harness (dsh). Pi setup selects native MCP for stable >=0.99.0 <2.0.0 or pi-mcp-adapter@5.0.0 for 0.84.4–0.98.x, alongside chorus-pi. Missing, unsupported, or uncertain Pi versions receive guidance rather than an unconditional MCP-complete claim. See Pi.

Useful flags (chorus agents add --help lists them all):

  • --agents <a,b> / --all — which agents to configure.
  • --url / --api-key — supply the credential non-interactively (env: CHORUS_URL / CHORUS_API_KEY).
  • --update-installed — refresh existing installations. For Pi, this runs pi update --extensions; simply repeating pi install does not update an already-installed package.
  • --dsh-profile <name> — the DeepSeek Harness profile to install the bundle into.
  • --daemon-wake <a,b> / --daemon-wake-all — opt the named (or every) wakeable agent into daemon waking. Wakeable agents (Claude Code, Codex, Kiro, Pi) are added parked by default — reachable by chorus mcp but not woken by the daemon until opted in here or at the per-agent TTY prompt.
  • --daemon-autostart — also install and enable the daemon boot service (Linux systemd / macOS launchd).
  • --no-linger — skip Linux systemd lingering setup or repair; it does not disable an existing setting. See daemon operations.
  • -y, --yes — skip confirmations (implied when not a TTY, where you must pass --agents or --all).

List and remove configured agents:

Terminal window
chorus agents # list configured agents (name, UUID, backend)
chorus agents remove <name|uuid> # remove one (match by name or UUID)

chorus agents never prints an API key. A listed name or UUID is a valid value for chorus mcp --agent or the CHORUS_AGENT_PROFILE environment variable.

For Codex, --yes never authorizes an App Server restart. Successful credential/MCP setup offers a separate interruption warning and consent prompt only in an interactive terminal. See Codex.

chorus agents add --agents hermes --hermes-cwd /path/to/repo installs both chorus and chorus-mcp from the CLI release tag, seeds $HERMES_HOME/.env, and configures the repository and unset approval defaults. --hermes-cwd <path> overrides the directory; otherwise setup keeps an existing directory or uses the current Git repository. Missing tags fail installation.

Hermes is registered as offline for Chorus daemon purposes. Neither chorus upgrade --plugins nor chorus agents run --type hermes supports it. After updating the CLI, rerun chorus agents add --agents hermes to reinstall both packages, then hermes gateway restart. See Hermes Agent for release-tag installation, remote MCP, skills, and owner approvals.

chorus agents run starts a configured agent in your terminal with its Chorus connection already wired in — the foreground counterpart to daemon waking. Because a child process cannot change its parent shell’s environment, the command injects the connection into the launched agent process directly, so you never export anything by hand.

Terminal window
chorus agents run --name work -- --model opus # launch agent "work"; pass --model opus to it
chorus agents run # launch the only configured agent
chorus agents run --name work --type codex -- resume # override the backend, then pass `resume` through
  • Which agent — --name <name|uuid> picks from agents[] in ~/.chorus/daemon.json. Optional when one agent is configured; with several, pass --name (or set CHORUS_AGENT_PROFILE), or the command exits with an error rather than guessing.
  • What’s injected (into the launched process only — never your shell, never printed): CHORUS_URL, CHORUS_API_KEY, and CHORUS_AGENT_PROFILE.
  • Which binary — defaults to the agent’s stored backend; --type overrides it. Types map to claude, codex, kiro-cli, pi, opencode, openclaw, and dsh. Agents added as OpenCode / OpenClaw / DeepSeek Harness are stored as offline (the daemon will not auto-wake them), so pass --type explicitly to launch those.
  • Passthrough — everything after -- goes to the agent verbatim, so its full flag surface is available. The agent inherits your terminal, and chorus agents run exits with its exit code.

Each selected agents[] entry can hold args (string array, default []) and env (string-to-string object, default {}). Both daemon wakes and foreground launches use them. When agents[] is non-empty, entries do not inherit top-level args / env, and setting them at the top level is an error. See the daemon guide for a copyable model/thinking/env example, flat-file migration, validation, and secret-handling precautions.

Values are literal, with no shell expansion, dotenv loading, or secret lookup. env affects only the launched agent. CHORUS_* and the Claude Code nesting variables CLAUDECODE / CLAUDE_CODE_ENTRYPOINT are reserved (case-insensitively): configuring one is an error rather than being silently dropped. Persistent args cannot override options Chorus manages (session, prompt, protocol, cwd, MCP, or permission controls), and cannot include -- / - separators or flags that only print help or version information and exit. Arguments you pass explicitly at launch are forwarded unchanged, including native resume commands. These checks guard against known conflicts; they are not a sandbox.

Each chorus agents run rereads the file; the daemon picks up changes only after chorus daemon restart. Neither affects agents that are already running. --type selects the backend used for validation and override matching; it does not translate backend flags.

For the options below only, passing one explicitly in the selected command scope replaces the configured option and its value:

Effective backendRecognized overrides
claude-code / claude--model, --effort
codex--model / -m / config key model; config key model_reasoning_effort
kiro--model, --effort
pi--model, --thinking, --provider
opencode--model / -m
openclaw--model, --thinking on agent (-m means message, not model)
dshNone; use DSH_PROVIDER / DSH_MODEL env instead

Matching recognizes --option value, --option=value, and, where listed, -mVALUE / -m=VALUE. Codex supports -c key=value, -ckey=value, -c=key=value, --config key=value, and --config=key=value; only the two listed keys participate in precedence, leaving unrelated config entries intact. The backend must support the spelling: for Pi 0.85.1, use separated --model, --thinking, and --provider values, not the equals forms.

Terminal window
chorus agents run --name pi-worker -- --model anthropic/claude-sonnet-4-6 --thinking medium
chorus agents run --name codex-worker -- exec --model gpt-5.4 -c model_reasoning_effort=high

Subcommands: persistent args go after the deepest recognized command: Codex exec, exec resume, or resume; Kiro chat; OpenClaw agent. Put the explicit override in that same scope: exec --model chosen, not --model chosen exec. A model option placed before the subcommand does not replace the subcommand’s configured model; Codex -c/--config keys apply across scopes. Without a recognized command, configured args are placed first. Other command paths are not inferred; omit incompatible persistent args and use native passthrough for those paths.

Unknown options:

  • Persistent args accepts ordinary unknown flags, but cannot guess whether the next token is a value or a prompt. Use ["--future=value"] if the backend supports it, not ["--future", "value"]. Known options require their expected values.
  • Unknown or repeatable options keep their order (configured first, then explicit) within the selected scope; there is no general last-wins guarantee.
  • After an ambiguous explicit option (an unknown option without an inline value), Chorus stops looking for overrides; put known overrides before it or use a supported inline value. Analysis also stops at the first bare -- inside agent arguments (after removing the outer Chorus delimiter).
  • Command discovery stops at a positional prompt, an unknown command, or an ambiguous option, and skips known option values.
  • All explicit tokens are still forwarded unchanged; checking backend flag and version compatibility is up to you. For Windows .cmd/.bat limits, see the daemon guide.

The Codex daemon further limits persistent args to model options and permitted -c / --config overrides. Other flags fail before the daemon wakes the agent, even if they work in a foreground session. See Codex daemon configuration.

Call MCP tools from the shell — chorus mcp

Section titled “Call MCP tools from the shell — chorus mcp”

chorus mcp is a native MCP client — a way to call any Chorus tool from a script or terminal without spending model tokens. It replaces the earlier chorus-api.sh / chorus-mcp-call.sh wrappers.

Terminal window
chorus mcp call <tool> '<json>' # call a tool with a JSON argument object
chorus mcp call <tool> --arg key=value # set one string argument
chorus mcp call <tool> --arg-file content=<path> # stream a file's raw bytes into an argument
chorus mcp whoami # print this agent's own UUID
chorus mcp list # list the tools this agent may call

--arg-file is how large content — a document body, an OpenSpec file — reaches a tool without being re-typed through the model. On success chorus mcp call prints the tool result verbatim on stdout; a tool or transport error goes to stderr with a non-zero exit code.

Identity resolves in this order: --agent <name|uuid> → explicit --url + --api-key flags → CHORUS_AGENT_PROFILE → CHORUS_URL + CHORUS_API_KEY → the single configured agent when only one exists.

VariableMeaning
CHORUS_URLThe Chorus instance URL.
CHORUS_API_KEYAn agent API key (cho_…).
CHORUS_AGENT_PROFILEOptional name or UUID of the configured agent to act as. When set, chorus mcp reads that agent’s key from ~/.chorus/daemon.json, so you need not export CHORUS_API_KEY.

Daemon-woken sessions receive CHORUS_AGENT_PROFILE automatically; you only set it by hand for an interactive shell that should act as a specific configured agent.

chorus agents add always writes the validated credential to ~/.chorus/daemon.json (mode 0600; the key is never echoed). For four agents it also seeds the agent’s own configuration so interactive sessions authenticate without any manual export:

AgentAlso written to
Claude CodeThe env block of ~/.claude/settings.json (honors CLAUDE_CONFIG_DIR).
Codex~/.codex/.env (honors CODEX_HOME); Codex reads its key from the environment through a keyless config.toml entry.
DeepSeek Harness$DSH_HOME/.env.
Hermes$HERMES_HOME/.env (default ~/.hermes/.env, mode 0600); remote MCP configuration stores a key placeholder.

Kiro, OpenCode, and OpenClaw read their credential from their own installed configuration or, for a daemon-woken Kiro, from the per-wake environment the daemon exports.

  • Triggers. You reach this page to install or upgrade the CLI, configure an agent (chorus agents add), or call a Chorus tool from the shell (chorus mcp call).
  • Constraints. Prefer chorus mcp call <tool> '<json>' --arg-file content=<file> for document-mirror and other large-content calls; fall back to chorus-api.sh / chorus-mcp-call.sh only when chorus is not on PATH. Never paste an API key onto a command line or into shell history — let chorus agents add / chorus login capture it.
  • Cite. Run chorus --help and chorus <command> --help for the authoritative flag surface; it always matches the installed version.