Skip to main content
Glama
sonthicse

VMware Workstation Pro MCP Server

by sonthicse

VMware Workstation Pro MCP Server

A local MCP server (stdio) that lets Claude drive VMware Workstation Pro 26 on Windows: list VMs, read configuration, power, snapshots, clone, guest operations, networking, and screenshots.

Built against Workstation 26.0.0, Python 3.14, mcp 2.0.


Install

git clone <this repo>
cd vmware-mcp-server
uv sync

Claude Code (with uv)

claude mcp add vmware -s user -- `
  C:\Users\<you>\.local\bin\uv.exe `
  --directory C:\path\to\vmware-mcp-server `
  run -m vmware_mcp

Two details matter:

  • Use the absolute path to uv.exe. The client spawns the server directly and does not guarantee your shell's PATH.

  • Pass --directory with an absolute path. A stdio server's working directory is chosen by the client and can be anywhere.

Then /mcp in Claude Code to check the connection.

Claude Code (manual install, no uv)

uv is not required — this is an ordinary Python package (requires-python = ">=3.14"). Any Python environment with the dependencies installed works:

git clone <this repo>
cd vmware-mcp-server
python -m venv .venv
.venv\Scripts\pip install -e .

Then register the venv's interpreter instead of uv.exe:

claude mcp add vmware -s user -- `
  C:\path\to\vmware-mcp-server\.venv\Scripts\python.exe `
  -m vmware_mcp

claude mcp add is itself just a convenience that writes the server entry into Claude Code's config (~/.claude.json for -s user, or .mcp.json for -s project). Editing that JSON by hand under mcpServers.vmwarecommand, args, env — has the identical effect; claude mcp add is not required either.

Claude Desktop

This is a standard stdio MCP server, so any MCP-compatible client can run it — including Claude Desktop. Add an entry to its config file:

%APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "vmware": {
      "command": "C:\\Users\\<you>\\.local\\bin\\uv.exe",
      "args": [
        "--directory", "C:\\path\\to\\vmware-mcp-server",
        "run", "-m", "vmware_mcp"
      ],
      "env": {}
    }
  }
}

Swap command/args for the venv's python.exe -m vmware_mcp if installing without uv, same as above. Restart Claude Desktop after editing the file so it reloads the server list.

Related MCP server: ProxmoxMCP-Plus

Configuration

All optional; the defaults suit a standard install. These are plain environment variables read once at server startup (config.py:load_settings) — there is no separate config file of the server's own, so they must be set wherever the MCP client launches the server process, then the server (and the client) restarted for a change to take effect:

  • Claude Code, user scope (claude mcp add ... -s user): edit the env object under mcpServers.vmware in ~/.claude.json (C:\Users\<you>\.claude.json), e.g. "env": { "VMWARE_MCP_ALLOW_DELETE_VM": "1" }. Equivalently, pass -e VAR=value flags when running claude mcp add.

  • Claude Code, project scope (-s project): same env object, in the project's .mcp.json instead.

  • Claude Desktop: the env object under mcpServers.vmware in %APPDATA%\Claude\claude_desktop_config.json.

  • Manual/other clients: set the variable in whatever environment spawns the process (a wrapper script, the OS-level user/system environment variables, etc.) — the server just reads os.environ.

Variable

Default

Purpose

VMWARE_MCP_VMWARE_DIR

C:\Program Files\VMware\VMware Workstation

Where vmcli.exe and vmrun.exe live

VMWARE_MCP_INVENTORY

%APPDATA%\VMware\inventory.vmls

Workstation's VM library file

VMWARE_MCP_VM_ROOTS

common ancestor of registered VMs

;-separated allowlist of directories the server may touch

VMWARE_MCP_TIMEOUT

120

Seconds before a VMware command is killed

VMWARE_MCP_MAX_OUTPUT

100000

Byte cap on guest output

VMWARE_MCP_ALLOW_DELETE_VM

unset

Set to 1 to enable delete_vm

VMWARE_MCP_CREDENTIALS

%APPDATA%\vmware-mcp\credentials.toml

Guest credentials file

VMWARE_MCP_GUEST_USER / _PASS

unset

Fallback guest credentials

Guest credentials

Guest username and password are never tool arguments, so they never enter the model's transcript. Put them in %APPDATA%\vmware-mcp\credentials.toml:

[default]
username = "user"
password = "secret"

[vm.ubuntu-server-26-04-lts]
username = "ubuntu"
password = "ubuntu"

Keys under [vm.*] are the vm_id values from list_vms.

Tools

31 tools, grouped by risk. Annotations are per-tool, which is why operations of different destructiveness are separate tools rather than one tool with an action switch.

Refer to VMs by the vm_id from list_vms; display names and absolute .vmx paths also work. Paths outside the allowlist are rejected with a JSON-RPC -32602.

Read-only

Tool

What it does

list_vms

List every VM registered in VMware Workstation's inventory, running or stopped, plus any unregistered VM that happens to be running

get_vm_info

Full configuration of one VM: CPU, memory, disks, NICs, shared folders, display, USB/sound/floppy, guest isolation, tools, power state

list_snapshots

List a VM's snapshots with the uid needed to revert or delete them

get_vm_ip

Read the IP address a running VM's guest has been assigned

capture_screenshot

Capture what is currently on a running VM's screen

guest_inspect

Read directory contents, running processes, or environment inside a guest

Write

Tool

What it does

vm_power

Start, stop, reset, suspend, pause, or unpause a VM

create_snapshot

Take a snapshot of a VM

clone_vm

Copy a VM to a new .vmx path — linked (fast, shares parent disks) or full (independent copy)

create_vm

Create a new VM, either blank or deployed from a .vmtx template

register_vm

Add an existing .vmx to the Workstation library, so list_vms sees it — Workstation must be closed

unregister_vm

Remove a VM from the library without deleting any files — Workstation must be closed

set_vm_hardware

Change a VM's vCPU count, cores per socket, and memory size

manage_disk

Create a standalone .vmdk file, or extend a disk already attached

attach_disk / detach_disk

Wire a .vmdk into a VM as a SATA or NVMe device, or unwire it

set_network_adapter

Change a NIC's connection type and plug or unplug its virtual cable

set_display

3D acceleration, monitor count, video memory, guest resolution

set_vm_option

Toggle USB / sound / floppy / serial / parallel and guest-isolation settings

manage_shared_folder

Add or remove a share, and turn shared-folder sync on and off (read them from get_vm_info)

set_device_connection

Connect or disconnect a device, live and at power on

send_keystrokes

Type into a VM's console as if at the keyboard — needs no VMware Tools or credentials, but does need host privileges

guest_run

Run a program or a script inside a guest OS

guest_copy_file

Copy a single file between the host and a guest OS

install_tools

Mount the VMware Tools installer in a running VM (install still finishes inside the guest)

manage_port_forwarding

Inspect host virtual networks and manage NAT port forwarding rules

Destructive

Tool

What it does

revert_snapshot

Restore a VM to a snapshot, discarding all changes made since it was taken

delete_snapshot

Remove a snapshot (VM must be powered off or suspended)

guest_modify_path

Create a directory, rename a file, or delete a file/directory inside a guest

guest_kill_process

Stop a process inside a guest OS by PID

delete_vm

Permanently delete a VM and all of its files from disk, sweeping up what vmrun leaves behind — cannot be undone; disabled unless VMWARE_MCP_ALLOW_DELETE_VM=1

To take a VM out of the library but keep its files, use unregister_vm; that is Workstation's Remove from Library, where delete_vm is Delete from Disk.

Everything under Write and Destructive needing guest access additionally requires VMware Tools running in the guest and credentials configured in credentials.toml (see above) — except send_keystrokes, which needs neither.

Things worth knowing

These were all found by testing against a real Workstation 26 install, and each one is a silent failure if you get it wrong.

Snapshots are addressed by UID, not name. vmcli Snapshot Take takes a name, but Revert and Delete take a uid. -n on Take/Revert is the boolean --native flag, not "name". list_snapshots therefore always returns uid; the tools accept a name and resolve it, refusing ambiguous ones.

PowerState: off is not a boolean. PyYAML implements YAML 1.1, where off/on/ yes/no parse as booleans — so a stock yaml.safe_load silently turns the power state into False. yamlfix.py restricts the bool resolver to true/false.

vmcli output is not always valid YAML. HGFS query prints a plain sentence before the mapping. The parser splits that preamble off and keeps it.

vmcli can fail while exiting 0. vmcli Power Start requires administrator rights or __vmware__ group membership; without them it prints a refusal to stdout and exits 0. All power actions therefore run through vmrun. Control commands on both CLIs are sniffed for known failure phrasing — guest output is exempt, since a guest may legitimately print the word "error".

Host-level operations need Administrator. Elevation is not only a vmcli Power Start problem, and it is never reported as one. Run the server as Administrator, or as a member of the __vmware__ group, if you need:

Operation

How it fails without privileges

send_keystrokes

Insufficient permissions in the host operating system

manage_port_forwarding (set/delete)

Failed to refresh NAT configuration — even with VMware NAT Service running

vm_power on some hosts

User must be a member of the __vmware__ group

Reading is unaffected; list_networks, list, and every query tool work unprivileged. Failures matching these patterns come back with an explanation appended, rather than as the CLI's original wording alone.

vmcli Ethernet ConnectionControl crashes vmcli.exe0xC0000409, for every argument arrangement, on Workstation 26. It is not wrapped. set_network_adapter unplugs a cable through Ethernet SetStartConnected plus vmrun connectNamedDevice instead.

A device has two connection states. connectionStatus is live and startConnected is what the .vmx says; get_vm_info reports them as connected and start_connected. A stopped VM shows everything as not connected, which is not a failed write — check start_connected there.

vmcli VM Create makes an unusable VM. It writes scsi0:0.present into the .vmx but never creates the scsi0 controller, so the disk it just made is not attached, and it adds no network adapter. vmcli has no way to create a SCSI controller — use attach_disk, which puts the disk on SATA or NVMe.

Neither CLI can register a VM. vmrun has no register on Workstation and vmcli VM only has Create, so clone_vm and create_vm produce VMs the library knows nothing about. register_vm edits inventory.vmls directly, which is why it refuses while Workstation is running: Workstation keeps the library in memory and rewrites it on exit.

install_tools is Windows-only now. Workstation 26 ships no linux.iso. Linux guests install open-vm-tools from their own package manager.

The two CLIs report errors on different streams. vmcli writes to stderr, vmrun to stdout. Both are captured.

vmcli flags come before positional arguments, and it consumes single-letter flags such as -c itself, so Guest run /bin/sh -c "..." does not work. Use guest_run in script mode for shell syntax.

guest_run does not return the command's output. VMware's guest API never pipes guest stdout back to the host: program mode returns a PID, script mode returns an empty string. To read output, redirect it to a file in the guest and fetch it with guest_copy_file.

Guest passwords are visible in the host process list while a guest command runs. Neither vmcli nor vmrun accepts a password on stdin, so this cannot be fixed here.

send_keystrokes needs neither VMware Tools nor credentials, which makes it the only way to drive a VM sitting at an installer, bootloader, or login prompt. It does need host privileges (see above), and it cannot type a newline: vmrun rejects an embedded \n as an invalid parameter. Send the text, then call again with mode="sequence" and keys="enter", which goes through vmcli MKS sendKeySequence — also the way to send tab, esc, arrow keys, or ctrl-alt-delete.

Development

uv run pytest                              # parser and policy tests, no VM needed
uv run mcp dev src/vmware_mcp/__main__.py  # MCP Inspector

Fixtures under tests/fixtures/ are real vmcli ... query output captured from Workstation 26. When adding a wrapper, read vmcli <Module> <Command> --help on the installed build first — the flags changed between 17.x and 26, and stale flags fail in ways that look like something else.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables comprehensive management of Proxmox virtualization environments, including VM and container lifecycle, snapshots, backups, monitoring, and OpenAPI integration.
    14
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sonthicse/vmware-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server