Documentation

MCP

agentpc mcp is one stdio MCP server for every VM. Agents use it to create desktops, drive them, take screenshots and reset them, with no human in the loop.

Connect an agent

The installer already ran this for you. Run it again after installing a new agent, or pass client names to pick which ones to register:

$ agentpc mcp-install
$ agentpc mcp-install claude claude-desktop codex cursor gemini vscode

Supported: Claude Code, Claude Desktop, Codex, Cursor, Gemini CLI and VS Code. Restart Claude Desktop after registering. For Codex it also raises the MCP timeouts so slow builds and boots don't trip them. agentpc mcp-uninstall removes the registration again.

Claude plugin

In Claude Code, the plugin bundles the MCP server with a skill that teaches Claude when and how to use the VMs. It runs the installed agentpc binary, so install that first.

/plugin marketplace add pawanpaudel93/agentpc
/plugin install agentpc@agentpc

With the plugin installed, agentpc mcp-install skips Claude Code so the server isn't registered twice.

Client configs

For any other MCP client, add the server by hand. The standard shape:

{
  "mcpServers": {
    "agentpc": { "command": "agentpc", "args": ["mcp"] }
  }
}

Codex

A first create_vm can take minutes while the image downloads, so the server needs longer timeouts than Codex's defaults. agentpc mcp-install codex adds these for you:

[mcp_servers.agentpc]
command = "agentpc"
args = ["mcp"]
startup_timeout_sec = 60
tool_timeout_sec = 900

VS Code

{
  "servers": {
    "agentpc": { "type": "stdio", "command": "agentpc", "args": ["mcp"] }
  }
}

The agentpc repository ships these as project configs (.mcp.json, .codex/config.toml, .cursor/mcp.json, .gemini/settings.json, .vscode/mcp.json), so an agent opened in a clone picks the server up automatically.

Tools

VMs

ToolUse
list_vms VMs (owner, state, size, checkpoints, viewer) and the images they come from, with OS versions. Start here.
create_vm New clone, returned once its desktop is ready: Ubuntu ~1 s, Windows ~4 s (the first create of an image can take minutes). Takes os, and optionally version (Ubuntu "22.04"; Windows "11-25h2", "11-24h2", "11-23h2"), name, memory_gb (2–64, default 8 Windows / 4 Ubuntu), cpus (1–16, default 4) and offline. A non-default size boots cold (~25 s / ~15 s). Retrying in the same session returns the VM it already made.
start_vm / stop_vm Boot a stopped VM, waiting until it's ready / shut one down cleanly.
reset_vm Discard all changes: back to a fresh copy of the image, booted.
delete_vm Stop a VM and delete it with its disk and checkpoints.

Checkpoints

ToolUse
checkpoint_vm Save a VM's disk and memory under a label (replacing an older one of that name) before a risky step. A running VM pauses for a few seconds.
restore_vm Go back to a checkpoint exactly as it was and start it, in seconds. Port forwards must be set up again.
delete_checkpoint Delete one checkpoint by label; the VM is untouched.

Shell, files and ports

ToolUse
run_command PowerShell on Windows, bash on Ubuntu, over SSH. Returns the exit code, stdout and stderr, each trimmed to its first and last 10,000 characters. A foreground run is killed at timeout (default 120 s) with partial output; background: true returns a job id.
get_job_status A background job's state (running, or exited with its code) and the tail of its log (tail_lines, default 50).
upload_file / download_file Copy files or folders between the Mac and a VM.
forward_port Reach a server in the VM from the Mac at 127.0.0.1:<host_port>. An SSH tunnel, so it reaches servers bound to the guest's own 127.0.0.1. Lasts until the VM stops.
list_forwards / delete_forward List a VM's forwards and whether each tunnel is alive / stop one by its host port.

Screen and desktop

