vmware-mcp
by omichelbraga
README.md
# vmware-mcp
Modern MCP server for **VMware Workstation Pro 26.x** (Broadcom). Exposes the
whole automation surface — the **vmrest REST API**, **vmrun**, and **vmcli** —
as MCP tools, so an assistant can list/clone/power/snapshot VMs, run guest
programs, tweak virtual hardware, and manage host networking.
A modernized rewrite of [`ZacharyZcR/vmware-mcp`](https://github.com/ZacharyZcR/vmware-mcp):
| | Original | This project |
|---|---|---|
| MCP SDK | low-level `Server` + 500-line if/elif | **FastMCP** decorators, auto schemas |
| Binary paths | hardcoded `Program Files (x86)` | **registry auto-detection** (+ env override) |
| Config | env vars only | **typed `.env`** (pydantic-settings) |
| Errors | raw tracebacks | **structured `{ok:false,error}` + stderr logging** |
| REST power op | query param (wrong) | request **body** (per API) |
| Health check | — | **`vmware_health`** tool |
| Target | older Workstation | **Workstation 26 / vmrest 1.3.1** |
## Requirements
- VMware Workstation Pro 17+ (built/tested against **26.0.0**)
- The **vmrest** service running (`vmrest.exe -C` to set credentials, then run it)
- Python 3.10+
## Running vmrest as an auto-start Windows service (NSSM)
`vmrest.exe` only runs in the foreground and is **not** service-aware (it never
reports to the Windows Service Control Manager), so a bare `sc.exe`/`New-Service`
service fails with **error 1053** ("did not respond to the start request in a
timely fashion"). Wrap it with [NSSM](https://nssm.cc). Its config (`vmrest.cfg`)
and the VM inventory are **per-user**, so the service must run as *your* Windows
account — not `LocalSystem`.
Replace the placeholders:
- `<USER>` — your Windows account, e.g. `.\alice` (local) or `CORP\alice` (domain)
- `<HOME>` — that account's profile folder, e.g. `C:\Users\alice`
- `<VMWARE>` — the Workstation install dir, e.g. `C:\Program Files\VMware\VMware Workstation`
**1. Set the REST API credentials (once), in a normal — non-elevated — shell** so
the config lands in your profile:
```powershell
& "<VMWARE>\vmrest.exe" -C
```
Enter a username and a password of **8–12 chars** (upper + lower + digit +
special; avoid `: @ / \` since it's used in HTTP Basic auth). This writes
`<HOME>\vmrest.cfg`.
**2. Install NSSM** (any one):
```powershell
choco install nssm -y # Chocolatey
winget install NSSM.NSSM # winget
# or download from https://nssm.cc and unzip
```
**3. Create the service** (elevated PowerShell):
```powershell
$nssm = "C:\ProgramData\chocolatey\bin\nssm.exe" # or your nssm path
$vmrest = "<VMWARE>\vmrest.exe"
& $nssm install vmrest $vmrest
& $nssm set vmrest AppDirectory "<HOME>" # so it finds vmrest.cfg
& $nssm set vmrest DisplayName "VMware Workstation REST API"
& $nssm set vmrest Start SERVICE_AUTO_START
& $nssm set vmrest AppStdout "<HOME>\vmrest-service.log"
& $nssm set vmrest AppStderr "<HOME>\vmrest-service.log"
```
**4. Run it as your account.** Easiest via the GUI so the "Log on as a service"
right is granted automatically:
- `services.msc` → **VMware Workstation REST API** → **Log On** tab → *This
account* → `<USER>` + password → OK.
Or from the CLI (note: `sc.exe`/`nssm` do **not** auto-grant the logon right):
```powershell
& $nssm set vmrest ObjectName "<USER>" "<WINDOWS_PASSWORD>"
# then grant "Log on as a service" to <USER> (secpol.msc → Local Policies →
# User Rights Assignment → Log on as a service), or use the services.msc tab above.
```
**5. Start and verify:**
```powershell
Start-Service vmrest
Get-Service vmrest
# should answer (404 on /api is fine — it means the server is up):
curl.exe http://127.0.0.1:8697/api -u <apiuser>:<apipassword>
```
### Gotchas
- **Run-as account is everything** — under `LocalSystem`, vmrest looks in the
system profile, finds no `vmrest.cfg`, logs *"please use -C to update
credential"* and exits. It must run as the user who ran `vmrest -C`.
- **"marked for deletion"** after `sc delete`/recreate → close any open
**Services console** or **Event Viewer** (they pin the service), then retry.
- **Binds to `127.0.0.1:8697` only** (Basic auth over HTTP) — don't expose it
off-box; front it with a reverse proxy or SSH tunnel if you need remote access.
- If you ever change your **Windows** password, update it on the service's
**Log On** tab or it won't start.
## Install
```powershell
cd D:\MEOC\vmware-mcp
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e .
```
## Configure
Credentials come from env vars (`VMWARE_USERNAME` / `VMWARE_PASSWORD`) or a
`.env` file. Everything else auto-detects. See `.env.example`.
## Register with Claude Code
```powershell
claude mcp add vmware -- D:\MEOC\vmware-mcp\.venv\Scripts\python.exe -m vmware_mcp.server
```
Pass credentials via env at registration:
```powershell
claude mcp add vmware --env VMWARE_USERNAME=<apiuser> --env VMWARE_PASSWORD=<apipassword> -- D:\MEOC\vmware-mcp\.venv\Scripts\python.exe -m vmware_mcp.server
```
## Tool groups
- **REST** (`vm_*`, `network_*`): lifecycle, power, NICs, shared folders, port forwarding.
- **vmrun** (`vmrun_*`): power, snapshots, guest file/process ops, screenshots, keystrokes, host networking.
- **vmcli** (`snapshot_*`, `guest_*`, `chipset_*`, `disk_*`, `ethernet_*`, `hgfs_*`, `serial_*`, `sata_*`, `nvme_*`, `power_*`, `config_*`, `mks_*`, `tools_*`, `template_*`, `vprobes_*`): fine-grained hardware/config.
- **local** (`vm_hardware`, `vm_vmx_raw`): read specs/config straight from the `.vmx` — works for **encrypted VMs** (see below).
- **`vmware_health`**: quick diagnostics.
Any tool that takes `vm_id` accepts either the REST VM id **or** a direct `.vmx` path.
## Encrypted VMs
vmrest 1.3.1 **cannot open encrypted VMs** — `vm_get` and other REST reads
return `Code 110: The virtual machine is encrypted`, and there is no working way
to pass the password over REST (verified: header/query/body all rejected).
Workarounds built in:
- **Reading specs:** `vm_hardware` / `vm_vmx_raw` parse the `.vmx` directly. VMware
Workstation encrypts the disks but leaves the `.vmx` in plaintext, so hardware
specs are fully readable without any password.
- **Power ops:** the `vmrun_*` power tools accept an `encryption_password`
argument (vmrun `-vp`). Set `VMWARE_VM_ENCRYPTION_PASSWORD` in `.env` to apply
it automatically to every vmrun call.
## Note on guest credentials
Guest file/process tools take `user` / `password` for the **guest OS** account —
separate from the vmrest API credentials.
## ⚠️ vmcli on Workstation 26
VMware's `vmcli.exe` (26.x) reads its password from an **interactive console**
and rejects piped/redirected stdin, so the `vmcli`-backed tools generally can't
run headlessly under an MCP server — they return a clear error to that effect.
This is a VMware limitation, not a bug here. Everything important is also
available through the **REST** and **vmrun** tools, which work over the running
vmrest service:
| Need | Use instead of vmcli |
|---|---|
| Set CPU / memory | `vm_update` (REST) |
| Power on/off/suspend | `vm_power_set` (REST) or `vmrun_start`/`vmrun_stop` |
| Snapshots | `vmrun_snapshot_*` |
| Guest exec / files | `vmrun_run`, `vmrun_copy_to`, `vmrun_ls`, … |
| Screenshot | `vmrun_screenshot` |
The vmcli tools are kept for completeness / future use (e.g. if VMware adds a
non-interactive credential path, or for disk/serial/sata/nvme config that has no
REST equivalent — run those from an interactive shell).
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues