My Claude Code setup, at the start and now
Updated 10 November 2026. The security section now covers how the box stays patched with nobody logged in, how phone sessions are kept away from live client sites and client logins, how the client keys are locked, and how the backups are protected from the box itself.
I built a for and put it on a spare Linux box at home. I use Claude Code from my phone through , or from my laptop or PC, anywhere with internet. I give it a job, and the box does the whole job with everything it needs already in place. It has no desktop and never sleeps. It keeps working without me logged in, and nothing reaches a live client site until I approve it.
A harness is everything around the AI that turns it into a safe way to do real client work: the access it may use, the rules it must follow, the checks it runs and the approvals it waits for. Claude is the engine. The harness is the rest of the car.
This is how I got from one Windows PC doing everything to that box, with real output from it and the security trade-offs I made.
The short version
- What it is: a harness for Claude Code on a spare computer at home that never sleeps. My phone, laptop and PC are only screens for it.
- What it gets me: one prompt from my phone becomes a whole client job, tested and reviewed, while I am somewhere else. Nothing goes live without my OK.
- What it needs: an old desktop, the free Ubuntu and Tailscale, and the Claude subscription I already had.
- For developers: the sections below show how the services, the start-up and the security work.
What the harness is: 5 parts around Claude Code
On its own, Claude Code is a very capable assistant with an empty desk. The harness fills the desk, so a short prompt is enough for a whole job:
For developers: Claude Code is already a harness around the model, with its own loop, tools and permissions. Mine is the layer on top, the part that knows my clients, my rules and my checks.
- Access. The client logins and the job needs, such as Search Console and analytics, kept on the box and never on a phone or laptop.
- Site copy. of each site I work on, so every fix is made and tested away from the live site.
- Rules. that run before each action and block the risky ones, such as touching a live site without my approval.
- Checks. My code checkers and go over every change for standards, SEO, speed and security before I see it.
- Memory. Notes on each client and project, and the lessons from past mistakes, read at the start of every job.
Session on the box
Fix the slow site.

Read the client notes

Pulled last month’s search data

Tested the local copy, found 3 causes

Fixed and re-tested all 3

Reviewers passed
· · · phone back in my pocket · · ·
Ready for your OK
Review the changes, then approve the deploy.
On the box at home
The harness
what a 4-word prompt gets
Claude Code
does the thinking and the edits
always on

Access
Client logins and API keys, kept on the box
search console api · ok

Site copy
A local copy of the site to work on
ddev start · local copy running

Rules
Hooks that block risky actions
live deploy → needs approval

Checks
Checkers and reviewer agents
4 reviewers · all passed

Memory
Notes on the client and past lessons
client notes + lessons · loaded
The prompt is 4 words. The harness supplies the rest. A diagram of a real job type; the lines in each part are simplified.
More than remote access
Remote access lets you look at a computer from somewhere else. A fresh cloud chat starts with nothing on its desk. The box is a desk that is already set up: the client’s access, a copy of their site, my checks and my reviewers are all on it, and it keeps working after I put the phone away.
Remote access to a PC
A view of a screen

Client access only while that PC is on

Local sites only while that PC is on

Nothing runs when it sleeps

The work waits when you disconnect
A fresh cloud chat
An empty desk

No client access until you add it

No local copies of client sites

None of my checks, reviewers or notes

Keeps going when you disconnect
My box
A workshop already set up

Client keys on the box, locked until I unlock them

A local copy of every site

My checks, reviewers and notes on every job

Keeps going when you disconnect, timers too
Remote access shows you a computer. The box is the computer, with everything a client job needs already on it.

Technical note
Credentials live in one place
- API keys and service-account files sit on the box, outside the code repos, and are never pasted into a prompt.
- The phone and laptop hold no client secrets. Lose one and I revoke a device, not a client’s access.
- The SSH keys for client servers carry a passphrase. On a day I need them I unlock them for a set number of hours, and then they lock again by themselves.
- Every fix is made on the local copy first. A change reaches a live site only through a deploy I approve, one action at a time.
Adding the laptop took about 20 minutes: join the private network, make a key on the laptop, add it to the box and map the 2 shares. If it goes missing, I remove it from the private network and delete its key on the box, and it can no longer reach anything. The work was never on it.
One prompt, a whole job
Session on the box
A client says their site got slow. Sort it out and tell me when it’s ready.
sent from the phone
· · · phone back in my pocket · · ·
Later
Ready for your OK: 3 fixes on the local copy, re-tested, reviewed, client summary drafted.
What the box did
at home, always on
With the client’s access, the site, my checks and my reviewers all on the box.
1
Pulled Search Console and analytics data
the client’s API access, stored on the box

