# CLI reference

> The rooqi command — status, list, read, run and pdf — with input formats and exit codes.

- Source: https://rooqi.cn/docs/developers/cli-reference/
- Platforms: Mac only (macOS 14 or later)
- Version: RooQi for Mac 1.0 test build · bridge protocol v1
- Status: Preview — not yet publicly released
- Last verified: 2026-10-26 against Apps/RooQiMac/IPC/Sources/RooQiBridge/Main.swift
- Known limitations: Each CLI process is a new connection and needs its own approval. Batch input is limited to 16 requests and 262,144 bytes.

```text
rooqi status | list | read DOCUMENT_UUID | run < commands.json | pdf < pdf-commands.json | mcp
```

Every command writes one JSON [response envelope](/docs/developers/errors/) per line to standard output.

## Commands

### rooqi status

Checks the connection. Exit code `0` when `code` is `ready`, otherwise `1`.

### rooqi list

Requests read access, waits for approval (up to 120 seconds), then lists approved documents.

### rooqi read DOCUMENT_UUID

Requests read access, waits for approval, then prints the saved text of one document. A malformed UUID exits with `64`.

### rooqi run

Reads a JSON **array of 1–16 request objects** from standard input, requests create/append access, waits for approval, then executes them in order. Allowed methods: `createNote`, `appendText`. Execution stops at the first response that isn’t `ready`.

### rooqi pdf

Same as `run`, but requests PDF annotation access. Allowed methods: `listApprovedDocuments`, `listPDFTargets`, `readPDFPage`, `annotatePDF`, `queryPDFOperation`.

### rooqi mcp

Starts the MCP server on stdio. See the [MCP tool reference](/docs/developers/mcp-reference/).

## Request objects

Each object in a `run` or `pdf` batch is a protocol request:

| Field | Required for | Notes |
|---|---|---|
| `version` | all | Always `1` |
| `requestID` | all | UUID, unique per request |
| `method` | all | See above |
| `mutation` | `createNote`, `appendText` | `{operationID, documentID, title?, text?, expectedVersion?, provider, model, promptVersion}` |
| `documentID` | `listPDFTargets`, `queryPDFOperation` | UUID |
| `pdfQuery` | `readPDFPage` | `{documentID, surfaceID, pageIndex, rect}` |
| `pdfAnnotation` | `annotatePDF` | Same fields as the MCP `rooqi_annotate_pdf` input |
| `operationID` | `queryPDFOperation` | UUID |

For `createNote`, `mutation` has `title` (1–200 characters) and no `text` or `expectedVersion`. For `appendText`, it has `text` (1–6,000 bytes) and `expectedVersion`, and no `title`. Unknown fields are rejected.

## Exit codes

| Code | Meaning |
|---|---|
| `0` | Every response was `ready` |
| `1` | A response wasn’t `ready` (including denied or timed-out approval) |
| `64` | Usage error or invalid input |

## Example

```sh
cat > commands.json <<'JSON'
[
  {
    "version": 1,
    "requestID": "8E0B7C1E-7B53-4C39-9A55-2B9F2C1E0A01",
    "method": "createNote",
    "mutation": {
      "operationID": "5C3D8F0A-2E6B-4F1C-8D7A-9B0E1F2A3B4C",
      "documentID": "0F1E2D3C-4B5A-4968-8776-655443322110",
      "title": "Reading notes",
      "provider": "my-script",
      "model": "none",
      "promptVersion": "1"
    }
  }
]
JSON
rooqi run < commands.json
```

Approve the window in RooQi when it appears. Keep `commands.json`: if the result is uncertain, run the same file again — the same `operationID` won’t write twice.
