FIELD NOTE / CLAUDE CODE

Claude Code · Remote Control · Hetzner · tmux

My Claude lives in a shed now. The laptop is just a screen.

2026-11-02  ·  ~9 min read  ·  by Gal Tidhar

Every Claude Code session I run, ten projects, the WhatsApp bridges, the browser it uses for logins, all of it ran on my MacBook. Lid closed, battery dead, Wi-Fi gone, and the work stopped. Since 1 November it all runs on a small Linux server I call the shed: EUR 11.28 a month on Hetzner, on top of the Claude subscription I already pay for. I open a session from my phone, from the laptop, from any browser, and it is the same session with the same files. This is the full setup, the price of each part, and the traps, so you can build your own.

What it looks like

  • Phone: the Claude app, Code tab. Every project on the server is listed there as its own session, and I can start a new one. It runs on the server, not on the phone.
  • Laptop: cmux mirrors the server's tmux sessions into its sidebar, so remote projects look exactly like local ones. Close the laptop mid-task: the session keeps going.
  • Browser work: the server has a small desktop with Chrome and the Claude extension. When a site wants a login or a captcha, I open the desktop over VNC (laptop or phone) and click it myself.
  • Files: a folder on the laptop syncs both ways with a folder on the server. Claude drops a file into out/, it appears on my Mac.

The price, all of it

Prices read from the Hetzner pricing API on 2 November 2026, excluding VAT.

Hetzner CX33   4 vCPU (shared), 8 GB RAM, 80 GB disk     EUR  8.49 / month
IPv4 address                                             EUR  0.50 / month
Volume 40 GB   for repos (EUR 0.0572 per GB)              EUR  2.29 / month
Tailscale, Syncthing, tmux, TigerVNC, xfce, Chrome        EUR  0
                                                         --------------
Server total                                             EUR 11.28 / month

Claude subscription  Remote Control needs Pro, Max, Ultra, Team or Enterprise.
                     API keys do not work. I use the Max plan I already had.

What I did not buy: a Mac mini (a new one with enough memory was around EUR 1,500, a used M1 still EUR 450-550) and a rented cloud Mac (EUR 75-150 a month). I wanted a Mac because the agent browser I used is macOS-only. Chrome with the Claude extension on a Linux desktop turned out to be enough, and that killed the only reason to pay ten times more.

One more honest number: the server was already running my Telegram agents, so my real extra cost was the disk and an upgrade to 8 GB. 4 cores and 8 GB holds ten mostly idle sessions, but not ten busy ones. On day one ten sessions, Chrome and two npm ci installs pushed the load to 186 and SSH timed out. 6 GB of swap on the volume (free) makes it slow down instead of freeze. If your sessions build a lot, take 16 GB: the CX43 is EUR 15.99, when the datacenter has one.

The setup, in order

1. A server and a user that is not root

Any Linux VM works. I use Ubuntu 24.04 on Hetzner. Make a normal user with no sudo, so a session running in bypass mode cannot touch the rest of the box, and turn on lingering so its services run without a login.

sudo adduser --disabled-password shed
sudo loginctl enable-linger shed
sudo apt install -y git tmux nodejs npm gh
sudo -iu shed
curl -fsSL https://claude.ai/install.sh | bash
claude auth login        # the full login, see trap 1

2. Remote Control as a service

claude remote-control is the piece that lets the phone app start a brand-new session on the server. It wants a terminal, so it runs inside tmux, and systemd keeps it up. --spawn worktree gives every new session its own git worktree so two of them do not edit the same files.

# ~/.config/systemd/user/claude-rc.service
[Unit]
Description=Claude Code Remote Control server

[Service]
Type=forking
WorkingDirectory=%h/work
Environment=PATH=%h/.local/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/usr/bin/tmux new-session -d -s rc -c %h/work "claude remote-control --spawn worktree --capacity 4"
ExecStop=/usr/bin/tmux kill-session -t rc
Restart=on-failure
RestartSec=30

[Install]
WantedBy=default.target
mkdir -p ~/work && git -C ~/work init
systemctl --user enable --now claude-rc

3. One tmux session per project

This is the part that makes it feel like a workstation. Each project folder gets a tmux session, each tab in it is a Claude session started with --rc, so it also shows up in the app. The whole thing is one small script:

#!/bin/bash
# ~/.local/bin/ws <name> [dir] - first run creates the workspace, every next run adds a tab
set -e
boot=0; [ "$1" = --boot ] && { boot=1; shift; }
name=${1:?usage: ws <name> [dir]}; dir=${2:-$HOME/projects/$name}
cmd="claude --rc --chrome --dangerously-skip-permissions; exec bash"
if ! tmux has-session -t "=$name" 2>/dev/null; then
  tmux new-session -d -s "$name" -n claude-1 -c "$dir" "$cmd"
elif [ $boot = 0 ]; then
  n=$(( $(tmux list-windows -t "=$name" | wc -l) + 1 ))
  tmux new-window -t "=$name:" -n "claude-$n" -c "$dir" "$cmd"
fi

A list file plus a oneshot unit reopens every workspace after a reboot:

# ~/.config/shed-workspaces - one project per line
website
client-app
invoices

# ~/.config/systemd/user/shed-workspaces.service
[Service]
Type=oneshot
RemainAfterExit=yes
Environment=PATH=%h/.local/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/bin/bash -c 'while read -r n d; do [ -n "$n" ] && ws --boot "$n" $d; done < %h/.config/shed-workspaces'
[Install]
WantedBy=default.target