2
Opened the local copy of the client’s site
a full copy, so nothing live is touched

3
Speed-tested the key pages and found 3 causes
my performance checks

4
Fixed all 3 on the local copy and re-tested
faster on mobile and desktop

5
Ran my code checkers and reviewer agents
standards, SEO, speed and security

6
Drafted a plain-English summary for the client
I read it and send it myself


Live site untouched. It changes only when I approve the deploy.
An example job, not a screenshot. The steps are the ones the box really runs for a speed job.
The keys stay home. The work goes anywhere. Everything a client job needs lives on the box: the site logins, the API keys for Search Console, analytics and Ads, and a full local copy of the site. Think of it as an office with the keys locked in a drawer that only I can open. Wherever I am, I tell the office what to do, and the keys never leave the drawer. From a phone on a train I can run the same data pull, speed check or code fix as at my desk. Putting a fix live is the one thing the phone can’t do: that waits for my desk and my yes.
Where it started: one Windows PC
Until November, one Windows PC did all of it. Claude Code sessions, the scheduled jobs, the local WordPress sites I build on, and my notes, synced through Google Drive.
It stopped working well once the AI work ran for hours at a time. A Windows update or the PC going to sleep ended every session. The scheduled jobs only ran while the PC was awake. When I added a second machine, the two drifted apart: by 5 November about 40 instruction files and 27 of Claude’s saved memories were different on each.
The fix I chose: put all the work on one machine that is always on, and make every other device a screen onto it.
Work from anywhere: three screens, one box
The box never leaves the house, but the work goes wherever I go. My main PC, my laptop and my phone are all screens onto it, and none of them holds the work. Closing the laptop lid or losing signal loses nothing: the session keeps running on the box and is still there when I reconnect.
Private network
Main PC
Deep work at my desk. It has its own SSH key and 2 file shares, one for the work and one for my notes, and it stores the daily backup.
Private network
Laptop
Set up the same way with a key of its own, so it opens the same sessions, files and local sites from anywhere with internet.
Claude app
Phone
Check-ins and approvals through Remote Control. The box connects out to the app, so no port is open.
At home, always on
The box: all the work runs here
- Claude Code sessions, which keep running when a screen closes
- The scheduled jobs, on timers day and night
- The local WordPress sites, open on every screen
- My notes and files, in one copy with nothing to sync
The private network is Tailscale: encrypted, with nothing open to the internet. The daily backup is encrypted on the box before it goes to the main PC.
The box: a spare desktop running Ubuntu
The box is an old desktop I already had: an 8-core processor, 16 GB of memory, a fast SSD and a large hard disk. The AI itself runs in Anthropic’s cloud, so the box only has to stay on, stay quiet and run a few sessions plus the local sites.
- 26.04 LTS. The same tools as the web servers my clients’ sites run on, and for local WordPress runs without the extra layer it needs on Windows.
- Encrypted disks that unlock themselves. The disks unlock at start-up with the computer’s , so a restart never waits for a password nobody is there to type.
- One way in. The firewall blocks everything except my private network. Nothing is open on the home router and the box is invisible on the internet.
The disk setup gave me the worst scare of the whole build. After a firmware update the box asked for its recovery key at start-up, because the update changed what the TPM checks. I had the key, but I had never tested it. I test a recovery key from another machine on day one now, and I re-seal the TPM before any firmware update.
Why I run it headless
A desktop on a machine nobody sits at only adds things that can go wrong. It needs someone logged in, it shows pop-ups nobody answers, and it tempts you into automatic login and a password-free keyring, the 2 weakest spots a box like this can have.
So the box is . It starts to a text login prompt, and the work runs as background services, so nothing waits for me to log in. The desktop is still installed, switched off, so getting it back takes one command.

