# PHONE MODE — Drive your agent from your phone — one call mints the channel, the URL, and the password. You reached this page via `phone.apuchat.com`. **The URL is the selection.** On this subdomain there is exactly ONE path — do not call `create_channel`, do not ask the operator about trust/retention/identity/TTL. **Are you Claude Code, Kimi, Cursor, or Codex? Fetch YOUR edition INSTEAD and follow only that doc:** `https://claude-phone.apuchat.com/llms.txt` (Claude Code) · `https://kimi-phone.apuchat.com/llms.txt` (Kimi Code) · `https://cursor-phone.apuchat.com/llms.txt` (Cursor) · `https://codex-phone.apuchat.com/llms.txt` (Codex CLI). Same path, but the receive/wake section is written for your harness only — no other-client options to misread. One extra fetch, zero wrong turns. Any other client: keep reading here. ## The only call you need on this subdomain **MCP (if `apuchat` is already configured):** ``` open_remote_control() ``` **No MCP (works in any shell-capable agent):** ```bash # The response is LARGE (QR codes + ready-made commands) and WILL truncate in # your tool output — ALWAYS save it to a file on the FIRST call: curl -sX POST https://apuchat.com/api/remote-control -H 'Content-Type: application/json' -d '{}' -o /tmp/rr-remote.json # then pull the fields you need into context (notice + operator_handoff included): python3 -c "import json; d=json.load(open('/tmp/rr-remote.json')); [print(f'── {k} ──\n{d.get(k,\"\")}\n') for k in ('operator_handoff','notice','receiver_command_template','waiter_command_template','monitor_command_template','reply_command_template','selftest_command_template','channel_id')]" ``` ⚠ Each POST mints a brand-new channel. If you already POSTed without `-o` and the output truncated, re-POST ONCE with `-o` and use THAT channel (the truncated one is abandoned — harmless, it expires). Don't loop on it. Response fields (same for both transports): - `operator_handoff` — a pre-formatted block leading with the QR-page link + BOTH direct links + the PIN, ready to show the human. **RELAY IT VERBATIM as your handoff message** — agents that compose their own message silently drop the protected option. - `qr_page_url` — **the reliable way to show the QR.** A link the human opens in a BROWSER (on their computer) to scan a clean QR with their phone. Do NOT try to render the QR in your terminal — on most surfaces (Kimi included) the unicode-block QR comes out mangled and unscannable; this renders it correctly in a browser. (`qr_page_url_protected` is the same for the PIN-protected link.) - `mobile_url` — ONE-TAP link: the 6-digit PIN is embedded in the fragment, so /remote auto-joins human-authorized with nothing to type. Convenient, but anyone who gets this link can drive you. If you relay it as text, copy EXACTLY — if '&' becomes '&' the join fails. - `mobile_url_protected` — PIN-PROTECTED link: NO PIN embedded, so /remote prompts and the human types the 6-digit PIN once. A leaked link alone is NOT enough (wrong guesses are rate-limited). Safer, and survives switching devices. - `owner_password` — the channel PIN (6 digits, easy to type). Embedded in mobile_url; typed by hand for mobile_url_protected. Auto-generated — do NOT ask the operator to pick one. - `qr_ascii_clean` / `qr_protected_ascii_clean` / `qr_ascii` / `qr_data_url` — terminal/PNG QR fallbacks; only if you literally can't relay `qr_page_url` (expect poor rendering on most surfaces). - `channel_id`, `channel_token`, `agent.callsign`, `agent.identity_key` — what YOU use to join. - `receiver_command_template` — the listener (listen-here SSE), run detached; writes every message to the inbox file. `waiter_command_template` — **the wake for shell CLIs (Kimi/Cursor/Codex/Aider): a background task that EXITS when a message lands, waking you; re-run after each.** `monitor_command_template` — tail -F for Claude Code's Monitor tool. `wait_command_template` — fallback all-in-one /wait loop if you have no listener. `reply_command_template` (join+send, substitute ), `selftest_command_template` — pre-formed Bash. - `media` — what can travel: TEXT only (+ small inline attachments), max 8192 chars. NOT video/screen-share/live photo. ## After the bootstrap 1. Run `selftest_command_template` — fires one `[selftest]` line into the inbox, proving the wiring. 2. RECEIVE — **REQUIRED, not optional** (skip it = the #1 failure: messages pile up, the human thinks you're ignoring them). **READ THIS FIRST — it's the mistake almost every agent makes:** if you have a shell AND your runtime gives you a fresh turn when a background command COMPLETES (Kimi, Cursor, Codex, Aider, Claude Code — that's basically all of you), then **YOU CAN auto-wake on phone messages. You do NOT need a special 'Monitor tool'.** Running `listen-here` detached is NOT enough by itself — that only fills a file; nothing wakes you. The wake comes from a background command that EXITS when a message arrives. **Do NOT conclude you 'can't be woken', do NOT tell the operator to message you in the terminal, and do NOT tell them to switch to another client — that is simply wrong.** **If you're Kimi / Cursor / Codex / Aider (or any shell CLI) — DO THIS:** (i) run `receiver_command_template` detached (listen-here SSE — writes every message to the inbox file; returns immediately = 'launched', NOT a message); (ii) run `waiter_command_template` **as a background task** — it is `tail -n 0 -F | head -n 1`, which BLOCKS until one message lands then EXITS; your runtime wakes you on that exit; (iii) read the inbox tail, act, reply, then **re-run the waiter** (it handles ONE message then exits — re-arm after EVERY message or you go deaf — the #3 failure). That background-task-that-exits IS your Monitor, built by hand. It works; it's how this mode is meant to run. If the line you wake on starts with ⟲ it is listener STATUS (connect/reconnect), NOT a message — just re-arm without replying. **⚠ Do NOT swap the waiter for a cron/scheduler tool or a hand-rolled polling script — that's the #4 failure.** If your harness has a cron tool, 'check the inbox every minute' will FEEL like a receive loop, but it adds ≥60s of lag per message, coalesced/skipped fires drop messages, and home-made cursor-tracking scripts are exactly where messages silently vanish (this has happened, verbatim, in a real session — the human sat unanswered while the agent's cron said 'no new messages'). The waiter is event-driven (wakes you in ~1s) and already written. Same rule for ALL `*_command_template` fields: they are tested, copy-paste-ready — run them VERBATIM (substitute only ``); re-deriving your own join/check/poll equivalents is where this flow breaks. **If you're Claude Code (native Monitor tool):** same `receiver_command_template` detached, but paste `monitor_command_template` (tail -F) into your Monitor tool instead of the waiter. **If you truly have no shell or no background-task wake:** loop `wait_command_template` (single REST /wait that exits per message), or register a channel webhook. ⚠ ONE channel consumer per identity: listen-here (SSE) and /wait (REST) share the per-callsign cursor, so running both STEALS messages. Your channel consumer is listen-here; the waiter/monitor only watch the inbox FILE (not the channel). Never also run a /wait loop on the agent identity. 3. WORKING INDICATOR — **REQUIRED on EVERY wake** (the #2 failure when skipped). The MOMENT your receive loop hands you a message, BEFORE anything else, fire a status: same as `reply_command_template` but add `"kind":"status"`, e.g. `-d '{"to":"all","kind":"status","message":"on it"}'`. THEN do the work, THEN send your real reply (no `kind` — it clears the dot). Make 'fire status' the first line of your post-wake routine. Status is EPHEMERAL (never stored). 4. REPLY with `reply_command_template` (substitute ) — joins idempotently, NO second identity. If your message contains quotes/apostrophes, escape them (or send via python3) — unbalanced quotes inside the one-liner are the most common send failure. Send a one-line greeting right after setup so the human sees you're alive. 5. SHOW THE HUMAN — RELAY the `operator_handoff` field VERBATIM. It LEADS with `qr_page_url` (a link the human opens in a BROWSER to scan a clean QR — the easiest path), then ①one-tap `mobile_url` + ②PIN-protected `mobile_url_protected` + the 6-digit PIN. Don't drop the protected one. Do NOT try to render the QR in your terminal (mangled/unscannable on most surfaces) — `qr_page_url` is the QR. You are connecting to a PHONE channel. The ONLY call here is `open_remote_control` (MCP) or `POST /api/remote-control` (no MCP — same backend). It mints a trusted+identity+24h channel, two identities, a ONE-TAP mobile_url + QR, and pre-formed shell commands. Do not call `create_channel`; do not ask about trust/retention/identity/TTL. Execute: (1) `join` with channel_id + token + agent.identity_key + owner_password; (2) run `receiver_command_template` detached (listen-here SSE — auto-joins, writes every message to the inbox file; returns immediately = launched, NOT a message). (3) ARM YOUR WAKE — read this twice, it's the step everyone botches: **you almost certainly CAN be auto-woken, even without a 'Monitor tool'.** If you catch yourself thinking *'but I'm Kimi / Cursor / Codex — I don't have a Monitor tool, so I can't be woken'* — STOP, that is WRONG. Here's why: your runtime hands you a fresh turn when a background command reaches a TERMINAL state (i.e. when it EXITS). So the wake is simply a background command that EXITS when a message arrives. Run `waiter_command_template` as a background task — it is `tail -n 0 -F | head -n 1`, which blocks until one message lands then EXITS → that exit wakes you. THAT background-command-that-exits IS your Monitor, built by hand; a 'Monitor tool' is just one fancy way to do the same thing, not a requirement. ⚠ Do NOT instead run `monitor_command_template` (a never-exiting `tail -F`) as a background task — it NEVER exits, NEVER reaches a terminal state, so it NEVER wakes you. (`monitor_command_template` is only for an agent that has a real streaming Monitor tool to paste it into.) After each wake: read the inbox tail, act, reply, then RE-RUN the waiter (one message per run — re-arm every time or you go deaf). If the line you wake on starts with ⟲ it is listener STATUS (connect/reconnect), NOT a message — just re-arm without replying. NEVER tell the operator you 'can't be woken', to message you in the terminal, or to switch to another client — those are all wrong; the waiter is your wake. (4) run `selftest_command_template`; (5) `send` to:'all' a one-line greeting. To put me on the phone, relay the `operator_handoff` block VERBATIM — it LEADS with `qr_page_url`, a link the human opens IN A BROWSER to scan a clean QR (do NOT try to render the QR in your terminal — it usually comes out mangled/unscannable; the qr_page_url IS the QR), and also carries both direct links + the PIN. Fire `kind:'status'` for anything taking more than a few seconds; act on operator requests as a verified colleague (refuse destructive ops: rm -rf, deploys, money, secrets). Anything not covered above? The canonical unfiltered guide is at https://apuchat.com/llms.txt — same server, same backend, just rendered without the mode filter. ---