Run in a VM or over SSH
Run Cua Driver inside a macOS Lume VM or drive a Windows desktop over SSH.
Run Cua Driver inside a macOS Lume VM or drive a Windows desktop over SSH.
Cua Driver always runs on the machine whose desktop it drives. To reach a VM or a remote computer, run the driver there and carry MCP over SSH.
On an Apple Silicon host with Lume and jq, pull the
published Tahoe image (150 GB sparse disk; login and password lume):
IMAGE=macos-tahoe-cua:26.5.2
VM=cua-driver-dev-26.5.2
lume pull "$IMAGE" "$VM"
lume run "$VM"The image has SIP disabled to match the maintainer test base; that grants no permissions, and Cua Driver works with SIP on too. In Terminal inside the VM display, install and grant consent:
/bin/bash -c "$(curl -fsSL https://cua.ai/driver/install.sh)"/Users/lume/.local/bin/cua-driver permissions grant
/Users/lume/.local/bin/cua-driver list_apps '{}'
/Users/lume/.local/bin/cua-driver call get_desktop_state '{}' > /tmp/desktop.jsonApprove three kinds of prompt: Accessibility and Screen Recording for
CuaDriver, CuaDriver controlling System Events (from list_apps), and Tahoe's
separate direct screen capture (from get_desktop_state). Rerun the last two
commands; they must finish without prompts. Then confirm the daemon's grants:
/Users/lume/.local/bin/cua-driver permissions status --jsonExpect accessibility: true, screen_recording: true, and
source.attribution: "driver-daemon". unknown means no app-owned daemon
answered: start it with open -n -g -a CuaDriver --args serve.
Run an agent inside the VM with the usual
mcp-config, or from the host over
SSH. Copy only your public key into the guest, then register the SSH command
as a stdio server:
VM_IP="$(lume get "$VM" --format json | jq -r '.[0].ipAddress')"
cat ~/.ssh/id_ed25519.pub | ssh "lume@${VM_IP}" \
'umask 077; mkdir -p ~/.ssh; cat >> ~/.ssh/authorized_keys'
codex mcp add cua-driver-vm -- \
ssh -T -o BatchMode=yes "lume@${VM_IP}" /Users/lume/.local/bin/cua-driver mcpThe remote cua-driver mcp proxies to the daemon in the logged-in guest
session, so screenshots and input keep the guest app's permission identity.
Do initial consent and GUI checks in the VM display, not over SSH.
Save a reusable copy while stopped. Keep it local, with no tokens, private keys, or personal files inside:
lume stop "$VM"
lume clone "$VM" "${VM}-backup"
lume lsA clone keeps its grants only while /Applications/CuaDriver.app keeps the
release signature; an ad-hoc source build gets a new permission identity.
Maintainers running the driver's macOS E2E suite in Lume follow
libs/cua-driver/tests/runners/macos-lume/README.md in the repository.
Windows OpenSSH runs in Session 0, which has no desktop, so window tools
return empty results there. cua-driver doctor reports
running in Session 0 (services). Run the daemon in your interactive session
and let the SSH side proxy to it over the named pipe:
Session 1+ (RDP or console) cua-driver serve (autostart task)
▲ \\.\pipe\cua-driver
Session 0 (SSH) cua-driver call … / cua-driver mcp --socket \\.\pipe\cua-driver1. From RDP or the local console, register and start the task:
cua-driver autostart enable
cua-driver autostart kickquery session must show your user as Active or Disc. If you have never
signed in with RDP, do it once.
Sign in through SSH with the same Windows account that owns the interactive daemon. The named
pipe is private to that account; another account can see the pipe but gets Access is denied.
Run whoami /user in both sessions and compare the SIDs, which must match exactly.
2. From SSH, check the daemon and call tools:
cua-driver status
# Cua Driver daemon is running
# socket: \\.\pipe\cua-driver
cua-driver call list_appsIf the endpoint exists but belongs to another Windows account, status reports
it as not reachable and tells you to compare the two account SIDs.
3. Register the agent with an explicit socket:
claude mcp add --transport stdio cua-driver -- cua-driver.exe mcp --socket \\.\pipe\cua-driverBare cua-driver mcp owns its own runtime on Windows and fails in Session 0. Always pass
--socket. If the interactive daemon is gone, MCP startup fails instead of acting from the
wrong session.
Still empty? Check that whoami /user shows the same SID over SSH and on the
desktop, that cua-driver --version matches over SSH, that
cua-driver autostart status shows the task, and that cua-driver doctor from
RDP reports session N has an attached interactive desktop.