# CLI Reference

MindRoom provides a command-line interface for managing agents.

## Basic Usage

```bash
mindroom [OPTIONS] COMMAND [ARGS]...
```

## Commands

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root [OPTIONS] COMMAND [ARGS]...

 AI agents that live in Matrix and work everywhere via bridges.

 Quick start:
 mindroom config init   Create a starter config
 mindroom run           Start the system

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --install-completion            Install completion for the current shell.              │
│ --show-completion               Show completion for the current shell, to copy it or   │
│                                 customize the installation.                            │
│ --help                -h        Show this message and exit.                            │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────╮
│ version             Show the current version of Mindroom.                              │
│ run                 Run the mindroom multi-agent system.                               │
│ doctor              Check your environment for common issues.                          │
│ connect             Pair this local MindRoom install with the hosted provisioning      │
│                     service.                                                           │
│ local-stack-setup   Start local Synapse + MindRoom Chat using Docker only.             │
│ config              Manage MindRoom configuration files.                               │
│ plugins             Validate and vendor external MindRoom plugins.                     │
│ desktop             Connect allowlisted local applications to cloud MindRoom over      │
│                     Matrix E2EE.                                                       │
│ avatars             Generate and sync managed avatar assets.                           │
│ threads             Export Matrix threads to local files.                              │
│ service             Install and manage MindRoom as a background user service.          │
│ trigger             Send signed external triggers.                                     │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

## version

Show the current MindRoom version.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["version", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root version [OPTIONS]

 Show the current version of Mindroom.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --help  -h        Show this message and exit.                                          │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

## run

Start MindRoom with your configuration.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["run", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root run [OPTIONS]

 Run the mindroom multi-agent system.

 This command starts the multi-agent bot system which automatically:
 - Creates all necessary user and agent accounts
 - Creates all rooms defined in config.yaml
 - Manages agent room memberships
 - Starts the bundled dashboard/API server (disable with --no-api)

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --log-level     -l              TEXT     Set the logging level (DEBUG, INFO, WARNING,  │
│                                          ERROR)                                        │
│                                          [env var: LOG_LEVEL]                          │
│                                          [default: INFO]                               │
│ --config        -c              PATH     Use this config file path. Defaults the       │
│                                          storage location to the selected config       │
│                                          directory unless --storage-path is set.       │
│ --storage-path  -s              PATH     Base directory for persistent MindRoom data   │
│                                          (state, sessions, tracking)                   │
│ --api               --no-api             Start the bundled dashboard/API server        │
│                                          alongside the bot                             │
│                                          [default: api]                                │
│ --api-port                      INTEGER  Port for the bundled dashboard/API server     │
│                                          [default: 8765]                               │
│ --api-host                      TEXT     Host for the bundled dashboard/API server     │
│                                          [default: 0.0.0.0]                            │
│ --help          -h                       Show this message and exit.                   │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

## desktop

Connect explicitly allowlisted local applications to cloud MindRoom over Matrix end-to-end encryption.
See the [Matrix Desktop Bridge](https://docs.mindroom.chat/tools/desktop/) guide for the complete secure setup.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["desktop", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root desktop [OPTIONS] COMMAND [ARGS]...

 Connect allowlisted local applications to cloud MindRoom over Matrix E2EE.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --help  -h        Show this message and exit.                                          │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────╮
│ login   Log in once, create an Olm device, and save its access token privately.        │
│ pair    Claim one requester-agent pairing through authenticated Matrix E2EE.           │
│ setup   Log in when needed, then claim one requester-agent pairing.                    │
│ run     Run the outbound-only Matrix sync loop and execute locally authorized          │
│         commands.                                                                      │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

### desktop setup

Log in when no saved local Desktop session exists, then claim the requester-agent pairing in one command.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["desktop", "setup", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root desktop setup [OPTIONS]

 Log in when needed, then claim one requester-agent pairing.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ *  --code                              TEXT  Short-lived code returned by !desktop     │
│                                              setup.                                    │
│                                              [required]                                │
│ *  --controller-user-id                TEXT  Pinned cloud controller Matrix user.      │
│                                              [required]                                │
│ *  --controller-device-id              TEXT  Pinned cloud controller device.           │
│                                              [required]                                │
│ *  --controller-ed25519                TEXT  Pinned controller fingerprint. [required] │
│    --user-id                           TEXT  Expected Matrix user ID; required for     │
│                                              password login and optional for SSO.      │
│    --homeserver                        TEXT  Matrix homeserver URL; defaults to the    │
│                                              configured MindRoom homeserver.           │
│    --cloudflare-access                       Authenticate Matrix requests              │
│                                              interactively with the local cloudflared  │
│                                              CLI.                                      │
│                                              [env var:                                 │
│                                              MINDROOM_DESKTOP_CLOUDFLARE_ACCESS]       │
│    --matrix-http-headers-file          PATH  Owner-only JSON file of HTTP headers      │
│                                              added to every Matrix request.            │
│                                              [env var:                                 │
│                                              MINDROOM_DESKTOP_MATRIX_HTTP_HEADERS_FIL… │
│    --config                    -c      PATH  MindRoom config path used for runtime     │
│                                              env.                                      │
│    --storage-path              -s      PATH  Desktop bridge state directory.           │
│    --help                      -h            Show this message and exit.               │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

### desktop login

Create and privately save the dedicated local desktop Matrix device.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["desktop", "login", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root desktop login [OPTIONS]

 Log in once, create an Olm device, and save its access token privately.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --user-id                                     TEXT                 Expected Matrix     │
│                                                                    user ID; required   │
│                                                                    for password login  │
│                                                                    and optional for    │
│                                                                    SSO.                │
│ --homeserver                                  TEXT                 Matrix homeserver   │
│                                                                    URL; defaults to    │
│                                                                    the configured      │
│                                                                    MindRoom            │
│                                                                    homeserver.         │
│ --login-method                                [auto|password|sso]  Matrix login        │
│                                                                    method. Auto uses   │
│                                                                    password when       │
│                                                                    advertised,         │
│                                                                    otherwise browser   │
│                                                                    SSO.                │
│                                                                    [default: auto]     │
│ --sso-idp                                     TEXT                 Matrix SSO          │
│                                                                    identity-provider   │
│                                                                    ID. Selects SSO     │
│                                                                    when login method   │
│                                                                    is auto.            │
│ --open-browser           --no-open-browser                         Open Matrix SSO in  │
│                                                                    the default         │
│                                                                    browser; otherwise  │
│                                                                    print the URL.      │
│                                                                    [default:           │
│                                                                    open-browser]       │
│ --cloudflare-access                                                Authenticate Matrix │
│                                                                    requests            │
│                                                                    interactively with  │
│                                                                    the local           │
│                                                                    cloudflared CLI.    │
│                                                                    [env var:           │
│                                                                    MINDROOM_DESKTOP_C… │
│ --replace                                                          Replace the saved   │
│                                                                    session with a      │
│                                                                    fresh Matrix        │
│                                                                    device.             │
│ --matrix-http-head…                           PATH                 Owner-only JSON     │
│                                                                    file of HTTP        │
│                                                                    headers added to    │
│                                                                    every Matrix        │
│                                                                    request.            │
│                                                                    [env var:           │
│                                                                    MINDROOM_DESKTOP_M… │
│ --config             -c                       PATH                 MindRoom config     │
│                                                                    path used for       │
│                                                                    runtime env.        │
│ --storage-path       -s                       PATH                 Desktop bridge      │
│                                                                    state directory.    │
│ --help               -h                                            Show this message   │
│                                                                    and exit.           │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

### desktop run

Run the outbound-only local Matrix worker with exact controller, requester, and agent allowlists.
Control remains disabled unless the local command grants a short lease.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer import rich_utils -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- previous_max_width = rich_utils.MAX_WIDTH -->
<!-- rich_utils.MAX_WIDTH = 96 -->
<!-- result = runner.invoke(app, ["desktop", "run", "--help"]) -->
<!-- rich_utils.MAX_WIDTH = previous_max_width -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root desktop run [OPTIONS]

 Run the outbound-only Matrix sync loop and execute locally authorized commands.

╭─ Options ────────────────────────────────────────────────────────────────────────────────────╮
│ *  --controller-user-id               TEXT                        Pinned cloud controller    │
│                                                                   Matrix user.               │
│                                                                   [required]                 │
│ *  --controller-device-id             TEXT                        Pinned cloud controller    │
│                                                                   device.                    │
│                                                                   [required]                 │
│ *  --controller-ed25519               TEXT                        Pinned controller          │
│                                                                   fingerprint.               │
│                                                                   [required]                 │
│ *  --allow-requester                  TEXT                        Human Matrix requester     │
│                                                                   allowed to operate this    │
│                                                                   desktop; repeat as needed. │
│                                                                   [required]                 │
│ *  --allow-agent                      TEXT                        MindRoom agent name        │
│                                                                   allowed to operate this    │
│                                                                   desktop; repeat as needed. │
│                                                                   [required]                 │
│ *  --allow-app                        TEXT                        Exact local application ID │
│                                                                   exposed to the agent;      │
│                                                                   repeat as needed.          │
│                                                                   [required]                 │
│    --allow-control                                                Enable semantic and        │
│                                                                   fallback input for a short │
│                                                                   local lease. Default is    │
│                                                                   observe-only.              │
│    --lease-minutes                    INTEGER RANGE [1<=x<=60]    Local control lease        │
│                                                                   duration.                  │
│                                                                   [default: 15]              │
│    --max-screenshot-width             INTEGER RANGE               [default: 1600]            │
│                                       [320<=x<=3840]                                         │
│    --jpeg-quality                     INTEGER RANGE [40<=x<=95]   [default: 80]              │
│    --browser-extension                                            Expose Playwright MCP      │
│                                                                   control of an existing     │
│                                                                   browser profile when its   │
│                                                                   extension is installed.    │
│    --browser-executable               PATH                        Chrome-family executable   │
│                                                                   to open the Playwright     │
│                                                                   extension connection page, │
│                                                                   including Brave.           │
│    --browser-user-data-dir            PATH                        Existing browser user-data │
│                                                                   root containing the        │
│                                                                   profile where the          │
│                                                                   extension is installed.    │
│    --browser-timeout-seconds          INTEGER RANGE [1<=x<=120]   Local Playwright MCP call  │
│                                                                   timeout.                   │
│                                                                   [default: 90]              │
│    --log-level                -l      TEXT                        [default: INFO]            │
│    --cloudflare-access                                            Authenticate Matrix        │
│                                                                   requests interactively     │
│                                                                   with the local cloudflared │
│                                                                   CLI.                       │
│                                                                   [env var:                  │
│                                                                   MINDROOM_DESKTOP_CLOUDFLA… │
│    --matrix-http-headers-fi…          PATH                        Owner-only JSON file of    │
│                                                                   HTTP headers added to      │
│                                                                   every Matrix request.      │
│                                                                   [env var:                  │
│                                                                   MINDROOM_DESKTOP_MATRIX_H… │
│    --config                   -c      PATH                        MindRoom config path used  │
│                                                                   for runtime env.           │
│    --storage-path             -s      PATH                        Desktop bridge state       │
│                                                                   directory.                 │
│    --help                     -h                                  Show this message and      │
│                                                                   exit.                      │
╰──────────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

## avatars

Generate and sync managed avatar assets.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["avatars", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root avatars [OPTIONS] COMMAND [ARGS]...

 Generate and sync managed avatar assets.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --help  -h        Show this message and exit.                                          │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────╮
│ generate   Generate missing managed avatar files in the workspace.                     │
│ sync       Sync configured room and root-space avatars to Matrix using the initialized │
│            router account.                                                             │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

## avatars generate

Generate missing managed avatar files in the workspace.
In a source checkout, generated files are written under `./avatars/`.
In containerized deployments, generated overrides are written under the persistent MindRoom storage path.
Existing managed files are skipped by default.
Use `--force` to overwrite them after changing avatar prompts or styles.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["avatars", "generate", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root avatars generate [OPTIONS]

 Generate missing managed avatar files in the workspace.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --force            Overwrite existing managed workspace avatar files.                  │
│ --help   -h        Show this message and exit.                                         │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

## avatars sync

Sync configured room and root-space avatars to Matrix using the initialized router account.
Existing Matrix avatars are skipped by default.
Use `--force` to replace them.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["avatars", "sync", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root avatars sync [OPTIONS]

 Sync configured room and root-space avatars to Matrix using the initialized router
 account.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --force            Replace existing Matrix room and root-space avatars.                │
│ --help   -h        Show this message and exit.                                         │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

## threads

Export Matrix threads to local files.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["threads", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root threads [OPTIONS] COMMAND [ARGS]...

 Export Matrix threads to local files.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --help  -h        Show this message and exit.                                          │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────╮
│ export   Export Matrix threads to YAML files for grep/ripgrep search.                  │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

## threads export

Export Matrix threads to YAML files for grep/ripgrep search.
The command reads persisted Matrix accounts and rooms from `matrix_state.yaml`, so run MindRoom once before exporting.
Rooms joined through authorized invites (user-created rooms) are exported too, each with the invited entity's own account, unless `--no-invited-rooms` is passed.
By default it writes to `<storage>/thread_exports`.
A thread file is only rewritten when its content changed, so `exported_at` reflects the last content-changing export.
Each thread document includes the latest MindRoom thread summary as `thread.summary` when one exists.
Each room directory also gets an `index.json` mapping every thread file to its message count, participants, latest summary, and last activity, sorted by most recent activity.
Complete passes normally remove exported room and thread files that are no longer present or authorized; a `--room` pass only reconciles the selected room.
The zero-room guard skips only final directory-wide reconciliation of rooms absent from the pass, while definitive per-room category or membership revocations still delete their exports.
A warning is logged when that guard preserves existing target state because the pass has no positive room evidence.
A complete room enumeration that returns zero threads preserves existing YAML exports for that room and logs a warning because an anomalous empty response cannot be distinguished from deletion of the final thread.
After either warning, verify the source state and remove the preserved export manually only when the deletion is confirmed; workspace git history remains the recovery path for mistaken cleanup.
Enabled targets whose resolved output directories are equal or nested are all skipped before Matrix work.
MindRoom claims an output root by writing a `.mindroom-thread-exports` ownership marker, and it claims automatically when the root is empty or already holds a room directory containing an exported thread file.
A directory that merely contains an `index.json` is not treated as evidence, so pointing `--output` at an unrelated project or build directory is refused rather than adopted.
Unrelated entries beside those room directories, such as `.DS_Store`, a `.git` directory, or your own notes, neither block the claim nor ever get deleted.
A root MindRoom cannot recognize is skipped for the entire pass, so it is neither exported to nor cleaned up, and the skip is reported as a target failure.
Adopt such a root by creating `.mindroom-thread-exports` inside it containing exactly `{"format":"mindroom-thread-exports","version":1}` followed by a newline.
Cleanup then removes only recognizable room directories and thread YAML files, leaving unrelated entries untouched and logged.
Retracting a room whose directory still holds unrelated entries removes only the exported files and leaves the directory in place, and repeating the pass stays a quiet no-op.
Output paths with a terminal `.`, `..`, or empty leaf are rejected, as are symlinked final output and room directories.
With `--prefer-cache` thread bodies are served from the durable event cache and only fetched from the homeserver on miss or invalidation; use it alongside a running MindRoom that keeps the cache fresh.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["threads", "export", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root threads export [OPTIONS]

 Export Matrix threads to YAML files for grep/ripgrep search.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --config            -c                        PATH     Use this config file path.      │
│ --storage-path      -s                        PATH     Base directory for persistent   │
│                                                        MindRoom data.                  │
│ --output            -o                        PATH     Output directory. Defaults to   │
│                                                        <storage>/thread_exports.       │
│ --room              -r                        TEXT     Filter exported rooms by a      │
│                                                        substring of the room key,      │
│                                                        alias, name, or Matrix room ID. │
│ --watch                                                Repeat the export forever on a  │
│                                                        fixed interval.                 │
│ --interval                                    INTEGER  Watch interval in seconds.      │
│                                                        [default: 300]                  │
│ --max-thread-roots                            INTEGER  Maximum thread roots to         │
│                                                        enumerate per room.             │
│                                                        [default: 2000]                 │
│ --prefer-cache                                         Serve thread bodies from the    │
│                                                        durable event cache and only    │
│                                                        fetch from the homeserver on    │
│                                                        miss or invalidation. Use       │
│                                                        alongside a running MindRoom    │
│                                                        that keeps the cache fresh.     │
│ --invited-rooms         --no-invited-rooms             Include rooms joined through    │
│                                                        authorized invites              │
│                                                        (user-created rooms).           │
│                                                        [default: invited-rooms]        │
│ --help              -h                                 Show this message and exit.     │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

```bash
mindroom threads export --storage-path mindroom_data --output "$HOME/mindroom-thread-exports"
mindroom threads export --storage-path mindroom_data --room lobby
mindroom threads export --storage-path mindroom_data --watch --interval 300
mindroom threads export --storage-path mindroom_data --prefer-cache
```

## service

Install and manage MindRoom as a background user service.
MindRoom runs the version installed by this command through `uv tool run` and starts automatically at login.
Rerun `mindroom service install` after upgrading MindRoom.
On macOS, MindRoom uses launchd user agents.
On Linux, MindRoom uses systemd user services.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["service", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root service [OPTIONS] COMMAND [ARGS]...

 Install and manage MindRoom as a background user service.

 MindRoom runs the version installed by this command through `uv tool run` and starts
 automatically at login.
 Rerun `mindroom service install` after upgrading MindRoom.

 Supported platforms:
 - macOS: launchd (`~/Library/LaunchAgents/`)
 - Linux: systemd user services (`~/.config/systemd/user/`)

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --help  -h        Show this message and exit.                                          │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────╮
│ install     Install and start MindRoom as a background user service.                   │
│ uninstall   Stop and remove the MindRoom user service.                                 │
│ start       Start the installed MindRoom user service.                                 │
│ stop        Stop the installed MindRoom user service without removing it.              │
│ restart     Restart the installed MindRoom user service.                               │
│ status      Show MindRoom service status and recent logs.                              │
│ logs        Follow MindRoom service logs.                                              │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

### service install

Install and start MindRoom as a background user service.
Use `--no-confirm` for non-interactive setup.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["service", "install", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root service install [OPTIONS]

 Install and start MindRoom as a background user service.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --skip-deps             Skip uv dependency check.                                      │
│ --no-confirm  -y        Skip confirmation prompts.                                     │
│ --help        -h        Show this message and exit.                                    │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

### service status

Show MindRoom service status and recent logs.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["service", "status", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root service status [OPTIONS]

 Show MindRoom service status and recent logs.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --logs  -l      INTEGER  Number of recent log lines to show. Use 0 to hide logs.       │
│                          [default: 10]                                                 │
│ --help  -h               Show this message and exit.                                   │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

### service uninstall

Stop and remove the MindRoom user service.
On macOS, log files are preserved under `~/Library/Logs/mindroom/`.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["service", "uninstall", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root service uninstall [OPTIONS]

 Stop and remove the MindRoom user service.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --no-confirm  -y        Skip confirmation prompts.                                     │
│ --help        -h        Show this message and exit.                                    │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

## doctor

Check your environment for common issues before running `mindroom run`.

Runs a series of checks in one pass:

- **Config file** exists and is valid YAML with correct Pydantic schema
- **Providers** — validates API keys for each configured provider (Anthropic, OpenAI, Ollama, Vertex AI Claude, etc.)
- **Memory config** — checks memory LLM and embedder reachability (Ollama, OpenAI embeddings, sentence-transformers)
- **Matrix homeserver** — verifies the homeserver is reachable via `/_matrix/client/versions`
- **Storage** — confirms the storage directory is writable

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["doctor", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root doctor [OPTIONS]

 Check your environment for common issues.

 Runs connectivity, configuration, and credential checks in a single pass
 so you can fix everything before running `mindroom run`.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --config        -c      PATH  Use this config file path. Defaults the storage location │
│                               to the selected config directory unless --storage-path   │
│                               is set.                                                  │
│ --storage-path  -s      PATH  Base directory for persistent MindRoom data (state,      │
│                               sessions, tracking)                                      │
│ --help          -h            Show this message and exit.                              │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

## config

Manage MindRoom configuration files.
The `config` subgroup contains commands for creating, viewing, editing, and validating your `config.yaml`.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["config", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root config [OPTIONS] COMMAND [ARGS]...

 Manage MindRoom configuration files.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --help  -h        Show this message and exit.                                          │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────╮
│ init       Create a starter config.yaml with a personal agent and model.               │
│ show       Display the current config file with syntax highlighting.                   │
│ edit       Open config.yaml in your default editor.                                    │
│ validate   Validate config.yaml and check for common issues.                           │
│ resolve    Print the fully merged config YAML with all !include tags resolved.         │
│ path       Show the resolved config file path and search locations.                    │
│ migrate    Apply safe, text-preserving migrations to config.yaml.                      │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

### config init

Create a starter `config.yaml` with the personal Mind agent, one model, file-based memory, and sensible defaults.

Matrix server presets (`--matrix-server`) choose where MindRoom should create Matrix users and rooms: `mindroom.chat` (default hosted Matrix) or `self-hosted` (your own homeserver).
Provider presets (`--provider`) set the default model: `anthropic`, `codex`, `kimi`, `llama.cpp`, `ollama`, `openai`, `openrouter`, or `vertexai_claude`.
Generated configs include commented model alternatives for providers that have common variants, such as OpenAI mini/nano models.

```bash
# Hosted Matrix quickstart (creates ~/.mindroom/config.yaml)
mindroom config init

# Self-hosted Matrix with Anthropic
mindroom config init --matrix-server self-hosted --provider anthropic

# Hosted Matrix with a Codex CLI ChatGPT login
mindroom config init --matrix-server mindroom.chat --provider codex

# Hosted Matrix with Ollama
mindroom config init --matrix-server mindroom.chat --provider ollama

# Hosted Matrix with llama.cpp
mindroom config init --matrix-server mindroom.chat --provider llama.cpp

# Hosted Matrix with Vertex AI Claude
mindroom config init --matrix-server mindroom.chat --provider vertexai_claude

# Preview generated YAML without writing files
mindroom config init --matrix-server mindroom.chat --provider ollama --print

# Force overwrite existing config
mindroom config init --force
```

Use `--print` to preview the generated `config.yaml` in the terminal with YAML syntax highlighting.
It does not create or modify `config.yaml`, `.env`, or starter workspace files.

The `--provider codex` preset generates `provider: codex` with `id: gpt-5.6` and `context_window: 258000`.
They set `extra_kwargs.reasoning_effort: medium`.
Prompt caching is enabled automatically per active agent session; leave `prompt_cache_key` unset unless you intentionally want to override the derived key.
Run `codex login` first so MindRoom can read `~/.codex/auth.json`.

The `--provider kimi` preset generates `provider: kimi` with `id: k3` and `context_window: 1048576`.
Run `kimi` and `/login` first so MindRoom can read `~/.kimi-code/credentials/kimi-code.json`.

The `--provider ollama` preset generates `provider: ollama` with `id: gemma4`, an additional `qwen3_6_27b` model using `qwen3.6:27b`, and `OLLAMA_HOST=http://localhost:11434`.
Pull both local models before running MindRoom:

```bash
ollama pull gemma4
ollama pull qwen3.6:27b
```

The `--provider llama.cpp` preset generates OpenAI-compatible local server config for Unsloth GGUF models.
Start llama.cpp with one of the configured model refs before running MindRoom:

```bash
llama-server -hf unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q4_K_M --host 127.0.0.1 --port 8080
llama-server -hf unsloth/Qwen3.6-27B-GGUF:UD-Q4_K_XL --host 127.0.0.1 --port 8080
```

### config show

Display the current config file with syntax highlighting.

```bash
# Show config with syntax highlighting
mindroom config show

# Print raw YAML (useful for piping)
mindroom config show --raw

# Show config at a specific path
mindroom config show --path /custom/path/config.yaml
```

### config edit

Open `config.yaml` in your default editor.
Editor preference: `$EDITOR` → `$VISUAL` → `nano` → `vim` → `vi`.

```bash
mindroom config edit
```

### config validate

Validate `config.yaml` and check for common issues.
Parses the YAML config using Pydantic and reports errors in a friendly format.
Also checks whether required API keys are set as environment variables.

```bash
mindroom config validate
```

### config path

Show the resolved config file path and all search locations.

```bash
mindroom config path
```

## connect

Pair this local MindRoom install with a provisioning service.

Default provisioning URL is `https://mindroom.chat` unless you override it with `--provisioning-url` or `MINDROOM_PROVISIONING_URL`.

```bash
mindroom connect --pair-code ABCD-EFGH
```

On success (default `--persist-env`), this writes to `.env` next to `config.yaml`:

- `MINDROOM_PROVISIONING_URL`
- `MINDROOM_LOCAL_CLIENT_ID`
- `MINDROOM_LOCAL_CLIENT_SECRET`
- `MINDROOM_NAMESPACE`

If your config still contains the owner placeholder token `__MINDROOM_OWNER_USER_ID_FROM_PAIRING__`, `connect` will auto-replace it in authorization and managed-room admin settings when pairing returns a valid `owner_user_id`.

Use `--no-persist-env` if you want to export variables only for the current shell session.

```bash
mindroom connect --pair-code ABCD-EFGH --no-persist-env
```

Use `--provisioning-url` for non-default deployments:

```bash
mindroom connect \
  --pair-code ABCD-EFGH \
  --provisioning-url https://matrix.example.com
```

## local-stack-setup

Start local Synapse and the MindRoom Chat client container for development.

By default this command also writes `MATRIX_HOMESERVER`, `MATRIX_SERVER_NAME`, and `MATRIX_SSL_VERIFY=false` into `.env` next to your active `config.yaml` so `mindroom run` works without inline env exports.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["local-stack-setup", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root local-stack-setup [OPTIONS]

 Start local Synapse + MindRoom Chat using Docker only.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --synapse-dir                                 PATH                 Directory           │
│                                                                    containing Synapse  │
│                                                                    docker-compose.yml  │
│                                                                    (from               │
│                                                                    mindroom-stack      │
│                                                                    settings).          │
│                                                                    [default:           │
│                                                                    local/matrix]       │
│ --homeserver-url                              TEXT                 Homeserver URL that │
│                                                                    MindRoom Chat and   │
│                                                                    MindRoom should     │
│                                                                    use.                │
│                                                                    [default:           │
│                                                                    http://localhost:8… │
│ --server-name                                 TEXT                 Matrix server name  │
│                                                                    (default: inferred  │
│                                                                    from                │
│                                                                    --homeserver-url    │
│                                                                    hostname).          │
│ --cinny-port                                  INTEGER RANGE        Local host port for │
│                                               [1<=x<=65535]        the MindRoom Chat   │
│                                                                    container.          │
│                                                                    [default: 8080]     │
│ --cinny-image                                 TEXT                 Docker image for    │
│                                                                    MindRoom Chat.      │
│                                                                    [default:           │
│                                                                    ghcr.io/mindroom-a… │
│ --cinny-container-n…                          TEXT                 Container name for  │
│                                                                    MindRoom Chat       │
│                                                                    (legacy default     │
│                                                                    retained for        │
│                                                                    compatibility).     │
│                                                                    [default:           │
│                                                                    mindroom-cinny-loc… │
│ --skip-synapse                                                     Skip starting       │
│                                                                    Synapse (assume it  │
│                                                                    is already          │
│                                                                    running).           │
│ --persist-env             --no-persist-env                         Persist Matrix      │
│                                                                    local dev settings  │
│                                                                    to .env next to     │
│                                                                    config.yaml.        │
│                                                                    [default:           │
│                                                                    persist-env]        │
│ --help                -h                                           Show this message   │
│                                                                    and exit.           │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

## trigger

Send signed external trigger requests from cron jobs and watcher scripts.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["trigger", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root trigger [OPTIONS] COMMAND [ARGS]...

 Send signed external triggers.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --help  -h        Show this message and exit.                                          │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────╮
│ keygen   Generate an Ed25519 trigger signing key.                                      │
│ send     Send a signed external trigger request.                                       │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

### trigger keygen

Generate an Ed25519 signing key pair for an external trigger.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["trigger", "keygen", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root trigger keygen [OPTIONS]

 Generate an Ed25519 trigger signing key.

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --private-key-file          PATH  Path where the base64 raw Ed25519 private key should │
│                                   be written.                                          │
│ --help              -h            Show this message and exit.                          │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

### trigger send

Send one signed trigger request to MindRoom.

<!-- CODE:START -->
<!-- from mindroom.cli.main import app -->
<!-- from typer.testing import CliRunner -->
<!-- runner = CliRunner() -->
<!-- result = runner.invoke(app, ["trigger", "send", "--help"]) -->
<!-- print("```") -->
<!-- print(result.output) -->
<!-- print("```") -->
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```

 Usage: root trigger send [OPTIONS] TRIGGER_ID

 Send a signed external trigger request.

╭─ Arguments ────────────────────────────────────────────────────────────────────────────╮
│ *    trigger_id      TEXT  Configured external trigger id. [required]                  │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ *  --key-file                           FILE   Base64 raw Ed25519 private key file.    │
│                                                [required]                              │
│ *  --kind                               TEXT   Trigger payload kind. [required]        │
│ *  --message                            TEXT   Trigger payload message. [required]     │
│    --event-id                           TEXT   Optional idempotency event id.          │
│    --title                              TEXT   Optional trigger title.                 │
│    --data-json                          TEXT   Optional JSON object for trigger data.  │
│    --timeout                            FLOAT  HTTP request timeout in seconds.        │
│                                                [default: 10.0]                         │
│    --verify-tls      --no-verify-tls           Verify TLS certificates.                │
│                                                [default: verify-tls]                   │
│    --url                                TEXT   MindRoom base URL.                      │
│                                                [env var: MINDROOM_URL]                 │
│                                                [default: http://127.0.0.1:8765]        │
│    --key-id                             TEXT   Trigger signing key id.                 │
│                                                [default: default]                      │
│    --help        -h                            Show this message and exit.             │
╰────────────────────────────────────────────────────────────────────────────────────────╯


```

<!-- OUTPUT:END -->

## Examples

### Basic run

```bash
mindroom run
```

### Debug logging

```bash
mindroom run --log-level DEBUG
```

To debug MindRoom internals without enabling debug logs from every dependency, keep the global level at `INFO` and set targeted logger overrides:

```bash
LOG_LEVEL=INFO MINDROOM_LOGGER_LEVELS="mindroom:DEBUG,httpx:WARNING,httpcore:WARNING,anthropic:INFO,nio:WARNING" mindroom run
```

Matrix crypto decrypt warnings from `nio.crypto` are quieted by default because missing Megolm sessions can produce bursts of diagnostically useful but high-volume logs.
To inspect those warnings while debugging encryption state, explicitly restore that logger:

```bash
LOG_LEVEL=INFO MINDROOM_LOGGER_LEVELS="nio.crypto:WARNING" mindroom run
```

### Custom storage path

```bash
mindroom run --storage-path /data/mindroom
```

### Pair local install with hosted provisioning

```bash
mindroom connect --pair-code ABCD-EFGH
```

### Start local Synapse + Cinny (default local setup)

```bash
mindroom local-stack-setup --synapse-dir /path/to/mindroom-stack/local/matrix
```

### Start local stack without writing `.env`

```bash
mindroom local-stack-setup --no-persist-env
```

### Show version

```bash
mindroom version
```

### Preflight environment check

```bash
mindroom doctor
```

### Initialize a config

```bash
mindroom config init
```

### Validate your config

```bash
mindroom config validate
```
