From boxcutter
Manages ephemeral dev environment VMs via SSH. Creates, lists, starts, stops, and destroys Firecracker microVMs that boot in ~5 seconds with Tailscale networking, pre-installed dev tools (Node.js, Ruby, git, Claude Code), and passwordless sudo. VMs use per-TAP fwmark routing (every VM is 10.0.0.2 on isolated TAP links). Supports normal and paranoid modes. Triggers on: spinning up a VM, creating a dev environment, testing in a clean machine, running something in isolation, setting up a dev box, ephemeral compute, throwaway environments, sandboxed execution, "try this somewhere safe", "fresh environment", "clean VM", or any mention of Boxcutter. Also triggers when the user needs to SSH into a remote dev machine, check VM status, or manage VM lifecycle.
How this skill is triggered — by the user, by Claude, or both
Slash command
/boxcutter:managing-dev-vmsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Boxcutter provides ephemeral dev environment VMs powered by Firecracker microVMs. VMs boot in about five seconds (including Tailscale join), get a routable Tailscale IP, and come pre-loaded with common dev tools. They're disposable — create one, use it, destroy it.
Boxcutter provides ephemeral dev environment VMs powered by Firecracker microVMs. VMs boot in about five seconds (including Tailscale join), get a routable Tailscale IP, and come pre-loaded with common dev tools. They're disposable — create one, use it, destroy it.
The Boxcutter control interface runs on an Orchestrator VM that joins Tailscale as boxcutter. Check these locations for the host address:
boxcutter — if MagicDNS is enabled, this hostname should workOnce you know the host, save it to memory so you don't have to ask again.
All examples below use HOST as a placeholder for the Tailscale IP or MagicDNS name.
All VM management happens over SSH to the Boxcutter host. No username is required — any username works, so just use the host directly.
Always use -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null when SSHing to Boxcutter hosts and VMs, since VMs are ephemeral and their host keys change on every creation.
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null HOST <command>
| Command | Description |
|---|---|
ssh HOST new | Create and start a new VM (returns name + Tailscale IP) |
ssh HOST create <name> --mode paranoid | Create a paranoid-mode VM |
ssh HOST list | List all VMs with marks, modes, Tailscale IPs, and status |
ssh HOST start <name> | Start a stopped VM |
ssh HOST stop <name> | Gracefully stop a VM |
ssh HOST destroy <name> | Permanently delete a VM (auto-removed from Tailscale) |
ssh HOST status | Cluster capacity summary |
ssh HOST nodes | List all nodes with health |
ssh HOST images | List golden images on nodes |
ssh HOST cp <name> [new-name] | Clone a VM's disk |
ssh HOST adduser <github-user> | Import SSH keys from GitHub for a new user |
ssh HOST removeuser <github-user> | Remove a user's SSH keys |
ssh HOST keys | List configured SSH keys |
ssh HOST help | Show available commands |
ssh HOST new
Output looks like:
-> Trying boxcutter-node-1...
Creating VM: bold-fox (2 vCPU, 2GB RAM, 50G disk, mode: normal)
Name: bold-fox
Node: boxcutter-node-1
vCPU: 2
RAM: 2G
IP: 100.64.1.42
Mode: normal
Status: running
Connect: ssh bold-fox
Parse the name and Tailscale IP from the output. The name appears after "Name:" and the IP appears after "IP:". You need the name for lifecycle commands (stop, destroy) and for SSH access — the VM name works as a hostname via MagicDNS (e.g., ssh bold-fox). The Tailscale IP also works (ssh 100.64.1.42).
Prefer using the VM name as the hostname — it's shorter and more readable. Give the user both the name and the Tailscale IP.
SSH directly to the VM by its name (via MagicDNS) or Tailscale IP. No username needed — all users map to dev (uid 1000) with passwordless sudo. You have full root access via sudo on every VM — use it freely to install packages, configure services, edit system files, or anything else. These are disposable VMs; you cannot break anything that matters.
# By hostname (preferred — MagicDNS resolves the VM name)
ssh bold-fox
# By Tailscale IP (always works)
ssh 100.64.1.42
# Run a command without an interactive session
ssh bold-fox "command here"
The ssh HOST new command waits for the VM to be fully booted and Tailscale-connected before returning. By the time you see the "VM ready" line, SSH should work immediately. If it doesn't connect on the first try (rare), retry once or twice:
ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null bold-fox echo ready
VMs come with:
The dev user has passwordless sudo, so sudo apt-get install ... works without prompts.
Use mise for language runtimes:
ssh bold-fox "mise use -g [email protected]"
ssh bold-fox "mise use -g [email protected]"
Use apt for system packages:
ssh bold-fox "sudo apt-get update && sudo apt-get install -y postgresql redis-server"
Always use -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null with scp too, since VM host keys are ephemeral.
# Copy a file to the VM
scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null file.txt bold-fox:/home/dev/
# Copy a directory
scp -r -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null myproject/ bold-fox:/home/dev/
# Copy from the VM
scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null bold-fox:/home/dev/output.txt ./
Services running in a VM are directly reachable from any device on the tailnet using the VM's hostname or Tailscale IP.
curl http://bold-fox:3000
curl http://100.64.1.42:3000
For HTTPS, see the TLS certificates section below.
When the user wants to test something without affecting their local machine:
ssh HOST new — create a VMssh HOST destroy <name> — clean upWhen the user needs an environment that persists across sessions:
ssh HOST new — create the VMssh HOST stop <name> when not in use (preserves disk state)ssh HOST start <name> to resumeVMs are isolated Firecracker microVMs with their own kernel. They're a good place to run code you don't fully trust, test destructive operations, or experiment with system-level changes. VMs are also isolated from each other on separate TAP devices (no shared network).
Tailscale can provision real Let's Encrypt TLS certificates for any VM on the tailnet. This requires HTTPS to be enabled in the Tailscale admin console (one-time setup at https://login.tailscale.com/admin/dns).
tailscale certAfter a VM is running and joined to Tailscale, get a cert for its MagicDNS name:
ssh bold-fox "sudo tailscale cert bold-fox.<tailnet-name>.ts.net"
This writes .crt and .key files to the current directory. The private key never leaves the VM. Certs last 90 days and must be manually renewed when obtained this way.
Caddy 2.5+ natively fetches TLS certs from the local Tailscale daemon for *.ts.net domains — zero configuration needed. A Caddyfile like this just works:
bold-fox.tail038cc3.ts.net {
reverse_proxy localhost:3000
}
Caddy handles cert provisioning and renewal automatically. It needs access to the Tailscale socket (run as root or grant the caddy user access).
new command waits for everything to be ready before returning.adduser <github-user>.ssh HOST status to see available RAM. Each VM uses 2GB by default.npx claudepluginhub andrewbudd/boxcutter --plugin boxcutterManages VPS for autonomous dev environments: checks status via Supabase queries and health endpoints, connects projects via SSH, provisions new VPS.
Deploys a KubeVirt virtual machine in a Kube-DC project with SSH access, cloud-init config, and optional external IP via LoadBalancer. Provides OS image lookup, DataVolume creation, and SSH key extraction steps.
Guides Azure Dev Box image design, troubleshooting, security, RBAC/SSO, limits, and VS Code dev tunnel workflows. Use for Dev Box deployment and configuration tasks.