Skip to main content
The Reflecto CLI (reflecto) is a paired device, like the Chrome extension or web app. It mirrors your phone’s notifications into your terminal in real time and lets you dismiss or reply to them. Everything is end-to-end encrypted — the server only routes opaque blobs and never sees plaintext.
The CLI is a receiver, not a sender. It is unrelated to the /v1/send API (see the Quickstart) and does not use rfk_live_… tokens — it pairs with your phone using a 6-digit code and derives its own encryption keys locally.

Install

brew tap reflectoapp/cli
brew install reflecto
Windows users can download reflecto-windows-x64.exe directly from the releases page. Verify the install:
reflecto --help

Pair with your phone

reflecto pair
This generates a 6-digit code and waits. On your phone, open Reflecto, tap Add a device, and enter the code. The code expires after 5 minutes — re-run reflecto pair if it does. Once confirmed, the CLI stores its credentials in ~/.config/reflecto/cli.json (created chmod 600). The two devices compute a shared secret via Diffie–Hellman locally; the server cannot derive it.
✓ Phone:        Pixel 8
✓ Encryption:   X25519 + XSalsa20-Poly1305
✓ Token saved:  ~/.config/reflecto/cli.json (chmod 600)   # your resolved path
You can only pair one phone at a time. Run reflecto unpair before pairing again — silently overwriting the config would orphan the old device on the server.

Stream notifications

reflecto tail
tail opens a live stream and renders each notification as a boxed card with its sender, full body, category glyph, and available actions:
┌─ 12:34  💬 WhatsApp  ───────────────────────── #a3f2c1d ─┐
│ Alice Smith                                              │
│ Hey, can you take a look at the design?                  │
│                                                          │
│ [1] ↩ Reply   [2] ✓ Mark read                            │
└──────────────────────────────────────────────────────────┘
Press 19 to invoke the corresponding numbered action on the most recent card with actions; a reply action opens an inline prompt. d dismisses that card without leaving the stream, r prints a one-time hint (in card view) pointing you at the numbered keys, and q (or Ctrl-C) quits. Conversation-style notifications (WhatsApp, Telegram, Messages) cluster: follow-up messages within 60s of the same thread render as ╰─ continuations rather than fresh cards.

tail options

FlagDescription
--app <names>Comma-separated apps to allow (case-insensitive).
--exclude <names>Comma-separated apps to block.
--grep <pattern>Substring, or /regex/, matched on title + body.
--since <duration>Replay backlog first, e.g. 30m, 1h, 2d.
--jsonEmit newline-delimited JSON instead of cards.
--auto-dismissAuto-dismiss each notification on your phone after rendering.
--notifyAlso fire a native desktop notification.
--onelineForce the single-line format.
--no-onelineForce card view even when piped (overrides the non-TTY auto-switch).
tail auto-switches to the single-line format when stdout is not a TTY, so piping to grep, jq, or a file stays readable. Pass --no-oneline to keep card view even when piped.
# Only WhatsApp and Telegram, replaying the last hour
reflecto tail --app whatsapp,telegram --since 1h

# Everything except Slack, as JSON, piped to jq
reflecto tail --exclude slack --json | jq .

Dismiss and reply

# Dismiss a notification by its message id (UUID)
reflecto dismiss <id>

# Reply (apps that expose a RemoteInput action: WhatsApp, SMS, Telegram…)
reflecto reply <id> "On my way"
Both take the full message id (a UUID). The #a3f2c1d tag in a card header is only the last 7 characters, shown to disambiguate scrolled-past cards — it is not a valid argument. Get the full id from the id field of reflecto tail --json:
reflecto tail --json | jq -r .id   # full UUIDs, one per line
Replies are encrypted to your phone, which executes the action on your behalf. A reply only lands if the original notification exposed a reply slot — reflecto reply always prints a note on stderr reminding you of that requirement, and a reply to a button-only notification has no effect on the phone.

Status and unpair

reflecto status   # phone, pairing date, server, connection, backlog, token path, crypto, version
reflecto unpair   # release this device on the server and clear local credentials
unpair removes only this CLI; any sibling devices (extension, web) paired with the same phone stay connected.

Configuration

The CLI always connects to the production server — there is no server override. Behavior is controlled entirely through these environment variables:
VariableEffect
REFLECTO_CONFIGOverride the config-file path (default ~/.config/reflecto/cli.json).
XDG_CONFIG_HOMEBase directory for the default config path.
REFLECTO_ASCII=1Force ASCII tags ([msg], [mail], …) instead of glyphs.
NO_COLORDisable color output (the NO_COLOR convention; the --no-color flag just sets it).
Glyphs also fall back to ASCII automatically when stdout is not a TTY (e.g. piped to jq or a file) or when the locale isn’t UTF-8.