Get the app, copy the setup prompt below, and paste it into your agent. It checks what you already have, shows you a plan, and asks before it changes anything. Works on Mac, Linux, VPS, and Raspberry Pi.
Install CARAPACE from the App Store and install Tailscale on your phone (same account as your machine).
2
Copy & paste the prompt
Copy the prompt below and paste it into your coding agent (OpenClaw, Claude Code, etc.) on the machine you want to control.
3
Approve & pair
Your agent shows a plan and asks before changing anything. Approve it, then scan the QR in the app to pair over Tailscale.
The setup prompt
Paste this whole thing into your agent. Nothing here contains secrets.
============================================================
CARAPACE + OPENCLAW SETUP — GUARDED, INVENTORY-FIRST, NON-DESTRUCTIVE
Paste this entire message to your coding agent. It is a set of instructions FOR YOU, the agent, running on the user's own machine (Mac, Linux, VPS, or Raspberry Pi). Follow the phases in order. Do NOT skip the safety preamble. The user is non-technical — explain blockers in plain language and never improvise around a missing prerequisite.
============================================================
#####################################################################
PHASE 0 — HARD SAFETY PREAMBLE (READ AND OBEY BEFORE ANYTHING ELSE)
#####################################################################
You are about to install/repair two layered components:
• OpenClaw — the agent gateway/runtime (CLI `openclaw`; gateway HTTP on 127.0.0.1:18789 with a /health endpoint; config file openclaw.json; workspace files AGENTS.md, MEMORY.md, IDENTITY.md, PROJECTS.md, HEARTBEAT.md, BOOTSTRAP.md). OpenClaw is installed FIRST and is the base layer.
• CARAPACE — a status-bridge server (status-server.js installed under ~/.carapace/) listening on 127.0.0.1:18794, exposing /agents /cron /sessions /projects /history /chat /diag /health and voice /tts/convert. It is published over Tailscale Serve so the user's iPhone app reaches it privately over the tailnet. The iPhone app pairs by scanning a QR (helper `carapace-qr`) on the SAME tailnet.
NON-NEGOTIABLE RULES for this entire task:
(a) INVENTORY BEFORE ANY MUTATION. Detect everything first (Phase 1). Touch nothing until you have a full picture.
(b) PRINT A PROPOSED PLAN. After inventory, print exactly what you intend to add or change, file by file, command by command (Phase 2).
(c) APPROVAL GATE. STOP and wait for the user to type explicit approval before ANY step that creates, edits, moves, restarts, or installs. No destructive or irreversible action without a clear "yes."
(d) ADDITIVE / OVERLAY OVER REPLACEMENT. Always prefer merging into existing config and sentinel-bounded inserts over rewriting files. This includes SHARED state such as Tailscale Serve routes and launchd/systemd service definitions — merge/add, never wholesale-replace.
(e) TIMESTAMPED BACKUP/SNAPSHOT BEFORE EDITING ANY EXISTING STATE. Format: <file>.bak.<YYYYMMDD-HHMMSS> (for MEMORY.md use <file>.carapace.bak.<YYYYMMDD-HHMMSS>). This rule applies to EVERY existing artifact you mutate, with NO exceptions, including: openclaw.json, AGENTS.md, MEMORY.md, status-server.js, ANY existing launchd plist or systemd unit file you are about to overwrite, AND the current Tailscale Serve config (snapshot `tailscale serve status` to a timestamped file before adding any route). Never overwrite or mutate state you have not first backed up/snapshotted.
FAIL-CLOSED. In ANY of these situations, STOP immediately, print a plain-language summary of the blocker, and ASK the user how to proceed — do NOT force, guess, or work around:
• missing sudo/permissions
• Tailscale not installed or not logged into a tailnet
• no AI provider auth configured (or only a single provider — warn)
• no usable package manager (Homebrew / apt / dnf)
• a port we need (18789 or 18794) is already occupied by something that is NOT our own OpenClaw/CARAPACE
• any existing config you cannot unambiguously interpret
• a Tailscale Serve route we intend to add would OVERWRITE an existing route owned by something other than our OpenClaw/CARAPACE setup (e.g. a stranger already owns `https=443 /` or a path we need) — STOP and ask; do not clobber it
NEVER, under any circumstance: reset OpenClaw, delete or wipe user data, erase auth/credentials, delete history/memory/projects, or blindly restart services. Service restarts are allowed ONLY as the explicit, approved setup steps in Phases 4–7, and ONLY after a backup AND with a wait-for-/health check afterward.
TRUSTED REFERENCE (do not run blindly): the official installer is `curl -fsSL https://carapace.info/install.sh`. You may consult its behavior as a reference. NOTE THESE SCOPE LIMITS so you do not over-trust it:
• The on-disk stock installer is macOS-only — it is the canonical reference ONLY for the Mac path. For Linux/VPS/Raspberry Pi you must DISCOVER service unit names and start methods from the live system (Phase 1), not assume them from the Mac installer.
• A few config tweaks in this prompt (gateway.requestTimeoutMs, gateway.trustedProxies CGNAT entries) are mandated by the CARAPACE spec but are NOT performed by the stock installer — treat them as spec-mandated additive deltas, not "what the installer does."
The PATH YOU FOLLOW is this guarded, inventory-first, approval-gated path — never an unattended curl|bash.
#####################################################################
PHASE 1 — INVENTORY (READ-ONLY; MUTATE NOTHING)
#####################################################################
Run only read-only probes. Collect and then report:
1.1 System
• OS and arch: `uname -a` (note `uname -m`: arm64/aarch64 vs x86_64); on Mac `sw_vers`; on Linux `cat /etc/os-release`.
• Detect platform class: macOS (Homebrew + launchd), Linux/VPS (apt or dnf + systemd), or Raspberry Pi (ARM + systemd). On Mac note `id -u` (used for launchd gui/<uid> domain).
• Package manager: which of `brew`, `apt-get`, `dnf` exists.
• Service manager: launchd (`launchctl` present on Mac) vs systemd (`systemctl --user` works) — if neither on Linux, note it (we will warn, not fail).
1.2 OpenClaw
• Is `openclaw` on PATH? `openclaw --version`.
• Gateway alive? `curl -sf http://127.0.0.1:18789/health` (a live gateway returns ok/status:live).
• Config present? Locate openclaw.json (commonly ~/.openclaw/openclaw.json). Do NOT print secrets; report only which keys exist: gateway.requestTimeoutMs, gateway.trustedProxies, agents.defaults.bootstrapMaxChars, agents.defaults.bootstrapTotalMaxChars, and the provider/auth section.
• Gateway TOKEN presence (PRESENCE ONLY — never print the value): check whether gateway.auth.token is set and non-empty, e.g. `jq -e '.gateway.auth.token != null and .gateway.auth.token != ""' ~/.openclaw/openclaw.json`. Report present/absent. (Phase 9 verifies this; capture it now so the plan can reason about it.)
• Gateway SERVICE LABEL/UNIT (discover, do not assume):
- Mac: `launchctl list | grep -i openclaw` to find the gateway label (commonly `ai.openclaw.gateway`). Record the actual label and its plist path; do not act on an assumed label.
- Linux/Pi: `systemctl --user list-units --all '*openclaw*'` (and `systemctl list-units --all '*openclaw*'` for a system unit) to discover the real gateway unit name. Do NOT assume `openclaw-gateway` — record whatever exists.
• Workspace: list ~/.openclaw/workspace/ — note presence of AGENTS.md, MEMORY.md, IDENTITY.md, PROJECTS.md, HEARTBEAT.md, BOOTSTRAP.md, and any agents/* subfolders.
• Providers/auth: report how many providers are configured and whether a cross-provider fallback exists (ChatGPT OAuth / Gemini key / custom). DO NOT print key values.
• Existing user data to protect: note that memory/history/projects exist (presence only).
1.3 CARAPACE
• Does ~/.carapace/ exist? Is status-server.js present? Note its size/mtime and any existing status-server.js.bak* backups.
• Is the bridge answering? `curl -sf http://127.0.0.1:18794/health` (the bridge serves /health and returns ok). If /health is ambiguous, cross-check `curl -sf http://127.0.0.1:18794/diag` as a secondary readiness probe.
• Is a service registered? Mac: `launchctl print gui/$(id -u)/com.carapace.status-server` (existence check; record the plist path). Linux: discover via `systemctl --user list-units --all '*carapace*'` — record the real unit name, do not assume one.
1.4 Tailscale
• Installed? `tailscale version`.
• Logged in / up? `tailscale status` (report the tailnet/login state; do not print the full peer list).
• Existing serve routes? `tailscale serve status`. RECORD the full current route map — you will need it both to detect collisions (Phase 7) and to know what to preserve. Note in particular whether `https=443 /` (root) and the per-path routes already exist and where they point.
1.5 Ports
• `lsof -nP -iTCP:18789 -sTCP:LISTEN` and `lsof -nP -iTCP:18794 -sTCP:LISTEN` (or `ss -ltnp` on Linux). For each port determine: free, owned by our own OpenClaw/CARAPACE (name the PID/command), or occupied by a stranger (FAIL-CLOSED case — name the PID/command and stop in Phase 2).
1.6 Helpers
• Are `carapace-qr`, `carapace-onboard`, `carapace-prune` on PATH?
>>> Now print a concise INVENTORY REPORT including the discovered gateway service label/unit, the token presence (present/absent, value never shown), the bridge health result, and the current Tailscale Serve route map. Then go to Phase 2. Do not mutate anything yet.
#####################################################################
PHASE 2 — PROPOSED PLAN + APPROVAL GATE
#####################################################################
Based on the inventory, print a PROPOSED PLAN that lists ONLY the steps actually needed (skip anything already satisfied — this whole procedure is idempotent and safe to re-run). For each step state: the exact file/command, why it is needed, the backup/snapshot that will be taken first, and (for service restarts and serve-route changes) the discovered label/route it will act on. Group the plan as: install/repair OpenClaw, config tweaks, workspace files, CARAPACE bridge, Tailscale routes (including the explicit list of routes to add and confirmation that none collide with a stranger's existing route), verification, QR pairing.
If the plan includes publishing the OpenClaw gateway root over Tailscale Serve (`https=443 /` -> 127.0.0.1:18789), CALL THIS OUT EXPLICITLY in the plan as a distinct, confirmable line item: state that this exposes the gateway to the tailnet on 443 in addition to the 18794 bridge, that it matches the real CARAPACE install layout, and ask the user to confirm they want it. Do not add it silently. If the user declines, set up only the 18794 bridge routes and the per-path 443 -> 18794 mappings the iPhone app needs.
If inventory triggered ANY fail-closed condition (Phase 0), surface it HERE as a blocker and stop for the user's decision instead of proposing to push through it.
>>> STOP. Ask: "Reply 'approve' to proceed with exactly this plan, or tell me what to change." Do nothing further until the user approves. If they approve only part, do only that part.
#####################################################################
PHASE 3 — PREREQUISITES (only the unmet ones, after approval)
#####################################################################
3.1 Package manager: if absent, STOP and ask (fail-closed). Do not auto-install Homebrew/apt/dnf without approval.
3.2 Node/runtime: install per platform only if OpenClaw needs it (Mac: Homebrew node; Linux: distro node, nvm only as last resort). If a global install needs sudo and you lack it, STOP and ask.
3.3 Tailscale: if not installed or not up, STOP and ask the user to install it and run `tailscale up`, and confirm the iPhone has Tailscale signed into the SAME tailnet with DNS enabled. Do NOT attempt to claim/auth a tailnet on the user's behalf. This is a hard dependency for phone<->machine; without it, pairing cannot work.
#####################################################################
PHASE 4 — OPENCLAW (base layer) — INSTALL OR LEAVE AS-IS
#####################################################################
4.1 If OpenClaw is already installed and /health (18789) is healthy: leave it. Do not reinstall.
4.2 If missing: install it (the official Mac reference does this for macOS), then start the gateway per platform:
• Mac (launchd, FIRST INSTALL ONLY): `openclaw gateway install`, then provision/start via the install ritual:
- If an existing gateway plist is present (rare on a fresh box), back it up first: copy <gateway plist> to <gateway plist>.bak.<timestamp>.
- `launchctl bootout gui/$(id -u)/<discovered-gateway-label>` (ignore errors) then `launchctl bootstrap gui/$(id -u) <gateway plist>`.
Use the gateway label DISCOVERED in Phase 1.2 (commonly ai.openclaw.gateway), not an assumed one. This bootout/bootstrap ritual is for INITIAL token provisioning/start only — for later config-tweak restarts use Phase 5's `openclaw gateway restart`.
• Linux/Pi (systemd): for a FIRST install use `systemctl --user enable --now <discovered-openclaw-unit>` (enable+start an unloaded unit); use `restart` ONLY for a unit that is already loaded. Use the unit name DISCOVERED in Phase 1.2. If systemd is ABSENT, WARN and continue: start the gateway by the documented manual method (run the gateway process per OpenClaw docs / the installer's manual-start path) and record how it was started; do not fail the whole run.
4.3 After any start/restart, WAIT for health: poll `curl -sf http://127.0.0.1:18789/health` for up to ~30s before continuing.
4.4 Providers: verify a chat provider is authed (ChatGPT OAuth / Gemini key / custom). If NONE, STOP and ask the user to authenticate one (Mac: the Carapace wizard's provider picker; Linux: `openclaw onboard`, or `carapace-onboard` to add one). If exactly ONE provider with no fallback, WARN clearly that there is no cross-provider failover — do NOT silently rewire providers.
#####################################################################
PHASE 5 — OPENCLAW CONFIG TWEAKS (ADDITIVE; BACK UP, USE CLI WHERE IT OWNS THE FILE, THEN GUARDED RESTART)
#####################################################################
These tweaks are spec-mandated (not all are done by the stock installer). Back up openclaw.json to openclaw.json.bak.<timestamp> BEFORE any change. Apply ONLY the following, and ONLY if the current value is lower/missing (merge, never replace). Prefer the OpenClaw CLI, which owns and schema-validates the file, over raw JSON surgery:
5.1 gateway.requestTimeoutMs → raise to at least 180000 (180s) if currently lower or unset. (Use `openclaw config set gateway.requestTimeoutMs 180000` if supported; otherwise edit the backed-up JSON minimally.)
5.2 Bootstrap caps via the CLI (this is how the installer does it):
`openclaw config set agents.defaults.bootstrapMaxChars 50000` (only if lower/unset)
`openclaw config set agents.defaults.bootstrapTotalMaxChars 200000` (only if lower/unset)
Do NOT hand-edit these in JSON if the CLI is available — let the tool that owns the file write them.
5.3 gateway.trustedProxies → MERGE-IN (do not replace existing entries) these Tailscale/loopback values:
"127.0.0.1", "::1", "100.64.0.0/10", "fd7a:115c:a1e0::/48"
Keep every entry already present; only add the missing ones. If a CLI merge primitive exists use it; otherwise edit the backed-up JSON additively (read array, union, write).
5.4 After writing, restart the gateway with the CANONICAL config-restart method and WAIT for /health:
• Mac: `openclaw gateway restart` (this is the canonical post-config restart — do NOT use the bootout/bootstrap ritual here; that is reserved for initial install in 4.2), then poll `curl -sf http://127.0.0.1:18789/health` up to ~30s.
• Linux/Pi: `systemctl --user restart <discovered-openclaw-unit>` (the unit is loaded at this point), then poll /health. If systemd absent, restart via the documented manual method recorded in 4.2.
If /health does not come back, STOP, restore openclaw.json from the .bak you took, surface the gateway logs path (e.g. ~/.openclaw/logs), and report — do not loop blindly.
#####################################################################
PHASE 6 — WORKSPACE FILES (SENTINEL-BOUNDED, NON-DESTRUCTIVE)
#####################################################################
All inserts use BEGIN/END sentinel blocks. If the sentinel block already exists, it is a NO-OP — never clobber real user content between or around the markers. If a file is so hand-edited that there is no clean place to insert a BEGIN/END region, STOP and ask rather than guessing.
6.1 AGENTS.md: upsert the CARAPACE vision-rules block bounded by
<!-- BEGIN CARAPACE VISION RULES ... --> ... <!-- END CARAPACE VISION RULES -->
Back up AGENTS.md first if it exists. Agent learnings below the END marker are preserved.
6.2 MEMORY.md: back up to MEMORY.md.carapace.bak.<timestamp> first. Upsert the CARAPACE project-rules sentinel block. Ensure the agent-maintained PROJECTS block bounded by
<!-- BEGIN CARAPACE PROJECTS --> ... <!-- END CARAPACE PROJECTS -->
exists (the iOS Projects tab reads/writes here). DO NOT auto-import old memory into it unless the user explicitly asks.
6.3 PROJECTS.md: write ONLY if missing. Ensure the project-scan sentinel exists. Do not overwrite an existing PROJECTS.md.
6.4 IDENTITY.md: if it exists and is non-default, leave it UNTOUCHED.
6.5 BOOTSTRAP.md: move to BOOTSTRAP.md.bak.<timestamp> ONLY if it carries our sentinel or a known openclaw-stock header. Otherwise leave it. Also retire any per-subagent BOOTSTRAP.md (rename to .bak.<timestamp>) since bootstrap is main-only — but only after backup.
6.6 HEARTBEAT.md: if it is a noisy legacy heartbeat, replace it (after backup) with a quiet comments-only heartbeat so OpenClaw skips heartbeat calls. If already empty/comments-only, no-op.
#####################################################################
PHASE 7 — CARAPACE STATUS BRIDGE (18794) + TAILSCALE ROUTES
#####################################################################
7.1 Install/refresh ~/.carapace/status-server.js (back up any existing status-server.js to a timestamped status-server.js.bak.<timestamp> first). PROVENANCE: obtain status-server.js and its node deps (better-sqlite3, etc.) from the official CARAPACE source the reference installer uses (carapace.info), not an arbitrary location; if you cannot confirm the source/integrity of the artifact, STOP and ask rather than installing an unverified file. Install its node deps as the reference does.
7.2 Register the service and start it, waiting for /health. BACK UP any existing plist/unit you are about to overwrite first (copy to <plist-or-unit>.bak.<timestamp>):
• Mac (launchd): if com.carapace.status-server plist already exists, back it up; then write/refresh it; `launchctl bootout gui/$(id -u)/com.carapace.status-server` (ignore error) -> `launchctl bootstrap gui/$(id -u) <plist>` -> `launchctl enable gui/$(id -u)/com.carapace.status-server`. Then poll `curl -sf http://127.0.0.1:18794/health` (up to ~30s; fall back to /diag if needed).
• Linux/Pi (systemd): back up any existing carapace unit; install/refresh it; for first install `systemctl --user enable --now <carapace-unit>`, for an already-loaded unit `systemctl --user restart <carapace-unit>`; poll /health the same way. If systemd absent, WARN and start it the documented manual way (per the reference installer's manual-start path) and record how; continue.
If port 18794 is occupied by a stranger (per Phase 1.5), STOP and ask — do not kill it.
7.3 Tailscale Serve routes (publishes the bridge to the iPhone over the tailnet).
FIRST — BACK UP SHARED SERVE STATE: snapshot the current config before any change:
`tailscale serve status > ~/.carapace/tailscale-serve.bak.<timestamp>.txt` (and, if available, `tailscale serve status --json > ~/.carapace/tailscale-serve.bak.<timestamp>.json`).
COLLISION CHECK (fail-closed): compare the routes you intend to add against the snapshot. If `https=443 /` (root) or any path you need is ALREADY owned by something that is NOT our OpenClaw/CARAPACE (i.e. it points somewhere other than 127.0.0.1:18789 or 127.0.0.1:18794), STOP and ask — do not overwrite a stranger's route.
Then add ONLY the missing routes (idempotent; re-adding an identical route is safe):
• Bridge listener: `tailscale serve --bg --https=18794 http://127.0.0.1:18794`
• Gateway root on 443 (CONFIRMED-INTENT ONLY): `tailscale serve --bg --https=443 http://127.0.0.1:18789`
This publishes the OpenClaw gateway root to the tailnet on 443. It matches the real CARAPACE install layout (the live reference setup maps 443 `/` to the gateway), but it exposes the gateway over the tailnet beyond the bare 18794 bridge. Add it ONLY if the user confirmed it in the Phase 2 plan; otherwise skip it.
• iOS API contract paths on https=443 mapping to the 18794 bridge — add each missing one with
`tailscale serve --bg --https=443 --set-path /<path> http://127.0.0.1:18794/<path>`
covering at minimum:
/health /identity /pair /status /agents /events /sse /sessions /chat /history /projects /cron /tracker /context /cognitive
and the voice paths: /tts/convert /voice/last-unheard /voice/deliver /voice/mark-delivered
Then confirm with `tailscale serve status` that the intended routes are active AND that no pre-existing route from the snapshot was removed or repointed. If Tailscale is down here, STOP (fail-closed) — pairing depends on it.
#####################################################################
PHASE 8 — OPTIONAL: HERMES (only if the user asks)
#####################################################################
Hermes is a SEPARATE, isolated runtime (its own history/projects/cron/auth) installed via install-hermes-agent.sh. It is NOT bundled and NOT part of the default setup. Do nothing here unless the user explicitly requests Hermes; if they do, run its installer and keep it isolated from the main runtime.
#####################################################################
PHASE 9 — END-TO-END VERIFICATION
#####################################################################
Verify and report each, plainly:
9.1 OpenClaw gateway: `curl -sf http://127.0.0.1:18789/health` → OK (live).
9.2 CARAPACE bridge: `curl -sf http://127.0.0.1:18794/health` → OK (if this fails, the iOS dashboard views will not load — flag it; you may cross-check /diag).
9.3 Tailscale: `tailscale status` up on the right tailnet; `tailscale serve status` shows the 18794 bridge listener and the 443 per-path routes. Verify the FULL per-path set the iPhone needs is present (at minimum /health /identity /pair /status /agents /events /sse /sessions /chat /history /projects /cron /tracker /context /cognitive plus /tts/convert /voice/last-unheard /voice/deliver /voice/mark-delivered). If the gateway-root-on-443 route was approved, confirm it too. List any missing path explicitly rather than reporting a generic pass.
9.4 Workspace files present: AGENTS.md, MEMORY.md, IDENTITY.md, PROJECTS.md, HEARTBEAT.md — with the expected sentinel blocks intact and no user data lost.
9.5 Gateway token present (PRESENCE ONLY; never print it) — confirm gateway.auth.token is set and non-empty, consistent with the Phase 1.2 probe.
9.6 Providers: confirm at least one is authed; restate the no-fallback WARNING if only one.
9.7 Warmup chat: send ONE short message through the agent (e.g. via the bridge /chat or `openclaw` CLI) and confirm a real (non-empty, non-error) reply — guard this so you do NOT run it when no provider is configured. If only a single provider exists, still run it but restate the no-fallback WARNING.
#####################################################################
PHASE 10 — IPHONE QR PAIRING
#####################################################################
10.1 Confirm the iPhone has the Tailscale app installed, signed into the SAME tailnet as this machine, with Tailscale DNS enabled. If not, STOP and ask the user to do that first.
10.2 Run `carapace-qr` to display the pairing QR.
10.3 Tell the user: open the CARAPACE iPhone app and scan the QR over the tailnet. Confirm the app reaches the bridge (agents/sessions/projects/chat load).
10.4 Final summary: report exactly what was added/changed, every backup/snapshot file created (with absolute paths — including openclaw.json.bak.*, MEMORY.md.carapace.bak.*, any plist/unit .bak.*, status-server.js.bak.*, and the tailscale-serve.bak.* snapshot), what was skipped because already satisfied, and any WARNINGS (e.g., single-provider, systemd absent, gateway-root-on-443 added or skipped). If anything is still blocked, state the single next action the user must take.
============================================================
REMINDERS: Idempotent and safe to re-run — skip satisfied steps. Additive over replacement (files, services, AND Tailscale Serve routes). Snapshot/backup before every edit, including shared serve state and service plists/units. Discover service labels/units from the live system; don't assume. Use the OpenClaw CLI for config/restarts where it owns the file. Never print secrets. Fail-closed on any blocker, including a serve-route collision with a stranger. Get approval before mutating.
============================================================
Scroll inside the box to read it all — the Copy button always copies the entire prompt.
Non-destructive by design
Inventory first
It detects your OS, OpenClaw, providers, Tailscale, and ports before touching anything.
Plan + approval gate
It prints exactly what it will do and waits for your “approve” before any change.
Backups + additive only
Timestamped backups before edits; it merges into config and never wholesale-replaces.
Fails closed
Missing Tailscale, provider auth, permissions, or a busy port → it stops and asks, never improvises.
Your data is preserved
Existing OpenClaw auth, memory, history, projects, and identity are never reset, deleted, or overwritten.
Advanced & fallback paths
Mac
Run the DMG wizard
Prefer a desktop installer? Download the DMG and follow the guided wizard.