ToolUse
take_screenshot PNG straight from the hypervisor, even while booting or hung. save_to also writes it to a path on the Mac.
list_desktop_tools The desktop-control tools inside a VM, or one tool's full schema.
use_desktop_tool Call one of them (tool plus arguments): click, type, launch apps, read the UI tree, and more. Gives up after 120 s.
read_vm_log Tail a VM's qemu or serial log (tail_lines, default 100) when it won't boot or the desktop is unreachable.

Desktop control

Both guests run cua-driver and are 1280×800. Work in a loop: look (take_screenshot or a snapshot tool), act (use_desktop_tool), then look again to verify. Prefer run_command for anything a shell can do.

GuestHow to drive it
Windows launch_app takes a name such as notepad and returns the pid and window_ids. get_window_state(pid, window_id) returns numbered elements and a snapshot_id; click and type_text take that snapshot_id with an element_index. Input goes in the background first; typing into the focused field, scroll, drag and right-click often need "delivery_mode": "foreground", which the driver asks for when background input can't reach the target.
Ubuntu XFCE on X11. get_desktop_state returns a screenshot plus window pid/window_id values. Keyboard and mouse tools need "delivery_mode": "foreground". launch_app takes a command such as xfce4-terminal. Google Chrome is installed for the browser_* tools.

Windows images built by agentpc 0.1.0 use Windows-MCP instead: call Snapshot first, Click takes loc: [x, y], and Type needs loc or label. list_desktop_tools shows which one a VM has.

Open Notepad on Windows and type into it, as three use_desktop_tool calls. The pid and window_id come from launch_app; the snapshot_id and element_index from get_window_state:

{ "name": "windows-1", "tool": "launch_app", "arguments": { "name": "notepad" } }
{ "name": "windows-1", "tool": "get_window_state", "arguments": { "pid": 4120, "window_id": 65812 } }
{ "name": "windows-1", "tool": "type_text", "arguments": {
    "pid": 4120, "window_id": 65812, "snapshot_id": "s1a2b3c4d",
    "element_index": 7, "text": "Hello from the agent" } }

Typical session

Test an install script on a clean machine, keeping a checkpoint to retry from:

create_vm        { "os": "ubuntu", "name": "install-test" }
upload_file      { "name": "install-test", "host_path": "./install.sh", "guest_path": "/tmp/" }
checkpoint_vm    { "name": "install-test", "label": "before-install" }
run_command      { "name": "install-test", "command": "bash /tmp/install.sh" }
take_screenshot  { "name": "install-test" }
restore_vm       { "name": "install-test", "label": "before-install" }  # retry from the same state
delete_vm        { "name": "install-test" }

Some prompts to try:

  • "Create an Ubuntu VM, open a terminal and run uname -a."
  • "Reset ubuntu-1 and check that my install script works on a clean machine."
  • "Open Notepad on windows-1, type a short note and show me a screenshot."

Long jobs and servers

A foreground run_command ends when the command returns, and is killed at its timeout. Start builds, servers and GUI apps with background: true, then poll:

run_command     { "name": "ubuntu-1", "command": "npm run dev", "background": true }  # → job id 1
get_job_status  { "name": "ubuntu-1", "id": 1, "tail_lines": 40 }
forward_port    { "name": "ubuntu-1", "guest_port": 3000 }  # → 127.0.0.1:<port> on the Mac

Reboots (some installers) drop SSH. Call start_vm on the same VM, which waits until the desktop is ready again even if it's already running, or retry run_command.

Session lifecycle

  • VMs a session created or started are stopped, never deleted, when the session ends. Set AGENTPC_KEEP_RUNNING=1 to keep them running.
  • list_vms shows each VM's owner. Agents should create their own uniquely named VM per task, and never reset, restore or delete one they didn't create.
  • Each running VM takes 4 GB (Ubuntu) or 8 GB (Windows) of RAM, so delete VMs when done.
  • The guest login is agent / agent.

Tool annotations

Tools carry MCP annotations so clients can auto-approve or confirm them: list_vms, take_screenshot, list_desktop_tools, get_job_status, list_forwards and read_vm_log are read-only. Tools that discard or overwrite state are marked destructive, including download_file, which writes to your Mac. start_vm and stop_vm are idempotent.