Technical note
What a restart looks like
- The firmware is set to power on when the power comes back, so a power cut needs nobody at home.
- The system disk unlocks itself with the TPM, and Linux is running about 20 s after power on.
- All services, file sharing, Docker and the timers, are running about 40 s after power on.
- Remote Control connects about 7 s after that, on the first try. On my first test restart it lost 24.5 s to a retry, fixed the same day (next section).
Claude Code from your phone: Remote Control as a background service
From the Claude app on my phone I start a session on the box, describe the change and approve the steps it asks about. The box does the work: it edits the files, runs the local site and checks the result. I can lock the phone, and the session is where I left it when I look again.
Claude Code has a Remote Control server that lets the phone app and claude.ai start sessions on your own machine. On the box it runs as a systemd service under my own user, so it starts at boot before anyone logs in, and it runs in a sandbox (more under security). Each phone session gets its own copy of the code to work in.
Getting there took more tries than any other part:
- The program expects a terminal, so it runs inside
script, which gives it one. - My first version hid crashes: the service still showed “running” after Claude Code had quit, so it never restarted. I caught it by stopping Claude Code on purpose before anything depended on the service.
- It restarts 30 s after any exit, and after 5 failed starts in 15 minutes it stops and sends me a notice instead of looping.
- At boot it waited until the API’s name looked up, then started. On my first test restart, the name lookup worked and the connection still failed 2 s later. It now waits until the API answers, and I only found that by reading the log for this post.
Two limits are worth knowing before you copy this. Sessions started from the phone don’t get some extras the desktop app has, such as side sessions and the task list. They also can’t reach a live client site at all, which I chose on purpose. I do deep work and live fixes from my PC over and use the phone for check-ins, code and approvals.

Technical note
How the Remote Control service is set up
- It runs as a background service that starts at boot, before anyone logs in.
- It is wrapped so it gets the terminal it expects.
- If it crashes it restarts itself. If it keeps failing, it stops and opens an issue, so I hear about it.
- At boot it waits until it can reach Claude, not only until the network is up.
- It runs in a sandbox that shows it no client keys and no route to a client server.
Security: running it like a server
The box holds client logins and keys, so it is a server, and I run it like one. This is how it is kept.
- Patched. Security updates install themselves every morning, so weeks without a login leave it up to date. An update that needs a restart waits for me to choose the moment.
- Firewalled, no open ports. Nothing is open on the home router. The firewall lets in only my private network, and the local sites can reach the box on one port only, the one the debugger uses.
- The phone stays away from live sites. Phone sessions run in a sandbox. They see no client SSH keys and no client logins, only the read-only keys for data pulls. They can’t reach the Docker that runs the local sites, and a guard blocks any command aimed at a client server.
- Client keys locked. Every SSH key for a client server has a passphrase, unlocked only for the hours I need it. A bad package that slipped onto the box would copy key files it can’t use.
- Staging first. Every fix is built and tested on a local copy of the site. The live site changes only through a deploy I approve, one action at a time.
- Setup backed up. Every file, setting and site database goes into the daily encrypted backup, and my PC keeps a copy the box can’t delete.
Defence in layers
Four layers between the internet and the work

Layer 1
Only my private network
The firewall refuses every incoming connection from anywhere else.

Layer 2
Keys in, password for admin
SSH takes keys only, never the administrator login. Admin commands need a password, apart from a few read-only checks.

Layer 3
Encrypted disks
Both disks are encrypted, and the logins the tools need sit in files only my user can read.

Layer 4
Hooks stop risky commands
Claude Code blocks dangerous commands before they run, such as anything that touches a live client site without my approval.
Trade-offs
Its limits, stated plainly

Docker is nearly admin
Local WordPress sites in DDEV need my user in the Docker group, and that group can do almost anything an administrator can. Phone sessions can’t reach Docker at all. At my desk, the command hooks are the real guard.

Some logins are plain files
WordPress application passwords and API tokens sit on the encrypted disk in files only my user can read, with no passphrase of their own, because the overnight jobs need them unattended. Phone sessions never see them.

The TPM has no PIN
The TPM unlocks the disks without a PIN. That protects a disk pulled out of the box, not the whole box carried away.

My Claude login is a key
Anyone who can log in to my Claude account can reach Remote Control, so two-factor login on that account matters as much as anything on the box.
For a few hours during the move I switched on admin access without a password, because the job got awkward. Narrowing it again was the last step of the job, not a to-do for later.
The rules that keep it safe
Giving an AI the keys to client sites only works if it cannot misuse them. These are not reminders in a prompt: the box enforces every one of them automatically, whichever screen started the session.

