Home / Documentation

VM installation and troubleshooting guide

What you need, where images come from, how VMs start in a second, and how to get files, ports and networks to do what you want.

Requirements

RequirementDetails
HardwareApple Silicon Mac, M1 or later (tested on M4).
macOSA version QEMU supports: the current one and, for up to two years, the previous one (tested on macOS 15).
RuntimeQEMU from Homebrew. The installer handles it, installing Homebrew too if needed.
Memory4 GB per running Ubuntu or Arch VM, 8 GB per running Windows VM.
Disk~10 GB per Ubuntu or Arch image, ~30 GB per Windows image, each including its snapshot.

Install

curl -fsSL https://agentpc.pawanpaudel.com.np/install.sh | sh

The installer:

  1. downloads the latest release and verifies its checksum,
  2. installs agentpc to ~/.local/bin (no sudo) and adds it to your PATH,
  3. installs QEMU with Homebrew if it's missing (installing Homebrew first if needed, which asks for your password once),
  4. registers the MCP server with the agents it finds,
  5. checks everything with agentpc doctor.

Upgrade later with agentpc update. Installer options:

VariableEffect
AGENTPC_VERSION=0.1.0Install a specific version.
AGENTPC_INSTALL_DIR=<dir>Install somewhere other than ~/.local/bin.
AGENTPC_NO_MCP=1Skip registering the MCP server.

Images

Every VM is a copy-on-write clone of a read-only image, so it starts from a clean install and costs only a few MB. A bare ubuntu means ubuntu-24.04, a bare arch means arch-rolling, and a bare windows means windows-11-25h2. Pin the full name when the release matters, for example in test harnesses.

ImageSource and how to get it
ubuntu = ubuntu-24.04 Official Ubuntu 24.04 cloud image. image pull (automatic on first create) or image build. Pin a published build with ubuntu-24.04-YYYYMMDD (pull only).
ubuntu-<release> Any release on cloud-images.ubuntu.com, e.g. 22.04 or 26.04. image build ubuntu-22.04, or image pull if published.
ubuntu-x86apps = ubuntu-24.04-x86apps Ubuntu 24.04 that also runs x86_64 and i386 Linux programs, through FEX translation. image pull (automatic on first create; built locally, ~8 min, only if the download fails) or image build ubuntu-x86apps. Also 22.04: ubuntu-22.04-x86apps (x86apps is built for 22.04 and 24.04 only).
arch = arch-rolling Arch Linux ARM (a community port of Arch) with XFCE and Chromium; install packages with sudo pacman -Syu --noconfirm <pkg>. image pull (automatic on first create; built locally in an Ubuntu helper VM, ~6 min, only if the download fails) or image build arch (needs the Ubuntu image, fetched if missing). Pin a published build with arch-rolling-YYYYMMDD (pull only).
arch-x86apps = arch-rolling-x86apps Arch Linux ARM that also runs x86_64 and i386 Linux programs, through FEX translation. image pull (automatic on first create; built locally, ~10 min, only if the download fails) or image build arch-x86apps. Pin a published build with arch-rolling-x86apps-YYYYMMDD (pull only).
windows-11-25h2 Windows 11 25H2 (Home/Pro), 7.3 GB ISO from Microsoft. image build windows.
windows-11-24h2, windows-11-23h2 Earlier Windows 11 releases. image build windows-11-23h2.
windows-<name> Your own Windows 11 ARM64 Home/Pro ISO. image build windows-<name> --iso <path>.

Only ARM64 Windows runs at native speed on Apple Silicon, and Windows 10's ARM64 build hangs at boot, so Windows 11 is the minimum. Enterprise, LTSC and evaluation ISOs aren't supported. Windows runs unactivated (a watermark, nothing else).

Images are clean installs, like a customer's new PC: Windows has no Visual C++ redistributable, no .NET beyond the built-in Framework 4.8.1, and no PowerShell 7. If a program fails with a missing VCRUNTIME140.dll, its installer is missing a dependency. Each image records what it is:

$ agentpc image info windows
{
  "os": "windows",
  "version": "Windows 11 Pro 25H2 (build 26200.6584)",
  "arch": "arm64",
  "built": "20260927",
  "desktop_server": "cua-driver 0.30.3",
  …
}