I run bypass mode only because this user owns nothing but its own home folder and the repos. Do not copy that flag onto your laptop account.

4. The laptop as a window into it

On the Mac, cmux ssh-tmux shed shows every server tmux session as a native workspace in the cmux sidebar (it needs the "Remote tmux" beta setting). A tiny shed wrapper on the laptop runs the server scripts over ssh: shed new <name> owner/repo clones a repo and opens its workspace, shed add <name> opens another tab, shed ls lists them. Without cmux, plain ssh -t shed tmux attach -t <name> does the same in any terminal.

5. Private network, shared folder

Tailscale on the server and the laptop, so the desktop and anything else listen only on the private network, never the public internet. Syncthing syncs ~/Shed on the Mac with ~/shared on the server: out/ is what Claude made for me, in/ is what I hand it.

6. A desktop for logins and captchas

Agents get stuck at the same place every time: a login, a 2FA prompt, a captcha. The server runs xfce on TigerVNC, bound to the Tailscale address only, with Chrome and the Claude in Chrome extension. Sessions start with --chrome so Claude drives that Chrome; when it hits a wall I connect with Screen Sharing on the Mac or a VNC app on the phone and type the code.

#!/bin/sh
# start the desktop on the tailnet IP only (see trap 6)
Xtigervnc :1 -interface 100.x.y.z -localhost=0 -rfbport 5901 \
  -rfbauth $HOME/.vnc/passwd -SecurityTypes VncAuth -geometry 1600x1000 -depth 24 &
X=$!; sleep 2
DISPLAY=:1 dbus-launch --exit-with-session startxfce4 &
wait $X

7. Move the rest

Repos go on the attached volume. Then copy the CLI logins you actually use (gh, Supabase, wrangler, gcloud, your .env files) and port scheduled jobs from launchd to systemd timers. Give the server its own ssh key, so revoking it is one line on each machine it can reach.

8. Make it survive a reboot

A plain reboot brings tmux back empty: no session names, no tabs, no conversations. A small script on a one-minute timer saves every tmux session, its tabs, their folders and the Claude session id running in each tab (Claude writes it to ~/.claude/sessions/<pid>.json, matched by tmux pane). At boot a oneshot unit rebuilds the same sessions and starts each tab with claude --resume <id>, a few seconds apart so the box does not choke again.

And the other direction: if the laptop dies, the server is fine, but the laptop's own setup is gone. I keep a private repo with my skills, settings and the server config (secrets encrypted, one passphrase in my password manager). A new laptop runs Tailscale, clones it, starts claude and says "restore my setup". Tailscale SSH means it can reach the server without any key file from the old machine.

The traps

  1. Remote Control refuses a setup token. claude setup-token or CLAUDE_CODE_OAUTH_TOKEN works for claude -p, not for Remote Control. Run the full claude auth login on the server.
  2. The trust prompt quietly exits. In a detached tmux session the "do you trust this folder" prompt defaults to "No, exit" and the session is gone before you see it. Pre-set hasTrustDialogAccepted: true for each project in ~/.claude.json.
  3. The app cannot pick bypass mode. Start the sessions with the flag on the server instead.
  4. Non-interactive ssh does not see ~/.local/bin. ssh shed ws foo fails with "command not found". Symlink the scripts into /usr/local/bin or call them by full path.
  5. The root disk fills up. Mine hit 91% with ten repos and their node_modules. A 40 GB volume for repos fixed it for EUR 2.29.
  6. Ubuntu's vncserver wrapper forces localhost-only, whatever the config says. Run Xtigervnc directly with -interface set to the Tailscale IP.
  7. A WhatsApp linked device lives in one place only. I moved two self-hosted WhatsApp bridges to the server. Two copies running at once kick each other off; stop the laptop one first, then copy its auth folder.
  8. The server clock is UTC. Write timers as OnCalendar=*-*-* 08:30 Europe/Berlin, or your morning report arrives an hour off.
  9. Old Python libs. Ubuntu's packaged google-auth was too old for a refreshed Gmail token and asked for a new browser login every time. pip install --user the current libs.
  10. Mac-only paths in your scripts. /opt/homebrew, framework Python, caffeinate. Every ported job needed one of these fixed.
  11. Ten busy sessions freeze 8 GB. Add swap, never leave a polling loop running on the box, and stagger session starts after a reboot.
  12. A reboot forgets your sessions. tmux names and Claude conversations are gone unless you snapshot them (step 8).
  13. The disk is smaller than the plan says. My CX33 is sold with 80 GB but the root disk was 41 GB, because it had been resized with --keep-disk. Check df -h.
  14. Two machines, one wrangler login. Its refresh token rotates, so copying the login to the server logged both machines out. Run wrangler login on each.
  15. Endpoint security reads your restore script as malware. A script that makes an ssh key, authorises it and decrypts a token archive is exactly what a credential stealer does. Mine was deleted on write. Build it on the server and only clone it onto a new laptop.

What still needs the laptop

"I don't need my laptop" is true for the work and not yet true for everything else. The laptop is the screen I prefer: cmux and VNC run on it. My WhatsApp history lives in the Mac app, so the server has a snapshot I refresh from the laptop; live messages work on the server already. Most scheduled jobs now run as systemd timers on the server; a few that need the Mac stay there. Skills and CLAUDE.md were a one-time copy and do not sync. And one client demo still runs locally. None of it stops a session from running when the laptop is off, which was the point.

Want a shed of your own?

I set up Claude Code for teams and small businesses through ZaZet Solutions: always-on servers like this one, remote access, skills, and the background jobs that keep running when nobody is watching.