VMware vSphere MCP Server

เซิร์ฟเวอร์ MCP ที่ทำหน้าที่เป็นอินเทอร์เฟซมาตรฐานในการเปิดเผยฟังก์ชันการทำงานของ VMware vCenter ในรูปแบบเครื่องมือที่โมเดล AI สามารถใช้งานได้โดยตรง

เอกสาร

vSphere MCP Server

A comprehensive Model Context Protocol (MCP) server for VMware vSphere management, providing AI agents with full access to virtual infrastructure operations through a secure, Dockerized environment.

Features

Core VM Management

  • List VMs - Get all virtual machines with power states
  • VM Details - Detailed information about specific VMs
  • Power Operations - Start, stop, restart VMs
  • Resource Monitoring - CPU, RAM, and network utilization
  • Storage Information - Disk usage and datastore details

Advanced Operations

  • Snapshot Management - Create, list, delete and revert VM snapshots
  • Template Management - List and manage VM templates
  • Bulk Operations - Power operations on multiple VMs
  • Resource Modification - Change CPU and memory allocation
  • Network Management - Port groups and network configuration
  • VM Cloning - Clone templates into new VMs via pyVmomi

Monitoring & Reporting

  • Performance Monitoring - Real-time resource utilization
  • Event Logging - VM events and system logs
  • Alarm Management - Active alarms and alerts
  • Comprehensive Reports - Environment-wide analytics
  • Resource Utilization - CPU, memory, and storage summaries

Safety Features

  • Confirmation System - All destructive operations require explicit confirmation
  • Optional Bearer Token Auth - Restrict access to /mcp with MCP_AUTH_TOKEN
  • Tool Allow-Listing - Hide any tool from clients with DISABLED_TOOLS (e.g. read-only deployments)
  • Error Handling - Comprehensive error messages and troubleshooting
  • Secure Authentication - Environment-based credential management
  • Audit Trail - Clear logging of all operations

Installation

Prerequisites

  • Docker and Docker Compose
  • VMware vCenter Server 7.x / 8.x
  • Valid vCenter credentials

Quick Start

  1. Clone repo

  2. Configure Environment

cp env.example .env
# Edit .env with your vCenter credentials
  1. Deploy with Docker
docker compose up -d

Configuration

Environment Variables

Create a .env file with the following variables:

# vCenter Connection
VCENTER_HOST=vcenter.domain.local
VCENTER_USER=username@domain.local
VCENTER_PASSWORD=your_password_here
INSECURE=True

# Server Configuration
SERVER_HOST=0.0.0.0
SERVER_PORT=8000

# MCP Server Authentication (optional, leave empty to disable auth)
MCP_AUTH_TOKEN=

# Tools to hide from clients (optional, comma-separated tool names)
DISABLED_TOOLS=

.env is excluded from both git (.gitignore) and the image build (.dockerignore). Credentials are injected at runtime via env_file, never baked into the image layer.

API Transport

Two different vSphere APIs are used depending on the operation:

APIUsed forClient
vSphere REST (/api)VM listing, power, inventory, performancevsphere_client.py
vSphere SOAP (pyVmomi)Snapshots, cloning, templates, network lookupsoap_client.py, pyvmomi_client.py

Snapshot operations use SOAP because vSphere 8 removed the REST snapshot endpoints.

AnythingLLM Integration

Add the following configuration to your anythingllm_mcp_servers.json. When MCP_AUTH_TOKEN is set, the same value must be supplied as auth_token:

{
  "mcpServers": {
    "vsphere-mcp-server": {
      "name": "vSphere MCP Server",
      "type": "streamable",
      "url": "http://vsphere-mcp-server:8000/mcp",
      "auth_token": null,
      "enabled": true
    }
  }
}

Local stdio (Claude Desktop, etc.)

For MCP clients that launch the server as a local subprocess over stdio (e.g. Claude Desktop) instead of connecting to an HTTP endpoint, set MCP_TRANSPORT=stdio and provide vCenter credentials directly in the client's own server config — stdio mode has no .env file and no interactive credential prompt, so VCENTER_HOST/VCENTER_USER/ VCENTER_PASSWORD must be set here or the server exits immediately with an error.

{
  "mcpServers": {
    "vsphere-mcp-server": {
      "command": "python",
      "args": ["-m", "vsphere_mcp_server.server"],
      "env": {
        "PYTHONPATH": "src",
        "MCP_TRANSPORT": "stdio",
        "VCENTER_HOST": "vcenter.domain.local",
        "VCENTER_USER": "username@domain.local",
        "VCENTER_PASSWORD": "your_password_here",
        "INSECURE": "True"
      }
    }
  }
}

This path runs directly against a local Python install (pip install -r requirements.txt first) — it does not use Docker. The Docker/AnythingLLM streamable-HTTP setup above is unaffected and remains the recommended deployment for production use.

Available Tools

42 tools are exposed. hostname is optional everywhere and falls back to VCENTER_HOST.

VM Management

