VMware Workstation Pro MCP Server

VMware Workstation Pro MCP Server

Enables controlling VMware Workstation Pro virtual machines, including listing, power management, snapshots, cloning, guest operations, networking, and screenshots.

Category
Visit Server

README

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.vmware — command, 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.

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.exe — 0xC0000409, 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.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured