Reference for broker-level command surfaces that are useful to integrations.
mcp-args
Compute per-CLI MCP args without spawning.
agent-relay-broker mcp-args \
--cli claude \
--agent-name reviewer \
--api-key rk_live_example \
--base-url https://api.relaycast.dev \
--cwd /Users/me/projectSample output:
{
"args": [
"--mcp-config",
"{\"mcpServers\":{\"relaycast\":{\"command\":\"npx\",\"args\":[\"-y\",\"@relaycast/mcp\"]}}}"
],
"sideEffectFiles": [],
"agentToken": null
}Flags:
| Flag | Required | Description |
|---|---|---|
--cli <name> | yes | CLI name or command to compute MCP args for, such as claude, codex, opencode, cursor-agent, gemini, or droid. |
--agent-name <name> | yes | Relaycast agent name to inject into the MCP configuration. |
--api-key <key> | no | Relaycast API key. Falls back to RELAY_API_KEY. |
--base-url <url> | no | Relaycast base URL. Falls back to RELAY_BASE_URL. |
--agent-token <token> | no | Pre-registered agent token to pass to the child MCP server. |
--register | no | Mint a fresh Relaycast agent token with --api-key/RELAY_API_KEY and --base-url/RELAY_BASE_URL; mutually exclusive with --agent-token. |
--workspaces-json <json> | no | Multi-workspace context JSON to pass to the child MCP server. |
--default-workspace <workspace> | no | Default workspace ID or name to pass to the child MCP server. |
--cwd <path> | no | Working directory used by CLIs that need local MCP config files. Defaults to the current directory. |
--existing-args <json> | no | Existing CLI args as a JSON string array, for example '["--foo","--bar"]'. Defaults to []. |
agentToken is null unless --register successfully minted and injected a fresh Relaycast agent token.
mcp-args writes side-effect files synchronously when the target CLI requires a config file. For opencode, it may write <cwd>/opencode.json; for cursor, cursor-agent, and agent, it may write <cwd>/.cursor/mcp.json; for gemini, it may write <HOME>/.gemini/trustedFolders.json. Treat the command as compute plus configure for those CLIs, not as a side-effect-free dry run.
view
Stream a running agent's PTY output to your terminal in real time. view is read-only: keystrokes are not forwarded to the agent, and the broker keeps doing whatever it was doing. Multiple view clients can attach to the same agent simultaneously. Exit with Ctrl+C — the agent keeps running under the broker.
agent-relay view reviewerThe client auto-discovers the running broker by reading .agent-relay/connection.json in the current directory. On attach, it first captures the agent's current visible screen via GET /api/spawned/{name}/snapshot?format=ansi and writes the reproduction bytes to your terminal — so you immediately see whatever the agent is looking at, not a blank window. It then opens a WebSocket to the broker and filters for worker_stream events matching the named agent for live deltas. ANSI escape sequences are preserved byte-for-byte so colors and cursor moves render correctly.
Flags:
| Flag | Required | Description |
|---|---|---|
--broker-url <url> | no | Broker base URL. Falls back to RELAY_BROKER_URL, then .agent-relay/connection.json. |
--api-key <key> | no | Broker API key. Falls back to RELAY_BROKER_API_KEY, then the api_key field in connection.json. |
--state-dir <dir> | no | Directory containing connection.json to use for auto-discovery. Defaults to .agent-relay/ under the project root. |
If the initial snapshot can't be served (broker hiccup, transient timeout) view prints a warning to stderr and falls through to the live stream — you may briefly see a blank screen until the agent next produces output. If the agent doesn't exist or has no PTY (headless worker), view aborts with an explanatory error.
view shares the snapshot-on-attach helper with the drive and passthrough verbs so all three open with a faithful redraw of the agent's current screen.
drive
Take interactive control of a running agent. drive flips the worker's inbound delivery mode to manual_flush so the broker parks new inbound relay messages in a per-worker FIFO queue, forwards your keystrokes to the worker's PTY, lets you drain the queue on demand, and detaches cleanly without killing the agent.
agent-relay drive reviewerThe client auto-discovers the running broker the same way view does (--broker-url → RELAY_BROKER_URL → .agent-relay/connection.json). On attach it:
- Records the worker's current inbound delivery mode so it can be restored on detach.
- Calls
PUT /api/spawned/{name}/delivery-modewith{ "mode": "manual_flush" }to start queueing relay messages. - Captures and renders the agent's current visible screen via
GET /api/spawned/{name}/snapshot?format=ansi. - Calls
GET /api/spawned/{name}/pendingonce to seed the status-line counter. - Opens a WebSocket to
/wsand subscribes toworker_stream,delivery_queued, andagent_pending_drainedevents for this agent. - Switches local stdin to raw mode and forwards keystrokes to
POST /api/input/{name}. - Syncs the agent's PTY dimensions to your local terminal via
POST /api/resize/{name}and forwards every subsequentSIGWINCH. Without this, a TUI in the agent would render into whatever 24×80 box the PTY was spawned with regardless of how big your terminal actually is. Skipped entirely when stdout isn't a TTY.
On detach (clean or abnormal), drive best-effort restores the worker's previous inbound delivery mode so the queue doesn't fill up indefinitely, and leaves the agent running under the broker.
Flags:
| Flag | Required | Description |
|---|---|---|
--broker-url <url> | no | Broker base URL. Falls back to RELAY_BROKER_URL, then .agent-relay/connection.json. |
--api-key <key> | no | Broker API key. Falls back to RELAY_BROKER_API_KEY, then the api_key field in connection.json. |
--state-dir <dir> | no | Directory containing connection.json to use for auto-discovery. Defaults to .agent-relay/ under the project root. |
Keybinds:
| Keys | Action |
|---|---|
Ctrl+G | Flush the pending queue (POST /api/spawned/{name}/flush). The broker injects each queued message in FIFO order and emits agent_pending_drained. |
Ctrl+B then D / d / Ctrl+D | Detach cleanly. Restores the worker's prior inbound delivery mode, closes the WebSocket, exits 0. The parser accepts uppercase, lowercase, or Ctrl+D after the Ctrl+B prefix. |
Ctrl+B then ? | Toggle a small help hint inside the status line. |
Ctrl+C | Safety alias for detach. drive never kills the agent — use agent-relay agents:kill for that. |
Ctrl+B then any other key | Forwarded to the agent unchanged so TUI apps that use Ctrl+B themselves aren't deprived. |
Status line: drive paints a one-line summary on the bottom row of your terminal using ANSI save/restore-cursor escapes so the agent's output isn't disturbed. It shows the agent name, current inbound delivery mode, and the number of relay messages currently queued. The line repaints whenever the queue size changes (delivery_queued / agent_pending_drained) or the agent emits new output.
[drive reviewer | delivery=manual_flush | pending=3 | Ctrl+G flush | Ctrl+B D detach]
Example session:
# Take over the `reviewer` agent
agent-relay drive reviewer
# … type instructions interactively, watch the queue grow as other agents
# send messages, flush them when you're ready with Ctrl+G, detach with
# Ctrl+B D when you're done.drive is single-driver-assumed: if two drive clients attach to the same worker, last writer wins on keystrokes and they both see the same WebSocket stream. There is no multi-driver coordination — the broker treats each client's keystrokes as independent input.
The auto-inject sibling is passthrough below.
passthrough
Watch a running agent with auto-injection enabled. Where drive flips the worker into manual_flush and parks inbound relay messages in a queue, passthrough leaves the worker in auto_inject mode (the broker default) so the broker auto-injects inbound relay messages into the agent's PTY while you also type. Both streams race — that's the verb's whole point. Use passthrough when you want to observe and occasionally nudge while the broker does its coordination thing; use drive when you want exclusive deterministic control.
agent-relay passthrough reviewerConnection discovery, snapshot-on-attach, resize forwarding, and detach semantics are identical to drive. On attach, passthrough issues an idempotent PUT /api/spawned/{name}/delivery-mode with { "mode": "auto_inject" } so a worker that someone left in manual_flush mode is moved back to auto-inject for the duration of your session, and the prior mode is restored on detach.
Flags:
| Flag | Required | Description |
|---|---|---|
--broker-url <url> | no | Broker base URL. Falls back to RELAY_BROKER_URL, then .agent-relay/connection.json. |
--api-key <key> | no | Broker API key. Falls back to RELAY_BROKER_API_KEY, then the api_key field in connection.json. |
--state-dir <dir> | no | Directory containing connection.json. Defaults to .agent-relay/. |
Keybinds:
| Keys | Action |
|---|---|
Ctrl+B then D / d / Ctrl+D | Detach cleanly. Restores the worker's prior inbound delivery mode, closes the WebSocket, exits 0. |
Ctrl+B then ? | Toggle the inline help hint in the status line. |
Ctrl+C | Safety alias for detach — passthrough never kills the agent. |
Ctrl+B then any other key | Forwarded to the agent unchanged. |
passthrough does not bind Ctrl+G (there's no queue to flush in auto_inject mode — that's a drive concept). The status line is similar to drive's but without the pending counter:
[passthrough reviewer | delivery=auto_inject | Ctrl+B D detach]
passthrough is single-driver-assumed in the same way drive is — last writer wins on keystrokes between the broker's auto-inject and your typing.
new
Spawn a new agent under the broker. Headless by default — the agent keeps running as a child of the broker and you attach later with view, drive, or passthrough. Pass --attach to immediately open a session.
# Spawn-only (headless): agent survives in the background.
agent-relay new Alice claude
agent-relay new Alice claude --task "review the auth changes"
agent-relay new Alice claude --channels general,reviews --model opus
# Spawn + attach in one shot.
agent-relay new Alice claude --attach # default mode: drive
agent-relay new Alice claude --attach --mode passthrough # auto-inject + human types alongside
agent-relay new Alice claude --attach --mode view # read-only
agent-relay new Alice claude --attach --ephemeral # release on client exitnew POSTs to /api/spawn with the supplied positional CLI (claude, codex, gemini, opencode, aider, …) and any trailing args, then either prints a one-line attach hint and exits (default), or composes the matching session verb (with --attach).
It's the lightest spawn entry point in the CLI — the longer-form spawn command does the same thing but autostarts a broker if there isn't one.
With --attach --ephemeral, the client registers a teardown that calls DELETE /api/spawned/{name} on clean detach, SIGINT, SIGTERM, or abnormal WebSocket close. Without --ephemeral, the agent keeps running after detach. --mode and --ephemeral are ignored without --attach (and produce a stderr warning if you try).
Positional arguments:
| Position | Required | Description |
|---|---|---|
<name> | yes | Agent name. Matches the positional shape of drive, view, passthrough, and rm. |
<cli> | yes | CLI to spawn (claude, codex, gemini, opencode, aider, …). |
[args...] | no | Extra positional arguments passed through to the spawned CLI. |
Flags:
| Flag | Required | Description |
|---|---|---|
--task <task> | no | Initial task description sent to the agent on spawn. |
--channels <list> | no | Comma-separated channel names for the agent to join. |
--cwd <path> | no | Working directory for the agent's process. |
--team <team> | no | Team name for the agent. |
--model <model> | no | Model override (e.g. opus, sonnet, gpt-4o). |
--attach | no | After spawning, immediately open a session (default mode: drive). |
--mode <mode> | no | With --attach: session to open (view, drive, or passthrough). Defaults to drive. |
--ephemeral | no | With --attach: release the agent on client exit. |
--broker-url <url> | no | Broker base URL. Falls back to RELAY_BROKER_URL, then .agent-relay/connection.json. |
--api-key <key> | no | Broker API key. Falls back to RELAY_BROKER_API_KEY, then the api_key field in connection.json. |
--state-dir <dir> | no | Directory containing connection.json. Defaults to .agent-relay/. |
-n NAME CLI shorthand
A bare -n NAME CLI invocation is also recognised — it routes to the spawn-and-attach composition in passthrough mode with --ephemeral on:
agent-relay -n Alice claudeis equivalent to:
agent-relay new Alice claude --attach --mode passthrough --ephemeralThe shorthand is detected by a small pre-parse pass before Commander runs.
| Shape | Routes to |
|---|---|
agent-relay -n NAME CLI [args...] | agent-relay new NAME CLI [args...] --attach --mode passthrough --ephemeral |
agent-relay --name NAME CLI [args...] | (same) |
agent-relay -nNAME CLI [args...] | (same — joined short flag form) |
agent-relay --name=NAME CLI [args...] | (same — equals form) |
rm
Release a running agent via the broker. Wraps DELETE /api/spawned/{name} — the lightweight counterpart to the longer-form release command, useful when you already have a broker running and don't want the SDK-client autostart.
agent-relay rm AliceFlags:
| Flag | Required | Description |
|---|---|---|
--broker-url <url> | no | Broker base URL. Falls back to RELAY_BROKER_URL, then .agent-relay/connection.json. |
--api-key <key> | no | Broker API key. Falls back to RELAY_BROKER_API_KEY, then the api_key field in connection.json. |
--state-dir <dir> | no | Directory containing connection.json. Defaults to .agent-relay/. |
Returns 1 with a friendly error if the agent doesn't exist (404) or the broker is unreachable.
The new, passthrough, and rm verbs above round out the attach-style client surface alongside view and drive. Together they're the first-class client interface on the broker's HTTP and WebSocket routes.
log
Inspect and prune the broker's daily-rotated tracing logs. The broker writes them to ~/Library/Logs/agent-relay/ (macOS), ~/.local/state/agent-relay/logs/ (Linux), or %LOCALAPPDATA%\agent-relay\Logs\ (Windows). See the broker lifecycle docs for the env var that controls destination (AGENT_RELAY_BROKER_LOG).
agent-relay log path
agent-relay log list [brokerId]
agent-relay log view <brokerId> [-n 200] [--file <path>]
agent-relay log rotate [--keep-days 7] [--broker-id <id>] [--dry-run]
agent-relay log clear [--broker-id <id>] [--force] [--dry-run]Subcommands:
| Subcommand | Description |
|---|---|
path | Print the log directory for the current platform. |
list [brokerId] | List broker log files (name, date, size, mtime), newest first. Filters by broker id when supplied. |
view <brokerId> | Tail the newest log file for the broker. -n / --lines controls the trailing line count (default 200). --file <path> reads a specific rotated file instead. |
rotate | Delete rotated files older than --keep-days (default 7). --broker-id scopes to one broker; --dry-run previews without deleting. The active un-suffixed file is always kept. |
clear | Delete every matching file, including the active one. Requires either --broker-id <id> or --force to avoid accidental full wipes. |
The same logic is available programmatically via the SDK helpers getBrokerLogDir, listBrokerLogs, tailBrokerLog, pruneBrokerLogs, and clearBrokerLogs exported from @agent-relay/sdk — see the TypeScript SDK docs.