mcp-vmware
Provides tools for managing VMware vCenter environments, including VM inventory, power operations, snapshots, clone, migration, cluster configuration (HA, DRS, affinity rules), ESXi host management (maintenance mode, services, firewall, storage, advanced settings), and role-based access control with four permission levels.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-vmwarelist all VMs in the datacenter"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-vmware
MCP server to pilot a VMware vCenter (vSphere 7/8) from Claude Code or any MCP client, with two deployment modes depending on your network topology:
Direct: the machine running the MCP client has a route to vCenter (homelab, admin workstation). Up and running in 2 minutes via Docker or pip.
Jump host: the workstation has no access to the management network (a common enterprise setup). The server runs on a bastion machine and the client talks to it over SSH stdio — vCenter credentials never leave the secured zone.
Highlights:
39 tools covering VMs (inventory, power, snapshots, clone, migration), clusters (HA, DRS, affinity rules) and ESXi hosts (maintenance, services, firewall, storage, advanced settings — esxcli equivalent through the official API, no SSH to the hosts).
4 roles with permission groups (viewer/operator/vm_admin/infra_admin): tools outside the active role are not even exposed to the LLM.
LLM ergonomics: compact markdown or structured JSON listings (structuredContent), uniform pagination, real-time progress for long operations.
API map versioned to the vCenter build: the full API surface (1409 SOAP methods, 1064 REST operations) is mapped and versioned; the coverage matrix drives the server's evolution.
Quick start (direct access to vCenter)
cp .vcenter.env.example .vcenter.env && chmod 600 .vcenter.env && vi .vcenter.env
# Docker / Podman (nothing else to install):
docker build -t mcp-vmware -f Containerfile .
docker run -i --rm --env-file .vcenter.env mcp-vmware
# or with Python (>= 3.12):
pip install . && MCP_VMWARE_ENV_FILE=./.vcenter.env python -m mcp_vmwareDeclaration in .mcp.json (the MCP client talks stdio to the container):
{
"mcpServers": {
"vmware": {
"command": "docker",
"args": ["run", "-i", "--rm", "--env-file", "/path/.vcenter.env", "mcp-vmware"]
}
}
}Building behind a corporate proxy (TLS interception included):
docker build --network=host \
--build-arg http_proxy --build-arg https_proxy --build-arg no_proxy \
--build-arg PIP_TRUSTED_HOST="pypi.org files.pythonhosted.org" \
-t mcp-vmware -f Containerfile .Related MCP server: vSphere MCP Server
Jump host mode (segmented enterprise networks)
When vCenter lives in a management network unreachable from workstations, the server installs on the official jump host. MCP speaks stdio over SSH natively: no tunnel, no exposed port.
Workstation (Claude Code / MCP client)
| spawn: ssh jumphost VMware/mcp-vmware/run.sh (stdio = MCP protocol)
v
jumphost (Linux, Python 3.12 venv)
| pyvmomi (SOAP vim25)
v
vcenter.example.com (vSphere 8)Benefits: network segmentation respected, credentials confined to the jump host
(~/VMware/.vcenter.env, chmod 600, never in the repo nor on the workstation),
single audit point.
# 1. Jump host: venv (once)
ssh jumphost 'mkdir -p ~/VMware && python3.12 -m venv ~/VMware/venv'
# 2. Credentials on the jump host
scp .vcenter.env.example jumphost:VMware/.vcenter.env
ssh jumphost 'chmod 600 ~/VMware/.vcenter.env && vi ~/VMware/.vcenter.env'
# 3. Deploy the server (rsync + pip install -e)
./deploy.sh
# 4. Adjust .mcp.json:
# {"mcpServers": {"vmware": {"command": "ssh",
# "args": ["jumphost", "VMware/mcp-vmware/run.sh"]}}}Quick check outside any MCP client:
ssh jumphost 'VMware/mcp-vmware/run.sh' <<'EOF'
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"0"}}}
EOFRoles and permission groups
Access is driven by MCP_VMWARE_ROLE in .vcenter.env (see docs/roles.md
for details and the matching vCenter privilege templates):
Role | Exposed tools | Scope |
| 20 | read-only over everything (inventory + host config) |
| 24 | + VM power and snapshots |
| 28 | + VM reconfiguration, clone, delete, migration |
| 39 | + cluster HA/DRS/rules, host operations and fine-grained host config (esxcli equivalent) |
Tools outside the role are not registered: the LLM never sees them in
tools/list. Additional protections: vmware_delete_vm,
vmware_host_maintenance (enter) and vmware_host_power require
confirm=true; host reboot/shutdown is refused outside maintenance mode unless
force=true.
Defense in depth: use a vCenter service account whose vSphere role matches the
ceiling of the MCP role (templates in docs/roles.md), one env file per
account (MCP_VMWARE_ENV_FILE).
Versioned API map (drives the evolution)
The server's evolution is driven by a complete map of the API, versioned to the vCenter build:
tools/build_api_map.py(run wherever vCenter is reachable) generatesapi-map/<version>-<build>/: the full vim25 SOAP surface (pyvmomi introspection) and the REST vAPI surface (live vCenter metamodel).api-map/coverage.yamllinks each API area to an MCP tool with a status (todo / in_progress / done / wontdo) and carries the v2 backlog.On every vCenter upgrade: rerun the script, commit the new snapshot, and the git diff shows how the API evolved.
Development
./.venv/bin/ruff check src tools tests && ./.venv/bin/ruff format src tools tests
./.venv/bin/mypy src
./.venv/bin/pytest # local suite, mocked pyvmomi, no vCenter requiredAdding a tool: implement it in the relevant tools_*.py module with the
tool(name, title, group=...) decorator (write tools call _gate() first),
update api-map/coverage.yaml in the same commit, deploy, smoke test.
See CONTRIBUTING.md and CODE_OF_CONDUCT.md.
Security & supply chain
Standard supply-chain hygiene, all with SHA-pinned GitHub Actions:
CodeQL static analysis (SAST) on every push/PR and weekly.
OpenSSF Scorecard weekly, results published.
Dependabot for Python and GitHub Actions updates.
Dependency Review on pull requests (fails on high-severity additions).
SPDX license headers on every source file.
Signed commits expected from contributors (see CONTRIBUTING.md).
Minimal workflow permissions (
contents: readby default).
Report vulnerabilities privately: see SECURITY.md.
Disclaimer
This is a personal, independent project — my own take on an MCP server for vCenter. It is not an official product and is not affiliated with, endorsed by, or supported by VMware, Broadcom, Anthropic, or any employer.
Provided "as is", without warranty of any kind (see LICENSE). Use at your own risk.
No support and no SLA. Issues and pull requests are welcome and handled on a best-effort basis, on my own time — there is no guarantee of a response or a fix.
Not production-hardened. This server gives an LLM the ability to act on virtualization infrastructure. Review the code before running it, start with the
viewerrole, use a vCenter service account whose privileges match the chosen role (docs/roles.md), and only raise privileges after validating the write tools on a disposable test scope. You are responsible for any action it performs on your environment.Trademarks (VMware, vSphere, vCenter, ESXi) belong to their respective owners and are used here for identification only.
Available Tools
20 toolsvmware_drs_recommendationsARead-only
Lists the pending DRS recommendations of a cluster (proposed migrations).
Returns a JSON {cluster, count, recommendations:[{key, type, reason, target, actions:[...]}]}. Apply afterwards with vmware_apply_drs_recommendation (cluster.ops).
Inputs: cluster (required), refresh. Returns: result
vmware_get_cluster_configARead-onlyIdempotent
Detailed HA (DAS) and DRS configuration of a cluster + failover capacity.
Returns a JSON {name, ha:{enabled, admission_control_enabled, failover_level, restart_priority, current_failover_level}, drs:{enabled, behavior, vmotion_rate}, rules_count}.
Inputs: cluster (required). Returns: result
vmware_get_hostARead-onlyIdempotent
Details of an ESXi host: state, uptime, hardware, hosted VMs, mounted datastores.
Returns a JSON {name, moid, connection_state, power_state, in_maintenance, in_quarantine, boot_time, uptime_hours, version, model, cpu, memory, vms:[...], datastores:[...], networks:[...]}.
Inputs: host (required). Returns: result
vmware_get_vmARead-onlyIdempotent
Full details of a VM: config, CPU/RAM, disks, NICs, guest IPs, snapshots.
Returns a structured object with uuid, path, hardware_version, disks[], nics[], guest_ips[], snapshots[] (tree), resource_pool, folder, on top of the standard summary.
Inputs: vm (required). Returns: result
vmware_host_advanced_settingsARead-onlyIdempotent
Advanced settings of a host (equivalent of esxcli system settings advanced list), filtered by key prefix.
Returns a structured object {host, filter, count, settings:[{key, value}]}. Modify with vmware_host_set_advanced_setting (host.config).
Inputs: host (required), filter_prefix (required). Returns: result
vmware_host_firewallARead-onlyIdempotent
Firewall of a host (equivalent of esxcli network firewall): default policy and rulesets.
Returns a structured object {host, default_policy, count, rulesets:[{key, label, enabled, all_ips_allowed, allowed_ips}]}. Toggle with vmware_host_firewall_ruleset.
Inputs: host (required), enabled_only. Returns: result
vmware_host_healthARead-only
Hardware health sensors of a host (equivalent of esxcli hardware): overall CPU/memory/storage state and alerting sensors.
Returns a structured object {host, sensor_count, summary:{green, yellow, red, unknown}, sensors:[{name, state, reading}]} — by default only non-green sensors are listed.
Inputs: host (required), all_sensors. Returns: result
vmware_host_network_configARead-onlyIdempotent
Network configuration of a host (equivalent of esxcli network): vSwitches, portgroups, vmkernel interfaces, physical NICs.
Returns a structured object {host, vswitches:[...], portgroups:[...], vmkernel_nics:[...], physical_nics:[...]}.
Inputs: host (required). Returns: result
vmware_host_servicesARead-onlyIdempotent
Lists the services of an ESXi host (equivalent of esxcli system service list).
In json: {host, count, services:[{key, label, running, policy, required}]}. Act on them with vmware_host_service_action (host.config).
Inputs: host (required), response_format. Returns: result
vmware_host_storageARead-onlyIdempotent
Storage of a host (equivalent of esxcli storage): HBA adapters and paginated LUNs with multipath paths.
In json: {host, adapters:[...], total, count, offset, has_more, next_offset, luns:[{canonical_name, model, type, capacity, operational_state, paths}]}. Rescan with vmware_host_rescan_storage (host.config).
Inputs: host (required), limit, offset, response_format. Returns: result
vmware_host_vibsARead-onlyIdempotent
Software packages (VIBs) installed on a host (equivalent of esxcli software vib list) and image profile.
In json: {host, image_profile, total, count, offset, has_more, next_offset, vibs:[{name, version, vendor, acceptance_level}]}. In markdown: table.
Inputs: host (required), limit, offset, name_filter, +1 more. Returns: result
vmware_list_affinity_rulesARead-onlyIdempotent
Lists the affinity / anti-affinity / VM-host rules of a cluster.
Returns a JSON {cluster, count, rules:[{key, name, type, enabled, vms}]}.
Inputs: cluster (required). Returns: result
vmware_list_clustersARead-onlyIdempotent
Lists the clusters: HA/DRS, hosts, aggregated CPU/RAM capacity.
In json: {count, clusters:[{name, moid, hosts, ha_enabled, drs_enabled, drs_behavior, total_cpu_mhz, total_memory, effective_hosts}]}. In markdown: table.
Inputs: response_format. Returns: result
vmware_list_datastoresBRead-onlyIdempotent
Lists the datastores: type, capacity, free space, accessibility.
In json: {total, count, ..., datastores:[{name, moid, type, capacity, free, free_pct, accessible, hosts, vms}]}. In markdown: table.
Inputs: limit, offset, response_format. Returns: result
vmware_list_eventsARead-only
Recent vCenter events, global or filtered on a VM.
In json: {total, count, offset, has_more, next_offset, events:[{time, type, user, target, message}]}, most recent first. In markdown: table.
Inputs: vm, limit, offset, response_format. Returns: result
vmware_list_hostsARead-onlyIdempotent
Lists the ESXi hosts: state, version, model, CPU/RAM load, VM count.
In json: {total, count, ..., hosts:[{name, moid, connection_state, power_state, in_maintenance, version, model, cpu_cores, cpu_usage_mhz, cpu_total_mhz, memory_total, memory_usage, vms}]}. In markdown: table.
Inputs: limit, offset, response_format. Returns: result
vmware_list_networksARead-onlyIdempotent
Lists the networks (standard and distributed portgroups).
In json: {total, count, ..., networks:[{name, moid, type, accessible, vms, vlan}]}. vlan is only filled in for distributed portgroups. In markdown: table.
Inputs: limit, offset, response_format. Returns: result
vmware_list_snapshotsARead-onlyIdempotent
Snapshot tree of a VM (name, description, date, children).
Returns a structured object {vm, count, current_snapshot_moid, snapshots:[...tree...]}.
Inputs: vm (required). Returns: result
vmware_list_vmsARead-onlyIdempotent
Lists the vCenter VMs with filters and pagination.
In json: {total, count, offset, has_more, next_offset, vms:[{name, moid, power_state, guest_os, ip, hostname, cpu, memory_mb, host, vmware_tools}]}. In markdown: table.
Inputs: limit, offset, name_filter, power_state, +1 more. Returns: result
vmware_recent_tasksARead-only
Latest vCenter tasks (running or recent operations) with state and target.
In json: {count, tasks:[{key, description, target, state, progress_pct, user, queued, started, completed, error}]}. In markdown: table, most recent first.
Inputs: limit, response_format. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
TDQS
Scored across 20 tools
Each tool targets a distinct VMware resource or configuration aspect (clusters, hosts, VMs, storage, networking, etc.) with no overlapping purposes. The descriptions clearly differentiate their scopes.
All tools use the 'vmware_' prefix, but verb usage is mixed: some use 'list_', some 'get_', and some are noun phrases (e.g., 'host_advanced_settings'). While readable and predictable, the pattern is not perfectly uniform.
20 tools is well-scoped for a VMware management server, covering major resource types (clusters, hosts, VMs, datastores, networks, events, tasks) without being excessive.
The tool set is heavily read-only; there are no write/modify tools (create, update, delete) for any resource. Several descriptions reference missing action tools (e.g., apply DRS recommendation, toggle firewall ruleset, modify advanced settings), indicating significant gaps for operational use.
Maintenance
Related MCP Connectors
Hosted MCP servers for MSP tools: ConnectWise, NinjaOne, Microsoft 365, SentinelOne, Pax8 and more.
The MCP server that vets MCP servers: identity, risk grade and per-tool risk before you install.
MCP gateway and cloud hosting for MCP servers, agents and apps like RAG, managed from your agent.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server for VMware vSphere/vCenter operations, enabling natural language control of VMs, hosts, and infrastructure.Apache 2.0
- FlicenseNot gradedqualityCmaintenanceA comprehensive MCP server for VMware vSphere management, enabling AI agents to perform VM operations, monitoring, snapshots, and reporting through a secure, Dockerized environment.26-
- AlicenseAqualityBmaintenanceMCP server for VMware vSphere infrastructure management, enabling VM operations, monitoring, and network discovery.1718 PyPI2MIT
- AlicenseNot gradedqualityDmaintenanceMCP server that provides AI agents with comprehensive access to VMware vSphere operations, including VM management, monitoring, and vSAN read-only monitoring, through a secure Docker environment.Apache 2.0