Claude Code Remote Control on a VPS: run Claude Code 24/7 and drive it from your phone
When your laptop sleeps, your Claude Code sessions stop. Run them on a VPS, drive them from your phone and keep attackers out of the server.
- Remote Control connects the Claude app on your phone to a Claude Code session. On a VPS, a rented server that never switches off, the session keeps working while your laptop sleeps.
- Remote Control opens no port, so only SSH and your Docker containers are left to lock down.
- You need a Pro, Max, Team or Enterprise plan. An API key is not enough.
You start a long task in Claude Code, close the laptop, and everything stops. This is my daily setup with Claude Code Remote Control: one VPS, about ten background sessions, and the Claude app in my pocket. Plan for an hour.
- A Claude Pro, Max, Team or Enterprise plan.
- A VPS running Ubuntu 20.04+ or Debian 10+, with at least 4 GB of memory. Mine: 8 cores, 23 GB, €33 a month at Contabo.
- The Claude app on your phone.
- You can paste a command into a terminal. Every command is explained.
Why run Claude Code on a VPS?
A Claude Code session lives on the machine that starts it. On a laptop, it stops when the laptop shuts down. On a VPS, a computer you rent in a data centre that stays on all the time, it works overnight, and you pick it up on your phone in the morning.
With no server at all, cloud sessions on claude.ai/code (opens in a new tab) run at Anthropic. A VPS keeps your own tools and files for a fixed price.
| Where the session runs | When it stops | |
|---|---|---|
| Your computer + Remote Control | On your computer | When it shuts down |
| A VPS + Remote Control | On your rented server | When the server reboots |
| Cloud sessions on claude.ai/code | At Anthropic | When the task ends |
What is Claude Code Remote Control?
Claude Code Remote Control connects claude.ai/code or the Claude app for iOS and Android to a session running on your machine. The work stays on that machine, with your files and tools. Your phone becomes a window and a keyboard, kept in sync with the terminal.
The session only makes outbound requests to Anthropic and opens no port, the numbered doors through which a server accepts connections. While it is connected, the conversation is stored at Anthropic to stay in sync. With /config, it can also notify you when a task finishes or needs your decision.
How do you install Claude Code on a VPS?
Connect to the VPS over SSH, the secure way to reach a server from your terminal. Run Anthropic's install command, then type claude. The server has no browser, so Claude Code shows a link to open on your computer, and you paste the code you get back into the terminal.
Connect to the server
If SSH runs on another port, add -p and the number.
ssh you@your-vps-addressExpected result: the server's prompt, for example you@vps:~$
Install Claude Code
curl -fsSL https://claude.ai/install.sh | bash claude --versionExpected result: a version number, for example 2.1.309 (Claude Code)
Sign in
Run claude, press c to copy the link, open it on your computer, then paste the code where the terminal says "Paste code here if prompted".
claudeExpected result: Login successful
Check: /status shows your account and plan.
Do not use `claude setup-token`: the documentation says that token cannot start Remote Control sessions.
How do you drive Claude Code from your phone?
On the VPS, go to the project folder and run claude remote-control. Answer yes to the two confirmations, then press the space bar to show a QR code. Scan it with your phone and the session opens in the Claude app. It also shows up in the session list on claude.ai/code.
Start the Remote Control server
cd ~/my-project claude remote-controlExpected result: "Trust <folder>? [y/N]", then "Enable Remote Control? (y/n)" the first time. Answer y.
Open the session on your phone
Press the space bar and scan the QR code.
Check: type "list the files in this folder" on your phone; the VPS terminal shows the same conversation.
This mode accepts 32 sessions at once by default, all in the same folder. For one git working copy per session, add --spawn worktree.
How do you keep Claude Code running 24/7?
A Remote Control session lives as long as its claude process runs: close the SSH connection that started it and it stops. So start it inside tmux, which keeps a terminal open after you leave. For other tasks, claude --bg starts a background session that survives logging out.
Open a tmux session and start Remote Control
tmux new -s claude claude remote-controlExpected result: the session link and QR code.
Detach
Press Ctrl+B, then D. You can close SSH.
Check: the session still answers from your phone.
Come back later
tmux attach -t claude
For tasks I start on the server myself, I use claude --bg. A supervisor runs them with no terminal open: as I write this, it has been up for 24 hours with 10 sessions.
Start a task in the background
claude --bg "fix the failing test in the billing folder"Expected result: a short id.
Follow your sessions
claude agentsExpected result: sessions running, waiting for your answer, or finished.
Three limits:
- A server reboot stops tmux and background sessions. Start them again.
- After about 10 minutes without network, claude remote-control exits.
- A session stops when your login expires. When you see "Your login expires in 3 days", run /login.
How do you lock your VPS down?
Remote Control needs no open port, so close the rest. Sign in with an SSH key, never a password. Keep SSH on a private network such as Tailscale. And check Docker: a container published on every address goes straight past the ufw firewall.
I learned this the hard way. In September 2026, on this VPS, RabbitMQ (a message queue) and KeyDB (an in-memory database, with no password) ran in Docker. ufw blocked everything by default, yet both answered from the internet. Someone created two administrator accounts in RabbitMQ, "miner" and "exploit". There was no mining program on the server, but the door had been open for two weeks.
The cause: Docker adds its own network rules, and they run before ufw's. The fix: publish each port on 127.0.0.1, the address only the machine itself can reach.
services:
keydb:
ports: !override
- "127.0.0.1:6379:6379"
rabbitmq:
ports: !override
- "127.0.0.1:5672:5672"
- "127.0.0.1:15672:15672"Without a terminal, start with your host's firewall in its control panel: block all incoming traffic except SSH. It filters before your server, so Docker cannot get around it.
Turn off password login
In /etc/ssh/sshd_config, set PasswordAuthentication no and PermitRootLogin no. Keep your session open and test from a second terminal.
sudo systemctl restart sshCheck: ssh -o PubkeyAuthentication=no you@your-vps-address is refused.
Install Tailscale
Tailscale builds a private network between your devices. Install it on the VPS and on your computer.
curl -fsSL https://tailscale.com/install.sh | sh sudo tailscale upExpected result: the VPS shows up in your Tailscale devices.
Keep SSH on Tailscale
Allow SSH on tailscale0 (replace 22 with your port), then delete the rule that opened it to the internet.
sudo ufw allow in on tailscale0 to any port 22 proto tcpCheck: ssh works through Tailscale and fails from any other network.
Republish containers on 127.0.0.1
Add the file above, then recreate the containers.
docker compose up -d --force-recreate ss -tlnCheck: your ports show behind 127.0.0.1, not 0.0.0.0.
Test from outside
From a machine off Tailscale:
nc -zv your-vps-address 6379Expected result: the connection fails.
On my VPS, SSH listens on port 2222. Moving the port protects nothing: it only cuts the noise from bots trying port 22.
How do you limit what Claude can break on the server?
Run Claude Code under a user with no administrator rights, or with rights limited to a few commands. Never paste a password or an API key into the conversation. And keep merging code, and anything that touches production, for a human to approve.
My VPS has two users, one without sudo. To change the firewall, the agent got sudo for iptables only, for that job. My agents hold no GitHub token: a separate program keeps the key and opens pull requests, and I merge myself.
Your Claude login is stored in ~/.claude/.credentials.json. Whoever gets into your Linux account uses your subscription, one more reason to lock down SSH.
Why does your weekly limit run out faster?
Each background session draws on your quota on its own, and a long conversation costs more with every message, because Claude rereads all of it. On my VPS, 81% of usage came from conversations over 200,000 tokens, the unit of text Claude reads, about three quarters of a word.
One session left open for twelve days, coordinating 94 subagents, took 61% of a week's quota. Since then:
- one fresh session per task;
- at most two sessions building or testing at once on 8 cores and 23 GB. With three, tests failed for lack of memory.
What about OpenClaw or Hermes on the same VPS?
The same rules apply to any AI agent that runs nonstop, including OpenClaw and Nous Research's Hermes Agent. The agent holds your keys and runs commands, so give it a separate user, publish its Docker services on 127.0.0.1, and keep access to the server on your private network.
OpenClaw on a VPS gets its own article.
Common errors
"Workspace not trusted" when you start claude remote-control
Cause: the folder was never trusted. Background sessions skip this check, so only Remote Control refuses.
Fix: run claude once in that folder and accept. In your home folder, the question comes back every time.
SSH times out with no message
Cause: SSH listens on another port, or fail2ban banned your address after too many attempts.
Fix: ss -tln on the server shows the right port. If you are banned, wait or go through Tailscale. Do not loop ssh during a reboot: that is how I got myself banned.
A Docker port stays open despite ufw
Cause: Docker's rules run before ufw's.
Fix: publish the port on 127.0.0.1. In the DOCKER-USER chain, match the container's port: on my server, a service published on 8083 listened on 8080.
Firewall rules vanish after a reboot
Cause: an iptables rule lives in memory only.
Fix: use ufw, which saves its rules, or /etc/ufw/after.rules.
Remote Control is unavailable
Cause: you are using an API key, or ANTHROPIC_BASE_URL points somewhere other than Anthropic.
Fix: sign in with your claude.ai account through /login and unset the variable.
Frequently asked questions
Do I need a Max plan for Remote Control?
No. Pro is enough. On Team and Enterprise, an owner must turn Remote Control on first.
Does my code go through Anthropic's servers?
Your code runs on your VPS. But the conversation, including tool activity, is stored at Anthropic while Remote Control is connected.
What happens to my sessions if the VPS reboots?
They stop. Background conversations stay on disk and resume when you open them again. Remote Control has to be started again in tmux.
- Anthropic, Claude Code documentation, "Remote Control", accessed 24 October 2026
- Anthropic, Claude Code documentation, "Advanced setup", accessed 24 October 2026
- Anthropic, Claude Code documentation, "Authentication", accessed 24 October 2026
- Anthropic, Claude Code documentation, "Agent view", accessed 24 October 2026
- Docker, documentation, "Packet filtering and firewalls"
- Tailscale, documentation, "Tailscale SSH"
- tmux, GitHub repository
- fail2ban, GitHub repository
- OpenClaw, GitHub repository
- Hermes Agent, Nous Research, GitHub repository
Keep reading
- Claude skills: the skills I use every day, to give your sessions your own instructions.