Nothing goes live without my yes.
Every change to a live site waits for my approval, one action at a time.

Past clients stay closed.
When a project ends, nothing can touch that client’s site or accounts again unless I reopen it.

No surprise costs.
Nothing the client pays for happens without their written OK.

Secrets stay on the box.
Keys and passwords never pass through a chat or leave the machine.

Every change is checked before I see it.
Automated checks and independent AI reviews cover standards, security, speed and SEO.

Mistakes do not repeat.
When something goes wrong, the fix becomes a safeguard, so the same mistake cannot happen twice.
The stack, layer by layer
For developers, here is each layer, from the hardware up. Nothing in it is exotic; the value is in how the pieces are wired together.
| Layer | What I use | What it does |
|---|---|---|
| Computer | A spare desktop with an SSD and a large hard disk | Stays on and runs the sessions and local sites |
| System | Ubuntu LTS, headless, with encrypted disks | Starts on its own after a restart or a power cut |
| Services | Background services and timers | Runs everything with nobody logged in |
| Network | A private network for my own devices | Lets my devices in and keeps the box invisible on the internet |
| AI | Claude Code on my Claude subscription, Remote Control for the phone app | Does the work, started from any screen |
| Harness | Rules, guards, a playbook for each job type, and memory | Gives every session the same rules, tools and knowledge |
| Reviewers | AI reviewers, one for each kind of check | Check every change before I see it |
| Local sites | A local copy of each WordPress site | Lets every fix be built and tested away from the live site |
| Client data | Google’s own data APIs, read-only | Pulls real numbers into a job without anyone logging in |
| Notes | A notes vault, searched on the box | Holds what I know about each client and project |
| Sharing | File shares over the private network | Shows the same files and notes on my PC and laptop |
| Backups | Encrypted backups to my PC, tested by a restore | Gets everything back if the box fails |
Scheduled jobs on systemd timers
My scheduled jobs used to run inside the desktop app: daily checks on the sites I look after, a daily ads check and a weekly report on how my own setup is doing. Each is now a small service plus a .
- A missed run still happens. If the box was off at 06:30, the site-care check runs as soon as it is back.
- No AI where none is needed. The site-care check is a plain script. The others run Claude Code without a chat window (
claude -p), on the same subscription. - Keep API keys out of the job. If an API key is set where the job runs, Claude Code bills that key per use instead of the subscription.
- Quiet when fine. A failed run opens an issue in a private GitHub repo, which reaches my phone. A run that worked sends nothing.
Each job was switched off in its old place at the moment its timer was switched on, so nothing ran twice and nothing was skipped. This is also the box that runs the checks behind my WordPress maintenance plans, which is why I care that it never sleeps.

Technical note
How the jobs are set up
- Each job is a one-off service, started by a timer.
- A run missed while the box was off happens at the next start.
- The AI jobs run Claude Code without a chat window and stay on the subscription, not API billing.
- A failed job opens an issue in a private repo, so nothing fails quietly.
Backups to my PC, with a tested restore
One always-on machine is also one machine that can die. So every day it makes an encrypted backup to a folder on my PC, over the private network. The backup is encrypted on the box before it leaves, so the PC only ever holds scrambled data.
9 November 2026, as restic reports it, for all the files and site databases together.
The first run backed up every file and every site database, and the PC stores less than half the space they take on the box. Later runs only send what changed.

- The PC is off some of the time. The box tries every hour and backs up once a day. If 2 days pass without a backup, I get a notice.
- Databases without starting every site. A running site’s database is exported through DDEV. A stopped site’s database files aren’t in use, so a straight copy is safe.
- A copy out of the box’s reach. Every hour my PC copies new backup files into a folder only the PC’s administrator can touch, and checks each file. A box that was taken over could wipe its backups on the share, but not that copy.
- A restore, not just a backup. Every Sunday it removes old snapshots, checks a sample of the stored data, and restores test files and a database to compare with the live copies.
- The password lives in 2 places. Without it the backup is unreadable, and the box may be the thing that died.
Setting up the folder on the PC needed one more try than planned. I ran the setup script in an administrator PowerShell window, which doesn’t have the network login my normal window has saved, so it couldn’t write to the box. The script now saves its file locally, and I move it across in File Explorer.
The backup has a limit I should be clear about. The PC is in the same house, so this covers a dead disk or a broken box, not a fire or a break-in. An off-site copy is the next step.