How it works

  • Hypervisor. VMs run in QEMU on Apple's Hypervisor.framework, natively on Apple Silicon.
  • Instant start. After building or downloading an image, agentpc boots it once, waits until the desktop and its control server are running, and saves the VM's memory. New VMs resume from that state instead of booting: ~1 s / ~4 s instead of ~14 s / ~25 s.
  • Checkpoints. A checkpoint pauses the VM for a few seconds, writes its memory to a file and clones its disk with an APFS copy-on-write clone.
  • VMs from a checkpoint. create_vm with from_checkpoint (CLI --from) clones a checkpoint's disk into a new, independent VM and boots it cold; agentpc first deletes its own job records in that guest, so the new VM starts with none. Prepare a VM once and checkpoint it: restore_vm per task is fastest (same VM), from_checkpoint gives independent copies.
  • Snapshots stay local. A memory snapshot depends on the Mac's chip and QEMU version, so only the disk is published; the snapshot is recaptured after each pull (about a minute).
  • Image distribution. Ubuntu and Arch images are OCI artifacts on GitHub Container Registry: a compressed qcow2 split into 64 MB parts, downloaded in parallel and checksum-verified. A pull checks free disk space first; an interrupted one keeps its verified parts, and pulling again resumes from them. Every layer and the image config are checked against their manifest digest and size, and the joined disk must pass qemu-img check before it replaces the current image.
  • Dated image tags. An image push updates rolling tags but preserves an existing …-YYYYMMDD tag. A refreshed rolling image can therefore differ from the dated build. Publishers on different machines must serialize pushes for a new date unless the registry enforces immutable tags.
  • Pinned downloads. What an image build fetches is pinned and verified: FEX by tag and commit, the Ubuntu and Arch x86 root filesystems and cua-driver's installers and binaries by SHA-256, the Arch Linux ARM tarball by its signature, and Chrome from Google's signed apt repository. Builds and snapshots check that the guest runs the pinned cua-driver.
  • Agent-ready guests. Each snapshot capture turns off what interrupts unattended work (SmartScreen, updates, first-run pop-ups, Ubuntu's background apt jobs, Arch's pacman timers) and installs Chrome on Ubuntu.
  • Arch build. A clone of the Ubuntu image installs the Arch Linux ARM tarball onto a blank second disk (systemd-boot, XFCE, Chromium, cua-driver); that disk becomes the image. The verified tarball is cached in ~/.agentpc/cache/alarm for the next build.
  • x86apps build. FEX (pinned by tag and commit) is built from source as a static-pie, with a patch so x86 containers work, plus an x86 root filesystem: Ubuntu's as a squashfs the kernel mounts at boot, Arch Linux's unpacked so fex-pacman can add to it. QEMU for these VMs turns on the CPU's TSO mode (macOS 15+); agentpc tells FEX after each boot whether it got it.

Networking

Each VM sits behind QEMU's user-mode NAT: VMs are isolated from each other but share the Mac's network, so a VPN on the Mac applies to their outbound traffic.

To reachDo this
A VM server from the Mac agentpc forward <name> <guest-port> (MCP: forward_port), then connect to 127.0.0.1:<host-port>. Works for servers bound to the guest's own 127.0.0.1; the Windows firewall doesn't apply. For a UDP server add --udp (MCP: protocol: "udp"); it must listen on 0.0.0.0, and on Windows needs a firewall rule.
The Mac from a VM 10.0.2.2 is the Mac. A dev server on 127.0.0.1 or 0.0.0.0 is at 10.0.2.2:<port>.
VM to VM Forward VM B's port to the Mac, then from VM A connect to 10.0.2.2:<host-port>. For UDP, forward with protocol: "udp" and have B's server listen on 0.0.0.0.
Through a corporate proxy Guests inherit no proxy. Set HTTP_PROXY/HTTPS_PROXY in the guest and import your root CA (Import-Certificate on Windows, update-ca-certificates on Ubuntu, sudo trust anchor --store <cert> on Arch).

Offline VMs (--offline / offline: true) can't reach the internet or 10.0.2.2, but TCP ports you forward from the Mac still reach them. UDP forwards don't work on them.

Configuration

VariableDescription
AGENTPC_HOMEWhere images, VMs, keys and caches live. Default ~/.agentpc.
AGENTPC_IMAGE_REPOPackage for image pull/push. Default ghcr.io/pawanpaudel93/agentpc.
WIN_ISOWindows ISO used by image build windows-… without --iso.
AGENTPC_KEEP_RUNNINGSet to 1 to keep VMs running when an MCP session ends.

Each VM gets its own ports on 127.0.0.1, derived from its slot number n:

PortUse
47000 + nSSH
47200 + nnoVNC WebSocket, for the viewer
47300 + nVNC
8100Browser viewer, shared by all VMs

Guest tips

Windows: GUI installers return immediately

Run them silently and wait for the process, then check its exit code:

Start-Process installer.exe -ArgumentList '/S' -Wait -PassThru

Windows Update is disabled

So updates never interrupt a task. This also blocks DISM /online and Add-WindowsCapability. Re-enable it temporarily:

Set-Service wuauserv -StartupType Manual; Start-Service wuauserv
# … Add-WindowsCapability / DISM …
Stop-Service wuauserv; Set-Service wuauserv -StartupType Disabled

Windows: Defender is on

Only SmartScreen is off. Defender may quarantine a fresh or unsigned test binary, so exclude your work directory:

Add-MpPreference -ExclusionPath C:\work

Windows: x64 apps run through emulation