ToolDescriptionParameters
list_vmsList all virtual machineshostname
get_vm_detailsGet detailed VM informationvm_id, hostname
power_on_vmPower on a virtual machinevm_id, hostname
power_off_vmPower off a virtual machinevm_id, hostname

Infrastructure Management

ToolDescriptionParameters
list_hostsList all ESXi hostshostname
get_host_detailsGet ESXi host detailshost_id, hostname
list_datacentersList all datacentershostname
get_datacenter_detailsGet datacenter detailsdatacenter_id, hostname
list_datastoresList all datastoreshostname
get_datastore_detailsGet datastore detailsdatastore_id, hostname
list_foldersList inventory foldersfolder_type, hostname
get_folder_detailsGet folder detailsfolder_id, hostname
list_networksList all networkshostname
get_network_detailsGet network detailsnetwork_id, hostname
list_vlansExtract VLANs from network nameshostname
get_vlan_infoLook up a VLAN by name or IDvlan_query, hostname
get_port_groupsGet network port groupshostname

Monitoring & Performance

ToolDescriptionParameters
get_vm_performance_infoGet VM performance metricshostname
get_host_performance_infoGet host performance metricshostname
get_vm_disk_usageGet VM disk utilizationhostname
get_vm_storage_infoGet VM storage layouthostname
get_datastore_usageGet datastore utilizationhostname
get_vms_with_high_resource_usageFind VMs with high resource allocationhostname
get_vm_eventsGet VM eventsvm_id, hostname
get_alarmsGet active alarmshostname

Snapshot Management

Snapshot tools use the SOAP API (vSphere 8 removed the REST endpoints).

ToolDescriptionParameters
list_vm_snapshotsList one VM's snapshots, or query all VMs' snapshotsvm_id (optional; omit for fleet-wide query), hostname (optional)
create_vm_snapshotCreate VM snapshotvm_id, snapshot_name, description, hostname (optional)
delete_vm_snapshotDelete VM snapshotvm_id, snapshot_id, confirm, hostname (optional)

Template Management

ToolDescriptionParameters
list_templatesList VM templates (REST)hostname
find_template_pyvmomiFind a template via pyVmominame, datacenter, hostname

pyVmomi Operations (clone & networks)

ToolDescriptionParameters
list_datacenters_pyvmomiList datacenters via pyVmomihostname
list_clusters_pyvmomiList clustersdatacenter, hostname
clone_vmClone a template into a new VMvm_name, template_name, cluster_name, datastore_name, network_name, target_datacenter, cpu_count, memory_gb, confirm, hostname
get_vm_networks_pyvmomiGet a VM's networksvm_name, hostname

Reporting & Analytics

ToolDescriptionParameters
generate_vm_reportGenerate comprehensive VM reporthostname
get_resource_utilization_summaryGet resource utilization summaryhostname

Automation

ToolDescriptionParameters
bulk_power_operationsBulk power operationsoperation, vm_list, hostname
bulk_delete_vmsBulk delete VMsvm_list, confirm, hostname

Destructive Operations (Require Confirmation)

ToolDescriptionParameters
delete_vmDelete virtual machinevm_id, confirm, hostname
modify_vm_resourcesModify VM resourcesvm_id, cpu_count, memory_gb, confirm, hostname
force_power_off_vmForce power off VMvm_id, confirm, hostname
delete_vm_snapshotDelete a snapshotvm_id, snapshot_name, confirm, hostname
revert_vm_snapshotRevert to a snapshotvm_id, snapshot_name, confirm, hostname
clone_vmClone a templatesee above

Destructive operations require explicit confirmation by setting confirm=True

Filtering, counting, and ranking

The list tools (list_vms, list_hosts, list_datastores, list_networks, list_clusters_pyvmomi) accept optional filters, group_by, fields, sort_by/descending, and limit parameters. Filtering, counting, and sorting run inside the server (one PropertyCollector round-trip for the whole inventory), so only the result — never the full inventory — reaches the LLM. list_vm_snapshots supports the same parameters in fleet mode: called without vm_id, it queries the snapshots of every VM in one round-trip.

Examples:

  • Which VMs run hardware version vmx-13? list_vms(filters=[{"field": "hardware_version", "op": "eq", "value": "vmx-13"}])
  • Show the guest OS distribution: list_vms(group_by="guest_os") → one line per OS with count and percentage
  • Datastores below 10% free: list_datastores(filters=[{"field": "free_pct", "op": "lt", "value": 10}])
  • VMs with hardware version vmx-13 or older: list_vms(filters=[{"field": "hardware_version", "op": "lte", "value": "vmx-13"}])
  • The 10 largest VMs by provisioned storage: list_vms(sort_by="storage_provisioned_gb", fields=["name", "storage_provisioned_gb"], limit=10)
  • The 10 oldest snapshots anywhere in the fleet: list_vm_snapshots(sort_by="age_days", limit=10)
  • Snapshots older than 30 days, per VM: list_vm_snapshots(filters=[{"field": "age_days", "op": "gt", "value": 30}], group_by="vm_name")
  • Which VMs are in which network? list_vms(fields=["name", "networks"], limit=0) — or list_vms(group_by="networks") for the VM count per portgroup
  • VMs attached to any DMZ portgroup: list_vms(filters=[{"field": "networks", "op": "contains", "value": "DMZ"}])
  • VMs stored on a specific datastore: list_vms(filters=[{"field": "datastores", "op": "eq", "value": "prod_store"}])
  • Hosts mounting fewer than two datastores: list_hosts(filters=[{"field": "datastore_count", "op": "lt", "value": 2}])

Operators: eq, ne, contains, not_contains, gt, gte, lt, lte, in (conditions are ANDed, string matching is case-insensitive). Range operators compare numbers, and also prefix-number strings like vmx-13 by their trailing number. sort_by orders by any queryable field (descending defaults to true — biggest/latest first). Each tool's description lists its queryable fields. limit defaults to 50 rows (0 = unlimited).

Membership fields: VMs, hosts, and clusters expose networks and datastores (name lists, resolved in one bulk lookup) plus network_count/datastore_count. On these list fields eq/contains match if ANY member matches, ne/not_contains only if NO member does, and group_by counts an object once per member (a multi-homed VM appears under every network it is attached to; objects with no members fall under (none)).

Security Features

Confirmation System

All destructive operations require explicit confirmation:

# First call - shows warning
delete_vm(vm_id="MyServer", confirm=False)
# Returns: DESTRUCTIVE OPERATION: Delete VM MyServer...

# Second call - executes operation
delete_vm(vm_id="MyServer", confirm=True)
# Returns: VM MyServer deleted successfully

Bearer Token Authentication

Set MCP_AUTH_TOKEN to require Authorization: Bearer <token> on every request to /mcp. Requests with a missing or wrong token get 401. Leave the variable empty to disable authentication.

curl -X POST http://127.0.0.1:8000/mcp \
  -H "Authorization: Bearer $MCP_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}'

Disabling Tools

List tool names in DISABLED_TOOLS (comma-separated) to keep them from being registered at all: clients never see them in the tool list and cannot call them. Unknown names are reported on stderr at startup, so a typo does not silently leave a tool enabled.

Read-only deployment (every tool that changes vSphere state):

DISABLED_TOOLS=power_on_vm,power_off_vm,force_power_off_vm,bulk_power_operations,create_vm_snapshot,delete_vm_snapshot,revert_vm_snapshot,delete_vm,bulk_delete_vms,modify_vm_resources,clone_vm

Only block the destructive ones:

DISABLED_TOOLS=delete_vm,bulk_delete_vms,delete_vm_snapshot,revert_vm_snapshot,force_power_off_vm,modify_vm_resources,bulk_power_operations

Environment-Based Authentication

  • Credentials stored in environment variables
  • No hardcoded passwords
  • Secure Docker deployment
  • SSL/TLS support with configurable verification

Usage Examples

Basic VM Operations

# List all VMs
"Show me all virtual machines"

# Get VM details
"Get details for VM WebServer01"

# Power operations
"Power on the VM DatabaseServer"

Monitoring and Reporting

# Performance monitoring
"Show me CPU and memory usage for all VMs"
"Which VMs have high resource usage?"

# Storage monitoring
"Show me datastore usage"
"Which VMs have disk usage over 90%?"

# Comprehensive reporting
"Generate a complete report of the vSphere environment"

Snapshot Management

# Create snapshots
"Create a snapshot of VM WebServer01 before updates"

# List snapshots
"Show me all snapshots for VM DatabaseServer"

# Revert to a snapshot (requires confirmation)
"Revert VM WebServer01 to snapshot 'before-upgrade'"
# -> shows warning, no action
"Revert VM WebServer01 to snapshot 'before-upgrade' with confirmation"
# -> VM is powered off first (if running), then reverted; stays powered off

revert_vm_snapshot behaviour:

  1. Without confirm=True it only returns a warning and touches nothing.
  2. A running or suspended VM is powered off first; if powering off fails the revert is aborted.
  3. The revert uses suppressPowerOn=True, so the VM is left powered off afterwards and must be powered on manually.

Destructive Operations (with confirmation)

# VM deletion (requires confirmation)
"Delete VM TestServer"  # Shows warning
"Delete VM TestServer with confirmation"  # Executes deletion

# Resource modification (requires confirmation)
"Modify VM WebServer01 to have 8 CPUs and 16GB RAM with confirmation"

# Bulk operations (requires confirmation)
"Delete VMs: OldServer1, OldServer2, OldServer3 with confirmation"

Development

Build and run locally

docker build -t vsphere-mcp-server .
docker compose up -d

Dependency pinning

mcp==1.14.1 requires pydantic._internal._typing_extra.eval_type_backport, which was removed in pydantic 2.14. Keep pydantic pinned to 2.13.x in requirements.txt, otherwise the server fails at import time.

Container checks

# Import sanity check (also used by CI)
docker run --rm vsphere-mcp-server:ci python -c "from vsphere_mcp_server import server"