№ 021 · 2026-09-20 · shipped · a second macbook + herdr + remote control

An always-on Claude in the closet

claudeclaude-codeherdrremote-controllaunchdmacoshome-labautomation

Most of what I build now starts as a conversation with Claude Code on my laptop. The problem is the laptop. It closes, it sleeps, it leaves the house, and every long-running session on it goes with it. The more of my life that runs through those sessions — the house, the cars, the calendar, a long list of small tools — the more that started to matter.

So I gave Claude a machine that never sleeps.

Two Macs, one setup

Diagram: the laptop and the closet Mac sync skills, tools, settings and MCP config every 30 minutes, with no deletes and no credentials; the phone reaches the closet Mac's always-on session over Remote Control

The closet Mac is a second MacBook that stays on, logged in, and out of the way. It runs Claude Code inside Herdr, a terminal multiplexer built for coding agents, with Remote Control switched on — so the session shows up in the Claude app on my phone and I can pick it up from anywhere. Ask it something from the driveway, and the work happens on a machine that’s still running when I put the phone away.

Two things make it worth having rather than a novelty.

It heals itself. A launch agent wakes every five minutes, checks that the Herdr server and the agent inside it are both alive, and restarts whichever isn’t. It’s idempotent — it will never start a second copy — so it can run forever without anyone thinking about it.

It’s the same Claude. A second machine is only useful if it can do everything the first one can: the same skills, the same small tools, the same MCP servers talking to Home Assistant, the cars and my calendar. That’s the sync script’s job.

Keeping two machines identical

The laptop pushes to the closet every thirty minutes; the closet checks for drift every thirty minutes and raises a macOS notification if the two have wandered apart. Either side can push by hand when it has the newer work.

The rules turned out to matter more than the mechanism:

The workspace-naming hook

Herdr shows each workspace by name, and I had four open, all named after the folder they started in. I couldn’t tell them apart.

So there’s now a small hook that runs every time I send Claude a prompt. In the background — it never slows the turn down — it asks a fast model to boil the prompt down to a two-to-four-word title and renames the workspace. A name I’ve typed by hand is never overwritten. Here’s a slice of the result:

A terminal listing Herdr workspaces with auto-generated titles: Montreux Blanc Whiskey, Brown Leather Sofa Search, UniFi Protect Stream Fix, Boat Status Check, OneNote Export Monitor, Home Security Status Check, and three named Clarify What Task, Unclear Request Input and Clarification Needed

The bottom three are my favourite part: they’re what it produces when my prompt was genuinely vague, which is its own kind of feedback.

It took three attempts, and the failures are the useful bit:

  1. It recursed. The summariser is itself a Claude call, so it fired the same hook, which asked for a summary of the summariser’s instructions. A single environment flag on the child process stops it.
  2. It ignored its input. When stdin isn’t a terminal — and inside a hook it never is — the CLI reads the prompt from stdin and silently ignores a prompt passed as an argument. The fix is to pipe it in.
  3. An option ate the prompt. One flag accepts a variable number of values, so it swallowed the argument that followed it. Order matters.

None of those are documented anywhere I found. All three are the kind of thing you only learn by watching it do the wrong thing.

Why it matters

The lesson is the one that keeps coming up: once an assistant is doing real work around the house, it needs the same things any other service needs — somewhere to run that isn’t a laptop, something that restarts it when it falls over, and a way to keep its configuration in one piece.