The guest is Windows 11 ARM64. x64 and x86 programs (installers, desktop apps, CLIs) run through Windows' built-in Prism emulation, roughly 2–4× slower than native. x64 drivers, kernel-mode software and anti-cheat don't run. Prefer an ARM64 build when one exists.

Arch guest tips

  • Packages: sudo pacman -Syu --noconfirm <pkg> (Arch doesn't support partial upgrades). The first -Syu may upgrade the whole system, so give run_command a longer timeout or background: true; after a kernel upgrade, reboot (start_vm) before loading new modules.
  • /tmp is a tmpfs, cleared at every boot (unlike Ubuntu's); keep files elsewhere.

x86_64 Linux programs

The Ubuntu and Arch guests are arm64. Create a VM from ubuntu-x86apps or arch-x86apps (create_vm with version: "x86apps") and x86_64 and i386 programs run through FEX, which translates each one to arm64: about 2× slower, JIT runtimes such as Node 6–7×, and much faster from the second start on thanks to FEX's code cache. On macOS 15 or later the VM's CPUs also run in TSO mode, x86's memory ordering, which makes multithreaded x86 code up to ~40% faster; list_vms (agentpc list --json) shows it as x86_tso: hardware or emulated. Go programs work (the image sets GODEBUG=asyncpreemptoff=1 for them). x86 Electron and Chromium apps need --no-sandbox. On Ubuntu a missing x86 library installs with sudo apt install libfoo:amd64 (or an amd64 .deb: sudo apt install ./app_amd64.deb, whose install scripts see an x86_64 machine); on Arch (no multiarch) x86 programs use the image's x86 Arch Linux tree, and sudo fex-pacman -Sy --noconfirm --needed <pkg> installs more x86 packages into it. x86 systemd services run too, hardened ones included: for a unit whose ExecStart is an x86 program, a generator relaxes MemoryDenyWriteExecute= and LockPersonality= (they stop FEX, as any JIT); a unit that runs its x86 program through a script needs sudo fex-unit <unit> (else it dies with a SIGSEGV inside FEX). An installer that refuses non-x86_64 (uname -m) runs unmodified under the x86 bash: sudo FEXBash ./install.sh; for a paste block (curl … | sudo bash -s), start FEXBash and paste it there. x86 containers work too: docker run --platform linux/amd64 <image> (install Docker first: sudo apt install docker.io on Ubuntu, sudo pacman -Syu --noconfirm docker && sudo systemctl start docker on Arch). x86 kernel modules don't run: it's translation, not an x86 machine.

Hardware limits

Guests have a fixed 1280×800 display, a 2D-only GPU (no 3D acceleration; WebGL is software-rendered or unavailable) and no audio device.

Troubleshooting

SymptomTry
Something's off with the setupagentpc doctor
Can't tell what the VM is doingagentpc screenshot <name>, or open the viewer URL from agentpc info <name>.
VM won't bootRead qemu.log and serial.log in ~/.agentpc/instances/<name>/ (MCP: read_vm_log).
VM is in a bad stateagentpc reset <name>
SSH dropped after a rebootagentpc start <name> waits until the desktop is ready again.
image build/pull/rm refusesVMs still use that image; agentpc rm them first. Build and rm also refuse while a running build uses the image (an Arch build runs in a clone of the Ubuntu image), and rm while a pull or snapshot of it runs: try again when it finishes. A pinned …-YYYYMMDD image can only be pulled.
A build or snapshot says the guest runs another cua-driverThe image came from a different agentpc version: agentpc image build <image>.
agentpc update can't write to its directorysudo agentpc update, or reinstall there with AGENTPC_INSTALL_DIR=<dir>.
Running low on diskagentpc clean deletes what can be downloaded again.

Security

  • Everything listens on 127.0.0.1 only.
  • Before handing out a viewer link, agentpc authenticates the local viewer with a fresh HMAC-SHA256 challenge. The private identity key is not returned over HTTP; a recorded response cannot authenticate a different challenge.
  • The desktop-control servers inside VMs are unauthenticated; any process on your Mac can reach them.
  • Each VM has its own VNC password. The viewer URL from agentpc info carries it in the URL fragment, so the browser viewer connects without a prompt. --open and open_in_browser: true open that same local viewer. Treat these links as credentials: do not share them, include them in logs, or capture the address bar in screenshots; browsers can retain visited URLs in history.
  • Guests use the fixed login agent / agent for the desktop and sudo; SSH takes only agentpc's key. Windows VMs have UAC prompts, SmartScreen and Windows Update turned off.
  • VMs can reach the internet and your Mac through 10.0.2.2. Use --offline for untrusted software.
  • Treat VMs as throwaway sandboxes, not a place for secrets.

Uninstall

$ agentpc uninstall            # asks first; -y skips the prompt

This stops all VMs, removes the MCP server from every agent, and deletes ~/.agentpc (--keep-data keeps it) and the binary. It leaves shared things alone and lists them: the PATH line, QEMU, and the Claude plugin.