Technical note
How the backup is set up
- The backup lives on a share on my PC that is only connected while the job runs.
- Encryption happens on the box, so the PC only stores encrypted data.
- Site databases are exported before each snapshot, so a restore gets a consistent copy.
- Every week old snapshots are thinned out, part of the data is checked, and a test restore is compared with the live files.
- A task on the PC copies new backup files every hour into a folder the box has no access to, never deleting any.
When an always-on Claude Code machine is worth it
My view, after running one since 4 November:
- Build one if restarts and sleep keep cutting your sessions off, if you want jobs that run overnight, or if you build on local sites and want them reachable from every device.
- Skip it if you run one session at a time and stay at your desk while it works. Your own PC or Claude’s cloud sessions are less work.
- Use a cloud server instead if other people need to reach the machine, or you have nowhere safe and quiet to keep one.
If you do build one, budget time for backups, failure notices and narrowing the access you opened while setting it up. I spent more time on those than on the install. I do the same for clients when I build custom WordPress tools, and you can see the results in my case studies.
If you came here from my post on getting a website ready for AI agents, this is the other side of it: the agent working for me, not visiting my site.
What comes next: more memory, then a GPU for local models
I built the box so that the next steps are upgrades, not rebuilds. The harness, the private network, the backups and the rules stay exactly as they are. Only the hardware grows.
- More memory, next. Going from 16 GB to 32 GB lets more local sites and sessions run side by side without one slowing the others down.
- A graphics card for local models, later. A GPU lets smaller AI models run on the box itself, as . They suit jobs that should never leave the house, such as reading private client files, and cheap background work such as sorting and summarising. Claude stays for the hard thinking.
- The framework is already in place. A local model would join the harness as one more tool, through an , so it gets the same access rules, hooks, checks and memory as everything else on the box.
FAQ
Questions people ask
Yes. Claude Code is a command-line program, so it needs no desktop. Log in once by hand over SSH, then run it as a service. For phone access, run claude remote-control as a systemd service under your own user, so it starts at boot before anyone logs in.
It is everything you build around Claude Code so it can do real work safely: the access it may use, a workspace such as local copies of sites, rules (hooks) that block risky actions, checks and reviewer agents that test its work, and memory files it reads at the start. The model is the engine; the harness decides what it can reach and what it must check.
Yes. Remote Control lets the Claude app on your phone start and steer sessions on your own machine, and that machine does the actual work. Keep it on and run Remote Control as a background service, and you can send a prompt from anywhere and come back to the result.
Run it on a machine that stays on, join your devices to a private network such as Tailscale, then connect over SSH from a laptop and through Remote Control from the phone app. The sessions run on the always-on machine, so you can close one screen and carry on from another.
Run it on another machine that stays on, such as a spare desktop, a mini PC or a cloud server. Start sessions there over SSH or through Remote Control from the phone app. A session the other machine hosts keeps running when your PC restarts or shuts down.
No. The claude remote-control command runs the Remote Control server by itself. It expects a terminal, so under systemd I run it inside script. Sessions it hosts don’t have some desktop-app extras, such as side sessions and the task list.
Ubuntu installs security updates by itself every morning, so the box stays patched when nobody logs in for weeks. An update that needs a restart waits for me, and a service that fails opens an issue that reaches my phone.
Not on my box. Remote Control sessions run in a sandbox with no client keys, no client logins and no route to a client server, and a guard blocks commands aimed at one. Live changes go from my desk, after I approve each one.
Only if an API key is set where the job runs. With no key, claude -p uses the login on the machine, which for me is the subscription. Keep API key variables out of the job’s settings to make sure.
The Claude Code sessions themselves use little, because the AI runs in the cloud. Local sites are what use it up. With 16 GB, running many WordPress sites at once made my box crawl, so I start sites on demand and stop idle ones after an hour.
How this post was made
I built and ran the box myself. Every number and screenshot comes from it, read on 9 November 2026, with machine names, usernames and client names replaced. I drafted the post with help from AI, then edited it.




