← Back to Too Good to Share

Too Good to Share / Series

CCSwitchboard

6. Setup, and dropping in at any point

The practical section, and the one where I am most explicitly not selling it.

The pieces are independently useful and independently adoptable. You do not have to take all five at once. The relay and the agent together are enough to drive the whole thing by hand: submit a job with curl, watch the result come back, no extension and no popup involved. The extension is what removes the last of the copy-paste, but the value does not depend on it.

Roughly, standing it up looks like this. The relay is PHP and SQLite; drop it on a host and hit the endpoints. The SQLite file creates itself on first run, and its data directory is denied to the web. The agent is a C# tray app; build it on whichever box will run Claude Code, point its config at the relay's base URL, and run it. It handles the spawning and streaming. The extension loads unpacked in Brave, and this is the messy one: the relay URL is currently hardcoded in about ten places across it, which is the honest caveat. The planned fix is a single relay profile, a URL and a token you paste into the extension's menu once. The popup is optional, lives on the host, and only exists for the finished-job notifications.

Because the relay is the single source of truth and every component only ever polls it, you can add or remove a component while the rest keeps working. Start with the minimum, relay plus agent plus curl, and bolt on the extension and the popup when you want them. Nothing has to come up in a particular order, and nothing breaks if a piece is missing.

On auth: it currently runs in grace mode. Every endpoint checks for a shared token, but a request without one still passes and simply gets logged, so nothing breaks while the token wiring is finished across all the components. The intended posture is a single shared secret that every request carries, generated fresh per install rather than baked into the shared source.

Running Claude Code without the safety prompts

Normally Claude Code stops and asks before it does anything that touches your machine: editing a file, running a command, deleting something. That is the right default when you are sat in front of it. But a headless run has nobody there to click "yes", so every one of those prompts would just hang the job forever. The agent starts each run with the permission checks switched off, so Claude Code acts on its own from the first line to the last.

A single run, stripped to the essentials, is one command:

claude -p "fix the failing test in lib/display.php" \
  --output-format stream-json \
  --verbose \
  --dangerously-skip-permissions

-p is the headless "print" mode: hand it a prompt, let it run, no interactive session. --output-format stream-json is the structured stream the feed renders into tool cards and code blocks instead of a plain terminal. And --dangerously-skip-permissions is the flag that lets it act without asking. The name is a warning, and it is meant literally.

Why it runs inside a VM

That flag is the whole reason for the VM. A virtual machine is a second computer running in a window on the first one, with its own disk and its own view of the world. Claude Code running loose inside it cannot see your real documents, your saved logins, or the rest of your network. If a run goes wrong the blast radius is one disposable box you can roll back or rebuild, not your actual desktop. The isolation is not a nice-to-have bolted on the side. It is what makes running with the prompts off a sane thing to do at all.

Where you can run it

I run it in VirtualBox on Windows because that is what I already had, and the relay does not care in the slightest what the agent runs on. Any of these work. They just trade convenience against isolation differently.

VirtualBox + Windows what I use

A free hypervisor sat on top of your normal Windows desktop. A Windows guest runs Claude Code; the host does everything else.

Easiest if you are already on Windows and want the guest to feel familiar. Shared folders are the one rough edge.

Hyper-V

Windows' own built-in hypervisor, on Pro and up. No extra download; you switch it on as a Windows feature.

Wired tighter into Windows than VirtualBox, and a touch less friendly to casual snapshots. Same idea, one fewer install.

Ubuntu in a VM

Run a Linux guest instead of a Windows one, in VirtualBox or Hyper-V. Claude Code is perfectly happy on Linux.

Lighter than a Windows guest and none of the shared-folder quirks. You give up the Windows-native C# tooling on the guest.

Ubuntu on bare metal

A machine that boots straight into Linux, no hypervisor at all. The whole box is the sandbox.

The strongest isolation of the lot and nothing to virtualise, but it is a whole computer given over to the job.

A separate physical machine

An old laptop or a cheap mini PC in the corner, running whatever OS, doing nothing but this.

Physically walled off from your main machine and able to run around the clock. Costs you a spare box and a bit of desk.

A cloud VM

A rented Linux box from any provider. Nothing local at all; the agent runs in someone else's data centre.

No hardware of your own and reachable from anywhere, but it is a running cost and your code lives off-site.

The honest hurdles, since they are the real content here: it assumes you have a web host for the relay and a Windows VM for the agent, and the token and URL wiring is manual right now. Those are the actual barriers to someone else using it, and I would rather name them than bury them. Where I would take it from here, a bundled local relay and a proper installer, belongs in the next section as things to explore, not here as if they were done.