VMware Storage
Author: Wei Zhou, VMware by Broadcom — wei-wz.zhou@broadcom.com This is a community-driven project by a VMware engineer, not an official VMware product. For official VMware developer tools see developer.broadcom.com.
VMware vSphere storage management: datastores, iSCSI, vSAN, and read-only Fibre Channel / multipath diagnostics — 15 MCP tools, domain-focused and lightweight.
Split from vmware-aiops for lighter context and local model compatibility.
Upgrading to 2.0
2.0 renames 10 of its MCP tools (all but the four that already started with a verb) so every name starts with a verb (e.g. fc_adapter_list → list_fc_adapters, storage_device_paths → list_storage_device_paths, storage_iscsi_add_target → add_iscsi_target). The full old → new table is in
RELEASE_NOTES.md. Three tools also change a parameter: browse_datastore and scan_datastore_images take
datastore_name (was ds_name, now the same as vmware-aiops' browse_datastore), and list_all_datastores gains an
optional limit (same as vmware-monitor's). Everything else stays: same tools, safety gates and CLI commands (the CLI
still takes the datastore name as before). If an agent prompt, script or ~/.vmware/rules.yaml names a tool, update it — though deny
rules written with the old names keep working with vmware-policy ≥ 1.18 (vmware-audit policy lists any rule the
renames widened), and vmware-pilot ≥ 1.13 translates old names in saved workflows.
If an install older than 2.0 shares that rules.yaml, give it vmware-policy ≥ 1.18.2 too: it matches each rule
against both the old and the new name, so one file serves both.
Companion Skills
| Skill | Scope | Tools | Install |
|---|---|---|---|
| vmware-aiops ⭐ entry point | VM lifecycle, deployment, guest ops, clusters | 49 | uv tool install vmware-aiops |
| vmware-monitor | Read-only monitoring, alarms, events, VM info | 27 | uv tool install vmware-monitor |
| vmware-vks | Tanzu Namespaces, TKC cluster lifecycle | 20 | uv tool install vmware-vks |
| vmware-nsx | NSX networking: segments, gateways, NAT, IPAM | 33 | uv tool install vmware-nsx-mgmt |
| vmware-nsx-security | DFW microsegmentation, security groups, Traceflow | 21 | uv tool install vmware-nsx-security |
| vmware-aria | Aria Ops metrics, alerts, capacity planning | 28 | uv tool install vmware-aria |
Quick Install
# Via PyPI
uv tool install vmware-storage
# Or pip
pip install vmware-storage
Offline / Air-Gapped Install (from source)
This project uses the modern PEP 517 build system (hatchling), so there is no
setup.py by design — that is expected, not a missing file. If you cloned the
source and hit ERROR: File "setup.py" or "setup.cfg" not found ... editable mode currently requires a setuptools-based build, your pip is older than 21.3 and
cannot do an editable (-e) install with a non-setuptools backend. Editable
mode is a developer convenience, not needed to run the tool — do one of:
# From the source tree — a normal (non-editable) install builds a wheel:
pip install . # NOT pip install -e .
# ...or upgrade pip first, and editable works too:
pip install --upgrade pip && pip install -e .
For a truly air-gapped host, build the wheels on a connected machine and copy them over — the target then needs no network:
# On a connected machine, collect this package + its dependencies as wheels:
pip wheel . -w dist # → dist/*.whl (or: uv build, for just this package)
# Copy dist/ to the air-gapped host, then install offline:
pip install --no-index --find-links dist vmware-storage
Configuration
mkdir -p ~/.vmware-storage
cp config.example.yaml ~/.vmware-storage/config.yaml
# Edit with your vCenter/ESXi credentials
echo "VMWARE_MY_VCENTER_PASSWORD=your_password" > ~/.vmware-storage/.env
chmod 600 ~/.vmware-storage/.env
# Verify
vmware-storage doctor
MCP Tools (15)
| Category | Tools | Type |
|---|---|---|
| Datastore | list_all_datastores, browse_datastore, scan_datastore_images, list_cached_images |
Read |
| iSCSI | enable_iscsi, get_iscsi_status, add_iscsi_target, remove_iscsi_target, rescan_storage |
Read/Write |
| vSAN | get_vsan_health, get_vsan_capacity, get_vsan_efficiency |
Read |
| FC / multipath | list_fc_adapters, list_storage_device_paths |
Read |
| Access | get_access_info — which account the server uses and whether it holds each tool's vSphere privileges (root folder) |
Read |
Auto-Remediation Patterns (PoC)
The patterns/ directory hosts L5 auto-remediation candidate patterns from the Enterprise Harness Engineering framework. The first PoC pattern, patterns/iscsi-target-stale-rescan.yaml, describes an iSCSI HBA rescan as a low-risk, reversible, repeatable operation. The pattern schema is documented here only — runtime enforcement is not yet wired up, so this is a reference design, not production auto-remediation.
Common Workflows
Set Up iSCSI Storage on a Host
- Enable iSCSI adapter:
vmware-storage iscsi enable esxi-01 - Add target:
vmware-storage iscsi add-target esxi-01 10.0.0.100 - Verify:
vmware-storage iscsi status esxi-01
The add-target command automatically rescans storage. Use --dry-run to preview any write command first.
Find Deployable Images Across Datastores
- List all datastores:
vmware-storage datastore list - Scan for images:
vmware-storage datastore scan-images datastore01 - Browse with a pattern:
vmware-storage datastore browse datastore01 --pattern "*.iso"
vSAN Health Assessment
- Check health:
vmware-storage vsan health Cluster-Prod - Check capacity:
vmware-storage vsan capacity Cluster-Prod - If issues found, investigate with
vmware-monitorfor alarms and events
Check Fibre Channel Paths
- Dead or disabled paths behind a datastore:
vmware-storage paths devices --datastore ds-fc-01 - Hosts that see a shared device through a different number of paths than their peers, or not at all:
vmware-storage paths devices --cluster Cluster-Prod --only-differences - WWPNs for the SAN team:
vmware-storage paths fc-adapters --cluster Cluster-Prod
Hosts that could not be read are listed in hosts_not_read and are never reported as missing a device. Path states are reported as vSphere reports them — standby is not flagged.
CLI
# Datastore
vmware-storage datastore list
vmware-storage datastore browse datastore01
vmware-storage datastore scan-images datastore01
# iSCSI
vmware-storage iscsi status esxi-01
vmware-storage iscsi enable esxi-01
vmware-storage iscsi add-target esxi-01 192.168.1.100
vmware-storage iscsi remove-target esxi-01 192.168.1.100
vmware-storage iscsi rescan esxi-01
# vSAN
vmware-storage vsan health Cluster-Prod
vmware-storage vsan capacity Cluster-Prod
# Fibre Channel / multipath (read-only)
vmware-storage paths fc-adapters --cluster Cluster-Prod
vmware-storage paths devices --datastore ds-fc-01
# Diagnostics
vmware-storage doctor
MCP Server
After uv tool install vmware-storage, start the MCP server with one command (v1.5.15+):
# Recommended — single command, no network re-resolve
vmware-storage mcp
# With a custom config path
VMWARE_STORAGE_CONFIG=/path/to/config.yaml vmware-storage mcp
# Or via Docker
docker compose up -d
Agent Configuration
Add to your AI agent's MCP config:
{
"mcpServers": {
"vmware-storage": {
"command": "vmware-storage",
"args": ["mcp"],
"env": {
"VMWARE_STORAGE_CONFIG": "~/.vmware-storage/config.yaml"
}
}
}
}
Alternative: uvx (no install) or legacy entry point
# Run without installing (requires PyPI access each launch)
uvx --from vmware-storage vmware-storage mcp
# Legacy entry point (still works, kept for backward compatibility)
vmware-storage-mcp
Behind a corporate TLS proxy? uvx may fail with
invalid peer certificate: UnknownIssuer. Use the recommendedvmware-storage mcpform above (no network needed), or setUV_NATIVE_TLS=true.
Why a Separate Skill?
vmware-aiops has 61 MCP tools — too heavy for local LLMs (7B-14B). By splitting storage into its own skill:
- 15 tools — fits comfortably in small model context windows
- Domain-focused — storage admins get only what they need
- Least privilege — can run under a vCenter service account with storage read-only permissions
- Composable — use alongside vmware-monitor or vmware-aiops as needed
Version Compatibility
Python: 3.10+ (since v1.5.27 — previously 3.11+). Tested on 3.10 / 3.11 / 3.12.
| vSphere / VCF | Support | Notes |
|---|---|---|
| VCF 9.1 / vSphere 9.1 | Full | Released 2026-05-12. pyVmomi+vSAN SDK <10.0 works via SOAP. |
| VCF 9.0 / vSphere 9.0 | Full | pyVmomi 8.0.3+ with bundled vSAN SDK connects to vSphere 9. |
| 8.0 | Full | vSAN SDK built into pyVmomi 8.0.3+ |
| 7.0 | Full | All storage APIs work |
| 6.7 | Compatible | iSCSI + datastore features work; vSAN limited |
Official Broadcom References
- SDKs: https://developer.broadcom.com/sdks — VCF Python SDK, vSAN Management SDK (bundled in pyVmomi)
- REST APIs: https://developer.broadcom.com/xapis — vSAN Management API, VCF API
- CLI Tools: https://developer.broadcom.com/tools — PowerCLI 9.1, ESXCLI
Safety
| Feature | Description |
|---|---|
| Read-heavy | 11/15 tools are read-only |
| Preview by default (MCP) | The 4 write tools take confirm (default false): a call without it changes nothing and returns blast_radius (host, adapters, and for target removal the paths, devices and datastores behind the target). confirm=true is refused when a datastore would lose every path or part of the blast radius could not be read. dry_run is a deprecated alias |
| Input validation | IP addresses and ports validated before iSCSI operations |
| Audit logging | All operations logged to ~/.vmware-storage/audit.log |
| No VM operations | Cannot create, delete, or modify VMs |
| Credential safety | Passwords only from environment variables, never config files |
Troubleshooting
| Problem | Cause & Fix |
|---|---|
| iSCSI enable fails with "already enabled" | Not an error — adapter is already active. Run iscsi status to see configured targets. |
| "Datastore not found" when browsing | Datastore names are case-sensitive. Run datastore list to get the exact name. |
get_vsan_health returns overall_health: null |
null = not asked (see health_not_queried_reason), never a measurement; a string is always vSAN's own answer, including its own "unknown". Usual cause: connected to standalone ESXi, but the health service runs in vCenter. |
| Rescan doesn't discover new LUNs | Wait 15-30 seconds after adding targets, then rescan again. Verify target IP is reachable from ESXi. |
| "Password not found" error | Variable names follow VMWARE_<TARGET_UPPER>_PASSWORD (hyphens → underscores). Check ~/.vmware-storage/.env. |
doctor fails with "no vSphere role", or every command fails with "session is not authenticated" |
The login works but the account has no vSphere role. Assign one (Read-Only or higher) on the vCenter root folder (Administration > Access Control > Global Permissions). Mid-run, the same fault can be an expired session: run the command again. |
| Connection timeout to vCenter | Use vmware-storage doctor --skip-auth to bypass auth checks on high-latency networks. |
| "Datastore browse did not finish within Ns" | The datastore is very large or busy. Narrow the search with a sub-path and a specific pattern (e.g. datastore browse ds01 --path templates --pattern "*.ova") instead of browsing the root — do not just retry the same broad browse. |
Remote access (HTTPS) and limiting tools
By default vmware-storage mcp speaks stdio to one local client and offers every tool. Two options change that
(vmware-policy ≥ 1.21.0).
Serve over HTTPS so clients on other machines can connect. Every caller needs a bearer token:
vmware-audit token create alice # prints the token once; give it to alice
vmware-audit token list # names only
vmware-audit token revoke alice # refused from its next request, no restart
vmware-storage mcp --transport https --host 0.0.0.0 --port 8443 \
--cert /etc/vmware-mcp/server.pem --key /etc/vmware-mcp/server-key.pem \
--public-name mcp.example.com
Connect a client (Claude Code shown; any MCP client that supports streamable HTTP and custom headers works):
claude mcp add --transport http vmware-storage https://mcp.example.com:8443/mcp \
--header "Authorization: Bearer $VMWARE_MCP_TOKEN"
{
"mcpServers": {
"vmware-storage": {
"type": "http",
"url": "https://mcp.example.com:8443/mcp",
"headers": { "Authorization": "Bearer ${VMWARE_MCP_TOKEN}" }
}
}
}
- The server will not start without a token, refuses Host/Origin values outside
--public-name, and checks before it binds that unauthenticated requests get 401. Use a certificate your clients trust for those names. - Behind a TLS-terminating reverse proxy on the same machine use
--transport http --host 127.0.0.1 --public-name mcp.example.comand pass theAuthorizationheader through. - Behind a load balancer or gateway on another machine, keep
--transport https(a self-signed certificate is fine), list in--public-namethe host name the balancer sends asHost, and have it forwardAuthorization. Its health probe can useGET /healthz, which needs no token and returns only{"status": "ok"}(vmware-policy ≥ 1.23.0). - Send
traceparentorX-Request-IDwith each request to have it stored on the audit row;vmware-audit log --correlation-id IDthen finds the calls behind one platform request. - The audit log records each caller as
token:<name>. Calls run side by side, also on the same target: the server keeps up toVMWARE_MCP_POOL_SIZE(default 2) sessions per target, each one a login on that target, and a call waits at most 300 s for a free session (vmware-policy ≥ 1.22.0). - Everyone who can reach the endpoint acts with this server's account. Tokens identify callers; they grant
nothing on the platform. Run one endpoint per privilege level.
vmware-storage access-infoshows which account that is and what it may do.
Offer only read tools, plus the writes you choose:
vmware-storage mcp --expose read --allow-write enable_iscsi
# or: VMWARE_STORAGE_MCP_EXPOSE=read VMWARE_STORAGE_MCP_ALLOW_WRITE=enable_iscsi vmware-storage mcp
Tools not offered do not appear in the client's tool list. A bad value or an unknown write tool stops the server (exit 2). This limits what clients are offered; it is not authorization, so the account itself should be least-privilege.
Details: skills/vmware-storage/references/setup-guide.md ("Serving MCP over HTTPS", "Limiting which tools are offered").
License
Metadata
Release files for vmware-storage 2.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| vmware_storage-2.3.1.tar.gz | 331.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vmware_storage-2.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 414.3 kB
Release files / vmware_storage-2.3.1.tar.gz
| Download URL | vmware_storage-2.3.1.tar.gz |
|---|---|
| Size | 331.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
04291cff927ac7ba5ad87a3ea17309f68a6aa7b1868f805db726a2941fdfe3a8
|
|
BLAKE2b-256 checksum How to use checksums |
c8fc3f4248882adbcd7a53d44c4142d78b885a7eb6f1ed7c1352cd49d4a0c76e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|
Release files / vmware_storage-2.3.1-py3-none-any.whl
| Download URL | vmware_storage-2.3.1-py3-none-any.whl |
|---|---|
| Size | 82.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
71270158ae07b4ca791dd73b785b241b3e93b78e9cb365075fb2d206e0666927
|
|
BLAKE2b-256 checksum How to use checksums |
5b02889f1f33814b0e305592cecbb3939691a3e0c3a3b2b616d8e2e4ca59665b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|