Feature Request: claude remote-control --headless — daemonizable remote control without TTY dependency
Summary
Remote control and headless mode are two powerful capabilities that solve complementary problems. Combining them would unlock a new class of deployment: always-on, remotely-accessible Claude Code instances on headless servers — no terminal multiplexer required.
The Architectural Insight
Today, three pieces exist independently:
| Capability | What it proves |
|---|---|
| Headless mode (claude -p) | The execution engine runs without a TTY |
| Remote control (claude remote-control) | The UI can live entirely on another device (phone, browser) |
| Remote control networking | Outbound-only HTTPS polling — no inbound ports, no local UI interaction needed |
When using remote control, the local terminal is rendering a mirror of what the remote client (claude.ai/code, iOS/Android app) already displays. The local TUI is redundant — the user is on their phone or browser, not looking at the server terminal.
Proposal
A --headless flag (or --daemon) for remote control:
claude remote-control --headless
Behavior:
- Starts the execution engine + HTTPS polling loop as a plain process (no PTY required)
- Prints the session URL/token to stdout, then runs as a background-friendly process
- No local terminal rendering — all UI interaction happens on the remote client
- Compatible with
nohup,systemd,supervisord, Docker, or any process manager
Permission Handling — Remote Client as the Permission UI
In current remote control, permission prompts are already forwarded to the remote client (iOS app, claude.ai/code). In headless mode, this becomes the primary permission interface — the remote client isn't just mirroring a terminal, it's the only UI.
| Scenario | Approach |
|---|---|
| Interactive remote (typical) | Permission prompts appear on iOS / claude.ai/code. User approves from phone/browser. |
| Unattended / sandboxed | --dangerously-skip-permissions or --permission-mode for environments where no human is watching. |
| Semi-trusted | --allowedTools to pre-approve specific tools, prompt for everything else via remote client. |
This means the iOS app and claude.ai/code effectively become the permission controller for a headless instance — no local terminal needed for any part of the workflow.
Flag Compatibility
Existing CLI flags should compose naturally with headless remote control:
| Flag | Why it matters for headless RC |
|---|---|
| -r / --resume | Essential. Reconnect to an existing session after a process restart, server reboot, or crash. Without this, a daemon that restarts generates a new session URL every time. |
| --dangerously-skip-permissions | Unattended operation for sandboxed/trusted environments where the remote client may not be connected when a permission is needed. |
| --permission-mode | Finer-grained alternative — e.g., --permission-mode acceptEdits for semi-trusted setups. |
| --allowedTools | Scope what the headless instance can do (e.g., only Bash(git:*), Read, Edit), with remaining prompts forwarded to the remote client. |
Use Cases
Always-on dev server (systemd):
[Service]
ExecStart=/usr/local/bin/claude remote-control --headless
Restart=on-failure
Resilient daemon with resume:
# First launch: prints session URL
claude remote-control --headless \
--session-id 550e8400-e29b-41d4-a716-446655440000 \
> ~/rc-session.txt 2>&1
# After restart: reconnect to same session
claude remote-control --headless \
--resume 550e8400-e29b-41d4-a716-446655440000
Quick background process:
nohup claude remote-control --headless > ~/rc-session.txt 2>&1 &
cat ~/rc-session.txt # grab session URL, open on phone
Docker / cloud dev environments:
CMD ["claude", "remote-control", "--headless", "--permission-mode", "acceptEdits"]
SSH fire-and-forget:
ssh devbox 'nohup claude remote-control --headless > /tmp/session.txt 2>&1 &'
ssh devbox 'cat /tmp/session.txt' # get URL, open on phone
Why This Is Not a TTY Bug
This is not about fixing stty ioctl errors when a TTY is absent (see #15428). This is a feature request for a new mode of operation where the local terminal rendering is intentionally removed because the remote client is the only UI. The execution engine and networking already work without a terminal — they just need to be offered as a first-class headless option.
Impact
Remote control is currently limited to machines where you can maintain an interactive terminal session (directly or via tmux/screen). This is ironic — remote control is designed to free you from being at your machine, but it still requires your machine to have an active terminal. A headless mode, combined with --resume for crash recovery and the remote client as the permission UI, would make remote control a true always-on development service.
Showing cached comments. Read the full discussion on GitHub ↗
4 Comments
I'm all for this
But I'm also wondering if this isn't against their TOS.
Otherwise did you tried remote-control server-mode
https://code.claude.com/docs/en/remote-control#server-mode
Use case: always-on coding daemon on a dedicated machine (Mac Studio)
I run Claude Code on a dedicated Mac Studio at my office and access it remotely while traveling internationally. The machine is always on and always connected. I want Claude to keep working on long-running tasks while I'm in transit, on a plane, or simply away from my laptop.
The current setup requires tmux to provide a TTY, which works but has two problems:
A
--headlessflag forclaude remote-controlwould let me run it as a proper launchd service on macOS — boot-persistent, auto-restarting on crash, no TTY dependency. I spent several hours trying to make launchd + tmux work reliably and hit the TTY wall every time.The interaction model already supports headless perfectly: when using remote control, I'm on my phone or browser — not looking at the local terminal. The local TUI is rendering for nobody. The execution engine and the remote control networking clearly work without a terminal; the TTY requirement is the only blocker.
This is a real production workflow: dedicated always-on machine + remote supervision via mobile app.
--headlesswould make it work properly.requires a TTY, the whole point of this request is to avoid that and make it truly headless.
The headless request makes sense, but I would keep one distinction explicit: removing the local TTY is different from preserving a durable session authority. The remote client should not become the authority by accident; it should attach to one host-side runtime that owns cwd, permissions, tool state, and receipts.
I have been testing the opposite conservative tradeoff in Faryo: keep the host CLI inside tmux as the live-process authority, then let phone/browser do compact output, short input, interrupt, and handoff into that same process. Redacted walkthrough: https://github.com/Snailflyer/faryo/releases/download/v1.0.7/faryo-public-redacted-same-session-handoff-walkthrough-20260528-0120.gif
For
remote-control --headless, the acceptance test I would want is not just "the daemon stays up". It is: