> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tuple.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Command reference

> Read Tuple CLI commands, flags, output formats, and Capture delivery behavior.

<View title="macOS" icon="apple">
  This page covers the commands provided by the `tuple` CLI. For installation instructions, see the [Tuple CLI overview](/cli/overview).

  ## Global flags

  | Flag | Description |
  | - | - |
  | `--format text\|json` | Output format. `text` is the default. Choose `json` for structured output. |
  | `-H`, `--host <path>` | Tuple app socket. `TUPLE_HOST` supplies the same setting. |
  | `--env dev\|prod\|staging` | Tuple environment. `TUPLE_ENV` supplies the same setting. An explicit host takes precedence. |

  Errors go to stderr. With `--format json`, errors are JSON objects with an `error` field and may include `error_code` and `kind`. Use JSON for a stable machine-readable contract. Text output is for people.

  ## Person arguments

  Commands with a `<person>` argument search contact names and email addresses. One match selects that contact. No matches return an error. Multiple matches return an error and list the candidates.

  ## `tuple contacts`

  ### `contacts list [flags]`

  List contacts, sorted by favorites, presence, then name.

  | Flag | Description |
  | - | - |
  | `-q`, `--query <text>` | Search by name or email. |
  | `--status <status>` | Keep `online`, `busy`, or `offline` contacts. `available` is a synonym for `online`. |
  | `--kind <kind>` | Keep `teammate`, `external`, or `agent` contacts. |
  | `--favorited[=false]` | Keep favorited contacts, or pass `false` for unfavorited contacts. |
  | `--recent` | Keep recently contacted people. |

  Filters combine with AND. An empty result succeeds and returns an empty list.

  ```bash theme={null}
  tuple contacts list --query ben
  tuple contacts list --status online --kind teammate
  tuple contacts list --favorited --recent
  ```

  ### `contacts follow`

  Emit the complete contact list as JSON Lines whenever it changes. The first line is the initial snapshot. This command does not accept the list filters.

  ### `contacts show <person>`

  Show one contact's ID, name, email, presence, kind, and favorite state.

  ### `contacts favorite <person>` / `contacts unfavorite <person>`

  Favorite or unfavorite a contact.

  ### `contacts remove <person>`

  Remove a contact.

  ### `contacts invite <email>`

  Invite someone to Tuple by email.

  ## `tuple call`

  ### `call list [flags]`

  List ongoing calls.

  | Flag | Description |
  | - | - |
  | `-q`, `--query <text>` | Search participant names, emails, room names, and room slugs. |
  | `--favorited[=false]` | Filter by whether a call involves a favorite. |
  | `--joinable[=false]` | Filter by whether you can join the call. |
  | `--limit <n>` | Maximum calls. The default is `100`; pass `-1` for all. |

  ### `call show [call] [--only <field>]`

  Show the active call, or select an active or retained call by exact ID. An unambiguous retained-call ID prefix also works.

  `--only` prints one field without a label. Valid fields are `id`, `state`, `participants`, `title`, `summary`, `started_at`, and `ended_at`.

  ```bash theme={null}
  call_id="$(tuple call show --only id)"
  tuple call show dbd433b7 --format json
  ```

  If you omit the selector while outside a call, the command returns `not in a call` and exits nonzero.

  ### `call edit [call]`

  Set a call's title or summary. You must pass `--title`, `--summary`, or both. An empty value clears that field.

  ### `call start <person-or-machine-id>`

  Start a 1:1 call with a contact or one of your connected machines. Get machine IDs from [`machines list`](#machines-list).

  The command waits for the other person to answer. It prints `Calling <name> (call <id>)...` when the call is placed and `<name> answered` when they connect. With `--format json`, it prints the call after they answer.

  The command exits `0` when they connect and `2` if the call ends first, such as when they decline, are busy, or don't answer. Tuple ends an unanswered call after 25 seconds.

  ### `call join <person-or-url>`

  Join a contact's call or a room slug or URL. Tuple tries the argument as a contact first. Pass `--switch` to leave your current call before joining.

  ### `call accept`

  Accept an incoming call. `--call` defaults to `current`, which is the call that is ringing. Scripts should pass the call's ID, such as `TUPLE_TRIGGER_CALL_ID` from a [`call-incoming` trigger](/triggers/api-reference#call-incoming). A late accept then fails instead of answering a different call that started ringing since.

  The command fails if the call has already been answered or is no longer ringing.

  ### `call participants add <person>` / `call participants remove <person>`

  Add or remove someone from a call. Both commands accept `--call`, which defaults to `current`.

  `add --wait` waits for the person to connect. `--timeout` controls how long it waits and defaults to `30s`; `0` waits without a timeout. A wait exits `0` when they connect, `2` if the call ends first, and `3` on timeout.

  ### `call leave`

  Leave a call. `--call` defaults to `current`.

  ### `call mute` / `call unmute`

  Mute or unmute your microphone. `--call` defaults to `current`.

  ### `call react <sound>`

  Play `airhorn`, `trombone`, or `flute` for everyone on the call. `--call` defaults to `current`.

  ## `tuple rooms`

  Manage [Tuple rooms](/pairing-with-tuple/using-rooms). Existing-room commands accept an exact slug, such as `acme/general`, or a full room URL.

  ### `rooms list [flags]`

  List your personal and team rooms. Occupied rooms come first, followed by favorites, then name.

  | Flag | Description |
  | - | - |
  | `--kind <kind>` | Keep `personal` or `team` rooms. |
  | `--occupied` | Keep rooms with someone present. |
  | `--favorited[=false]` | Keep favorited rooms, or pass `false` for unfavorited rooms. |
  | `--limit <n>` | Maximum rooms. The default is `100`; pass `-1` for all. |
  | `--members` | Include a preview of member names in text output. |

  ### `rooms follow [flags]`

  Emit the complete filtered room list as JSON Lines when the result changes. It supports `--kind`, `--occupied`, `--favorited`, and `--limit`.

  ### `rooms show <slug-or-url>`

  Show one room by exact slug or URL.

  ### `rooms join <slug-or-url>`

  Join a room without resolving the argument as a contact. Pass `--switch` to leave your current call first.

  ### `rooms favorite <slug-or-url>` / `rooms unfavorite <slug-or-url>`

  Favorite or unfavorite a room.

  ### `rooms create <name>`

  Create a team room.

  ## `tuple machines`

  ### `machines list`

  List your other signed-in, connected machines. Each result contains its machine ID, platform, device name when available, and current call ID when that machine is in a call. Use a machine ID with `tuple call start` to call that device.

  ## `tuple screen`

  Save the shared screen as a JPEG with visible annotations composited in.

  ```bash theme={null}
  tuple screen
  tuple screen -o screenshot.jpg
  tuple screen -o -
  tuple screen --at 2026-05-19T10:00:00Z --call dbd433b7
  ```

  | Flag | Description |
  | - | - |
  | `-o`, `--output <path>` | Output path. The default is `tuple@<call-id>@<timestamp>.jpg`; use `-` for stdout. |
  | `--at <timestamp>` | Read an ISO8601 moment from a stored call. A timestamp without a zone uses local time. |
  | `--exact` | With `--at`, use the requested instant instead of settling an unfinished annotation forward. |
  | `--call <id>` | Call to inspect. The default is `current`. |
  | `--user <id>` | Sharer's user ID. The default is whoever is sharing. |

  For stored frames, read stderr for timing and annotation caveats.

  ## `tuple capture`

  Control [call capture](/pairing-with-tuple/capturing-calls), read its records, and find or export stored calls. The app owns the local archive. Use the CLI instead of reading its database directly.

  Capture records have three categories: `transcript`, `events`, and `content`. Read commands include all three unless `--exclude` removes a category.

  ### `capture start` / `capture stop`

  Start or stop capture. `--call` defaults to `current`.

  ### `capture show [call-id]`

  Print a finite snapshot, then exit. Omit the selector for the active call, use `current`, or pass a stored call ID or unique prefix. Use `--recording <uuid>` to select one recording session without a call selector.

  | Flag | Description |
  | - | - |
  | `--recording <uuid>` | Select one recording session. |
  | `--since <timestamp>` | Include records at or after this RFC3339 timestamp with a zone. |
  | `--until <timestamp>` | Include records at or before this RFC3339 timestamp with a zone. |
  | `--exclude <categories>` | Exclude `transcript`, `events`, or `content`. Repeat the flag or separate values with commas. |
  | `--timestamps clock\|rfc3339` | Timestamp style for text output. The default is `rfc3339`. |

  Text output is one readable line per record. `--format json` emits one canonical record per line as JSON Lines. It is not a single object or array. The number of lines grows with the selected records, so use `--since` and `--until` when a JSON consumer needs a bounded interval.

  ### `capture follow [call-id]`

  Follow records continuously. Without a call ID, it stays subscribed across calls. When pinned to a call or recording session, it ends with that scope.

  ### `capture next [call-id]`

  Return one batch and exit. The first read without `--cursor` returns the available catch-up immediately. To wait for later records, pass the highest delivered record ID back with `--cursor`.

  If the first read is empty and provides no record ID, use `--cursor 0` to start waiting.

  Use one foreground invocation at a time. Let your agent harness or task runner schedule the next invocation after it processes the result. Avoid an unattended shell polling loop.

  #### Live-read flags

  `follow` and `next` support these flags in addition to `--recording`, `--since`, `--exclude`, and `--timestamps`:

  | Flag | Description |
  | - | - |
  | `--cursor <id>` | Resume strictly after a durable capture record ID. |
  | `--batch <duration>` | Set a bounded window for accumulating records before emitting them, such as `60s`. |
  | `--wake-on <phrase>` | Flush a buffered batch when finalized speech contains this literal phrase. Repeatable. `@FILE` loads one phrase per line. |
  | `--wake-if <executable>` | Run a trusted executable to decide whether to flush early. Requires a positive `--batch` duration. |
  | `--timeout <duration>` | `next` only. Return empty after this much silence. The default is `30s`; `0` waits without a timeout. |

  For `follow` and `next`, `--since` applies only to the initial catch-up. Each JSON output line is either a canonical capture record or a synthetic status line such as `{"kind":"status","status":"call_ended","call_id":"..."}`. Status lines frame delivery. They are not stored capture records and have no durable record ID.

  A consumer should save the highest positive record `id` only after those records reach the model or destination. Preserve the call or recording selector and category exclusions when resuming. Never advance a checkpoint from a status line or a record with ID `0`.

  #### Wake phrases

  Use `--wake-on` with `--batch` to flush buffered output early. Matching is case-insensitive and applies only to finalized speech. `*` matches every finalized speech record. An `agent_prompt` flushes a batch regardless of wake phrases.

  `capture follow` watches each referenced `@FILE` and reloads it when it changes. `capture next` reads the file once. Wake phrases apply only to that command invocation.

  #### Programmable wake conditions

  Use `--wake-if FILE` on `capture follow` or `capture next` to decide when buffered context deserves attention. The mechanisms compose: `--batch` bounds accumulation, `--wake-on` provides an explicit phrase or wake-word interrupt, and `--wake-if` adds a programmable predicate. Either wake condition can flush early; a false predicate keeps buffering until another wake condition or the batch deadline.

  The predicate is provider-neutral. You can use a deterministic script, a local model, or a network classifier such as Jev. You supply the executable and any dependencies; Tuple does not bundle Jev. Pass an explicit path such as `./decision-ready` or an absolute path. Tuple does not search `PATH` or run the file through a shell.

  As the pending batch grows, Tuple sends one JSON object to the executable's stdin:

  ```json theme={null}
  {"version":1,"elapsed_ms":2300,"records":[{"id":7,"category":"transcript","type":"transcription_finished","time":"2026-09-21T14:00:00Z","data":{"text":"We should cache this lookup.","user_id":42}}]}
  ```

  `elapsed_ms` is the batch's age in milliseconds. `records` contains canonical Capture records in delivery order, after applying `--exclude`. Exit `0` to wake, `1` to keep buffering, or `2` or higher to report an error. Tuple ignores stdout. A failure, missing executable, or 10-second execution timeout ends the CLI command with an error.

  For example, give an agent earlier context to draft a decision note when a proposal gets agreement. With `jq` installed, save this local rule as `decision-ready`. It looks for “we should” and either “sounds good” or “agreed” in finalized speech within the pending batch:

  ```sh theme={null}
  #!/bin/sh
  exec jq -e '
    if .version != 1 then error("Unsupported wake protocol") else
      [.records[] | select(.type == "transcription_finished") | .data.text]
      | join("\n")
      | test("\\bwe should\\b"; "i") and test("\\b(sounds good|agreed)\\b"; "i")
    end
  '
  ```

  ```bash theme={null}
  chmod +x ./decision-ready
  tuple --format json capture follow current --batch 60s \
    --wake-on "Hey Tuple" --wake-if ./decision-ready --exclude events,content
  ```

  Connect this stream to your agent runner to act on the context. `follow` skips predicate calls for its opening backlog. After a wake, it flushes immediately and streams without buffering for about 15 seconds. `next` instead collects until about one second of quiet, capped at about 15 seconds after the wake.

  Use only an executable you trust. It runs with your permissions, inherits the CLI environment, and receives transcript contents. A network-backed classifier can send that conversation data to an external service.

  ### `capture list`

  List stored calls newest first. Results include call metadata, a segment count, and resolved participants.

  | Flag | Description |
  | - | - |
  | `--participant <text>` | Keep calls with a matching participant name or email. |
  | `--after <date>` | Keep calls starting on or after this date. |
  | `--before <date>` | Keep calls starting on or before this date. |
  | `--limit <n>` | Maximum calls. The default is `100`; pass `-1` for all. |

  ### `capture search <query>`

  Search stored speech and shared app names, window titles, and URLs. Results are newest first.

  | Flag | Description |
  | - | - |
  | `--kind spoken\|content\|all` | Select what to search. The default is `all`. |
  | `--call <id>` | Keep one call. Repeatable; accepts `current` or stored-call ID prefixes. |
  | `--recording <uuid>` | Keep one recording session. |
  | `--speaker <text>` | Keep speech from a matching speaker. |
  | `--participant <text>` | Keep calls with a matching participant. |
  | `--after <date>` / `--before <date>` | Bound results by date. |
  | `-C`, `--context <n>` | Include nearby speech segments around spoken matches. |
  | `--limit <n>` | Maximum matches. The default is `50`; pass `-1` for all. |
  | `--timestamps clock\|rfc3339` | Timestamp style for text output. |

  Use plain terms or quote a phrase. If the result set is broad, add participant, call, date, kind, or speaker filters.

  Each result identifies its `kind`, call ID, timestamp, and matching snippet. Spoken results also identify the speaker and can include `context_before` and `context_after`. Content results include the app name, window title, and URL when available.

  ### `capture export <destination>`

  Write selected records from one or more calls to one artifact file. The destination is replaced only after the complete artifact is ready. If no calls match, the command fails and leaves an existing destination untouched. On POSIX systems, the file mode is `0600`.

  | Flag | Description |
  | - | - |
  | `--as jsonl\|markdown\|text` | Artifact format. JSON Lines is the default. |
  | `--call <id>` | Select a call. Repeatable; accepts `current` or stored-call ID prefixes. |
  | `--recording <uuid>` | Select one recording session. It cannot be combined with `--call`. |
  | `--participant <text>` | Keep calls with a matching participant. |
  | `--after <date>` / `--before <date>` | Bound calls by start date. |
  | `--exclude <categories>` | Exclude capture categories. |

  Each JSON Lines artifact record preserves the canonical capture record and adds `call_id`. The global `--format json` changes only the command receipt; `--as` controls the artifact.

  ### `capture delete <call-id>`

  Permanently delete one stored call's conversation, events, content, and retained media. This cannot be undone.

  ### Recording sessions

  Each time capture starts, Tuple creates a recording-session UUID. `show`, `follow`, `next`, `search`, and `export` accept `--recording <uuid>`. The `call-capture-started` and `call-capture-complete` triggers provide it as `TUPLE_TRIGGER_RECORDING_ID`.

  ## `tuple notifications`

  The `--call` flag applies to every notification command and defaults to `current`.

  ### `notifications send`

  Post a notice without waiting for a response. `--title`, `--body`, and `--sender` are required. By default, the card persists until dismissal or cancellation.

  `--ephemeral` dismisses an unnoticed card after 10 seconds. `--interaction-timeout <duration>` sets a value from `2s` through `60s` and implies `--ephemeral`.

  ### `notifications ask`

  Post a decision card and wait. `--title`, `--body`, and `--sender` are required. `--accept-label` and `--reject-label` customize the buttons.

  The command prints `decision` and `notification_id`. It exits `0` only for `accepted`; `rejected` and `canceled` exit nonzero. The card has no timeout.

  ### `notifications list`

  Return bounded notification containers with their current state, response, timestamps, and lifecycle.

  ### `notifications follow`

  Follow notification lifecycle events. With `--format json`, each event is one JSON line. `--interval <duration>` buffers output.

  ### `notifications cancel <notification-id>`

  Withdraw a card you posted. Only the user can accept or reject it.

  ## `tuple whoami`

  Print the signed-in user's email in text output. `--format json` returns `id`, `email`, `full_name`, and `short_name`.

  ## `tuple state`

  Print a bounded orientation summary. It contains the active call, current user, contact and room counts, pending-invite count, connection state, platform, app version, and available update. Its `see` map points to commands for full entity lists.

  The summary's `call` field is the same normalized Call shape returned by `tuple call show --format json`. Online favorite names are capped at 10. When `connection.websocket_state` is not `connected`, presence-derived counts are last-known. Pass `--raw` for the full daemon state.

  ### `state follow`

  Emit a complete bounded summary whenever it changes. With `--format json`, each summary is one JSON line. Pass `--raw` for the daemon's initial state and incremental event stream.

  ## `tuple agent guide [topic]`

  Read operating guidance embedded in this CLI build. Run `tuple agent guide` for the bounded index, then read only the topic your task needs.

  Topics include `automation`, `call-content`, `communication`, `connection`, `live-call`, `past-calls`, `safety`, and `troubleshooting`. An app-managed agent also gets `managed-agent`. Availability can hide guidance for unsupported operations.

  Use `connection` for call connectivity or quality diagnosis. Use command `--help` for exact flags.

  ### Session-specific agent commands

  The session's generated guidance exposes `agent message <text>` when agent messaging is available. It sends a message to the user's Tuple chat panel. Capture must be running for the message to enter the stored record.

  An app-designated managed run can expose `agent attention`. Its `--cadence` sets a duration in whole seconds and repeatable `--wake-on` values replace that run's wake phrases. Use only the commands exposed for the app-provided session; reading a guide does not enable a capability.

  ## `tuple connect [purpose]`

  Launch the configured AI agent with current-call context and embedded operating instructions. With `--call`, an active call supplies live context and an ended call supplies historical context. See [Connect an AI agent](/cli/connect).

  | Flag | Description |
  | - | - |
  | `--call <id>` | Select an active or ended call. |
  | `--harness <name>` | Agent to launch. |
  | `--model <name>` | Override the configured model when the harness supports it. |
  | `--reasoning <level>` | Override configured reasoning effort when the harness supports it. |

  ### `connect prompt [purpose]`

  Print the same instructions without launching an agent. It accepts `--call`.

  ### `connect configure [harness]`

  Configure the default agent and its launch settings. This command requires a terminal.

  ## `tuple mcp`

  Run the Tuple MCP server over stdin and stdout. See the [MCP server page](/cli/mcp).

  ### `mcp install [agent...]`

  Register the server with detected supported agents, or name one or more of `claude`, `claude-desktop`, and `codex`. Use `--name` to choose the server identifier.
</View>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.