3.8 KiB
claude-rc
Run Claude Code Remote Control (claude rc) servers so projects are
drivable from claude.ai/code and the Claude mobile app
— either as always-on, reboot-surviving services, or as ad-hoc throwaways.
Two tools:
| Tool | Purpose | Persistence |
|---|---|---|
claude-rc |
central manager of always-on servers, supervised by systemd --user from a registry |
survives reboot (linger) + crash (Restart=always) |
crc |
ad-hoc headless launcher for one dir on one host | survives terminal drops; dies on reboot |
Both run claude rc headless — detached, logged, with --spawn and
--permission-mode preset so it never blocks on the interactive spawn-mode
prompt.
Why no tmux
The obvious approach — park claude rc in a tmux session — is a trap: a shared
user tmux server can be restarted out from under you (e.g. by another
supervisor) and your sessions vanish. claude rc needs no TTY (it connects fine
with stdin closed), so systemd alone gives boot-persistence + crash-restart,
and crc uses a plain logged background process. No tmux anywhere.
Install
./install.sh # symlink bin/*, install the unit, seed registry
sudo loginctl enable-linger "$USER" # once, so units start at boot (Linux)
claude-rc sync # bring up everything in the registry
Requires claude (Claude Code) on $PATH and a logged-in subscription account.
Manager — claude-rc
Registry (~/.config/claude-rc/projects) is the single source of truth:
name=dir # dir relative to $HOME, or absolute, or ~/...
Each entry → a systemd template instance claude-rc@<name>.service running
claude rc --name <name> in <dir>.
claude-rc list # registry + unit state + dir
claude-rc status [name] # state + claude.ai/code URL
claude-rc url <name> # just the URL
claude-rc add <name> <dir> # register + enable --now
claude-rc rm <name> # disable + unregister
claude-rc sync # reconcile units to the registry
claude-rc logs <name> [-f] # journal
claude-rc restart|stop|start <name>
claude-rc envs # account-wide environment list (all hosts)
Account-wide view — claude-rc-envs
claude-rc list/status only know about this host's units. To see every
Remote Control environment across all hosts (exactly what the claude.ai/code
picker shows — including orphans and cloud envs), query the API:
crc status # or: crc envs / claude-rc envs / rc envs
claude-rc-envs # state, host, project, env id, dir
claude-rc-envs --json
claude-rc-envs rm <env_id> # delete an environment (e.g. an orphan)
claude-rc-envs archive <env_id>
Reads the OAuth token from the macOS Keychain or ~/.claude/.credentials.json
and hits GET https://api.anthropic.com/v1/environments
(anthropic-beta: environments-2025-11-01).
Defaults (override via env in a unit drop-in):
CLAUDE_RC_SPAWN=worktree— isolated git worktree per spawned session.CLAUDE_RC_PERM=bypassPermissions— spawned sessions skip permission prompts.
Ad-hoc — crc
crc <host> <dir> # launch headless; prints the URL. host=local for here
crc <host> <dir> --status | --log | --stop
crc <host> <dir> --spawn same-dir --perm default -- <extra claude rc args>
host is any ssh target, or local. State lives under
~/.local/state/claude-rc/ on the target. Re-running reports the existing
server instead of duplicating it.
Layout
bin/claude-rc manager (runs on the host; drive remotely over ssh)
bin/crc ad-hoc headless launcher
units/claude-rc@.service systemd --user template
projects.example registry seed
install.sh symlinks + unit install + registry seed