vcf-mcp
Provides tools for interacting with VMware Cloud Foundation 9.1 APIs, enabling agents to search, describe, validate, call, and monitor operations across SDDC Manager, vCenter, NSX, Avi Load Balancer, VCF Operations, and vSAN Data Protection.
Click on "Install 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., "@vcf-mcplist all hosts in the SDDC and their states"
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.
vcf-mcp
An MCP server that gives an LLM agent full API access to a VMware Cloud Foundation 9.1 estate.
It connects to seven appliances — SDDC Manager, VCF Installer, vCenter, NSX, Avi Load Balancer, VCF Operations and vSAN Data Protection — and exposes their 8,931 API operations through eight tools. It handles authentication for each appliance, resolves request paths, follows async tasks, and records every mutating call.
It speaks MCP over stdio, so it works with any MCP client: Claude Code, Claude Desktop, Cursor, Windsurf, Zed, Continue, or your own agent built on an MCP SDK. There is nothing to install — point a client at:
uvx --from git+https://github.com/NiranEC77/vcf-mcp vcf-mcpContents
How it works · Install · Configure · Connect an agent · Tools · Targets · Environment variables · Write safety · Tests · VCF 9.1 behaviour
Related MCP server: vlp-mcp-agent
How it works
One tool per endpoint does not scale. 8,931 tool schemas would exhaust the context window before the agent asked its first question, and tool selection degrades badly past a few dozen options.
Instead, the OpenAPI specs are indexed once at startup into a compact record per operation (method, path, summary, operationId, tags). The agent then works the way an engineer does — search, read the schema, dry-run, execute, follow the task:
vcf_search_api("commission hosts") -> POST /v1/hosts (commissionHosts)
vcf_describe_api(operation_id=...) -> required fields, types, responses
vcf_validate(target, path, body) -> dry-runs the spec, changes nothing
vcf_call(target, method, path, body) -> executes it, auth handled
vcf_task(target, task_id) -> follows the async resultContext cost stays fixed however many operations exist. Adding an appliance means adding a spec file and a registry entry, not a new tool.
Authentication is per-appliance and automatic. Each target has its own scheme (see Targets); the server mints a token on first use, caches it in memory for the process lifetime, never writes it to disk, and re-mints it automatically on a 401/403.
Spec handling. Both dialects are parsed: OpenAPI 3.x (SDDC Manager,
Installer, Operations, vCenter) and Swagger 2.0 (NSX). Base paths differ per
spec — /suite-api for Operations, /api for vCenter, /policy/api/v1 for
NSX policy — and are resolved at index time, so paths returned by search are
real request paths you can pass straight to vcf_call.
Install
Requires network access to the appliances. Nothing else — uvx fetches,
builds and runs the server in one step, and the API specs ship inside the
package, so there is no separate download:
uvx --from git+https://github.com/NiranEC77/vcf-mcp vcf-mcp checkThat is also the command an MCP client should launch (see
Connect an agent). uvx comes with
uv; install it with
curl -LsSf https://astral.sh/uv/install.sh | sh.
To install it as a normal command instead:
uv tool install git+https://github.com/NiranEC77/vcf-mcp # then: vcf-mcp
pipx install git+https://github.com/NiranEC77/vcf-mcp # same, via pipx
pip install git+https://github.com/NiranEC77/vcf-mcp # into a venvOr work from a clone (Python 3.10+):
git clone https://github.com/NiranEC77/vcf-mcp.git && cd vcf-mcp
uv venv --python 3.12 && uv pip install -e .A clone keeps its config and logs in the repo directory; an installed copy
uses ~/.config/vcf-mcp/ and ~/.local/state/vcf-mcp/. Either way the
environment variables below override both.
Configure
1. Appliance addresses
No addresses are stored in this repo. Create a hosts.json — in
~/.config/vcf-mcp/ for an installed copy, or the repo root for a clone
(where it is gitignored), or anywhere if you set VCF_MCP_HOSTS_FILE:
{
"hosts": {
"sddc": "sddc-manager.example.local",
"installer": "vcf-installer.example.local",
"vcenter": "vcenter.example.local",
"nsx": "nsx-vip.example.local",
"ops": "vcf-ops.example.local",
"avi": "avi-controller.example.local",
"vsan-dp": "vcenter.example.local"
}
}Any target can instead be set with VCF_MCP_<TARGET>_HOST, which wins over the
file. vsan-dp is served by the vCenter appliance, so it takes the same
address as vcenter. Targets you leave out are reported as unconfigured by
vcf_targets rather than called.
2. Credentials
Passwords are read from a .env file — point VCF_MCP_ENV_FILE at whichever
file is already your rotation point, or create one next to hosts.json:
NSX_ADMIN_PASSWORD=...
SDDC_MANAGER_PASSWORD=...
VCF_INSTALLER_PASSWORD=...
NESTED_VCSA_PASSWORD=...
VCF_APPLIANCE_PASSWORD=...Each target tries its own ordered subset of these keys; empty values and
anything containing CHANGEME are skipped. A single target can be overridden
with VCF_MCP_<TARGET>_PASSWORD. Nothing is copied into the repo, and no tool
ever returns a secret — failures name the key they looked for, never a value.
Authentication is capped at 3 attempts per target
(config.MAX_AUTH_ATTEMPTS). vSphere SSO locks accounts after repeated
failures, so trying every password in the file is not a harmless fallback.
Avi has no standing credential anywhere. Its admin password is
VCF-generated and lives only in SDDC Manager's credential store. The server
fetches it at auth time (GET /v1/credentials, resourceType NSX_ALB), uses
it to log in, and never returns, logs or persists it. Set
VCF_MCP_AVI_PASSWORD to override this for a controller VCF does not manage.
Avi rejects HTTP Basic outright — only the session flow works.
3. Verify
vcf-mcp index # index all operations (~8s, then cached to disk)
vcf-mcp check # print every target and whether it answersPrefix with uvx --from git+https://github.com/NiranEC77/vcf-mcp if you have
not installed it. check names any target whose address is still unset.
Connect an agent
The server is a stdio process: run vcf-mcp with no arguments (equivalently,
python -m vcf_mcp) and it speaks MCP on stdin/stdout.
Any MCP client
Most clients read the same JSON shape. Add this to the client's MCP config —
no prior install needed, uvx handles it:
{
"mcpServers": {
"vcf": {
"command": "uvx",
"args": ["--from", "git+https://github.com/NiranEC77/vcf-mcp", "vcf-mcp"],
"env": {
"VCF_MCP_HOSTS_FILE": "/absolute/path/to/hosts.json",
"VCF_MCP_ENV_FILE": "/absolute/path/to/your/.env"
}
}
}
}If you installed it already, replace those two fields with
"command": "vcf-mcp" (or the absolute path to the executable, which some
clients require because they do not inherit your shell's PATH).
.mcp.example.json in this repo is that file, ready to copy. Where each client
keeps its config:
Client | Config location |
Claude Code |
|
Claude Desktop |
|
Cursor |
|
Windsurf |
|
Zed |
|
Continue |
|
Claude Code
claude mcp add vcf \
--env VCF_MCP_HOSTS_FILE=/absolute/path/to/hosts.json \
--env VCF_MCP_ENV_FILE=/absolute/path/to/your/.env \
-- uvx --from git+https://github.com/NiranEC77/vcf-mcp vcf-mcpYour own agent
Any MCP SDK can launch it as a subprocess. With the Python SDK:
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
params = StdioServerParameters(
command="uvx",
args=["--from", "git+https://github.com/NiranEC77/vcf-mcp", "vcf-mcp"],
env={"VCF_MCP_HOSTS_FILE": "/absolute/path/to/hosts.json"},
)
async with stdio_client(params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool("vcf_search_api", {"query": "commission hosts"})The server advertises read_only and destructive annotations per tool, so a
client that gates writes can do so without a hardcoded tool list.
Tools
Tool | Arguments | Returns |
|
| Every appliance: name, product, address, auth scheme, operation count, whether it answers |
|
| Ranked operations with method, full path, summary, operationId |
|
| Path/query parameters, resolved request body schema with required fields, response schemas |
|
|
|
|
| Status and response body; task id for async operations |
|
| Task status and, on failure, which subtask failed and why |
|
| Domains, clusters, hosts, gateways and alerts in one snapshot |
|
| Recent mutating calls made through this server |
vcf_call is annotated as destructive; every other tool is annotated read-only.
Typical sequence for a change: vcf_search_api → vcf_describe_api →
vcf_validate → vcf_call → vcf_task.
Targets
Target | Product | Authentication | Operations |
| SDDC Manager |
| 500 |
| VCF Installer |
| 57 |
| vCenter Server |
| 1,367 |
| NSX Manager (VIP) | HTTP Basic | 5,182 |
| Avi Load Balancer (NSX ALB) |
| 1,233 |
| VCF Operations |
| 527 |
| vSAN Data Protection | vCenter session | 65 |
Every scheme above was verified against a live 9.1 estate.
Environment variables
Variable | Effect |
Defaults differ between a clone and an installed copy, as noted: |
Variable | Effect | Default (clone → installed) |
| Path to the addresses file |
|
| Override one address, e.g. | — |
| Path to the credentials |
|
| Override one target's password, e.g. | — |
| Installer's generated credentials file | alongside the |
| Enforce TLS verification | off — appliances present self-signed certs |
| Where mutations are recorded |
|
| Spec source directory |
|
| Index cache directory |
|
Write safety
There is no write gate. Any operation the API allows — including
DELETE /v1/domains/{id} and host decommission — executes immediately when the
agent calls it. This is deliberate: the server does not try to second-guess
which operations are safe.
What exists instead is a record. Every POST/PATCH/PUT/DELETE is appended to
logs/vcf-mcp-audit.jsonl with target, path, status, duration and a
redacted body — anything keyed like a password, token, secret or credential
is replaced before the line is written. vcf_audit reads it back, including
changes made by earlier sessions.
If you want a gate, client.request() is the single chokepoint that every call
in the server passes through.
Tests
.venv/bin/python -m pytest tests/ -q36 offline tests, no appliance required. Each pins a bug found during the
build: camelCase tokenisation, plural stemming, $ref cycle handling,
truncation across differently-named collections, secret redaction, task-id
detection, case-insensitive task states, and the rule that no appliance address
is ever hardcoded into the registry.
Specs
Vendored from vmware/vcf-api-specs
at commit 3949fc3 (2026-05-13), version 9.1.0.0. Provenance in
specs/SPECS-PROVENANCE.txt.
The 170 Avi object specs in specs/avi/ were downloaded from an Avi
controller's own swagger endpoint (/swagger/<Object>.yaml), so they are
version-matched to the deployed build by construction. Avi's per-object files
re-declare related objects' paths; the index deduplicates them and keeps the
declaration from the file named after the resource.
VCF 9.1 behaviour
Discovered while building against a live estate, and encoded in the server:
POST /v1/system/prechecksis gone; the replacement isPOST /v1/system/health-summary(startHealthCheck).The whole
/v1/edge-clustersfamily on SDDC Manager is deprecated, includingupdateEdgeCluster(PATCH /v1/edge-clusters/{id}).Deprecated operations are hidden from search unless
include_deprecatedis set. Well-scoring ones are still reported underhidden_deprecated, so a legacy path found in old documentation is identified as legacy rather than appearing not to exist.SDDC Manager returns task status as
"Successful", not"SUCCESSFUL";vcf_taskcompares case-insensitively.vCenter (vAPI) specs declare enums as prose ("Possible values: ...").
vcf_describe_apilifts them into a realenumlist.NSX often has the strictest password complexity rules of the fleet, so an estate is frequently built with one password NSX accepts.
NSX_ADMIN_PASSWORDis therefore tried first for several targets.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-qualityCmaintenanceA comprehensive MCP server for VMware vSphere management, enabling AI agents to perform VM operations, monitoring, snapshots, and reporting through a secure, Dockerized environment.19
- Flicense-qualityCmaintenanceMCP server for automating VLP lab VM operations, exposing VM management tools to AI agents like Cursor and Claude Code.
- AlicenseBqualityAmaintenanceAn MCP server that enables Claude and other LLM agents to manage and monitor Pexip Infinity deployments through natural language, with 122 tools for configuration, status, history, and command operations.761MIT
- Alicense-qualityBmaintenanceAn MCP server that gives an LLM full control over a VMware-hosted Windows VM: lifecycle, snapshots, remote execution, file transfer, and kernel debugging.MIT
Related MCP Connectors
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
MCP server providing access to the Scorecard API to evaluate and optimize LLM systems.
MCP server exposing the Backtest360 engine API as tools for AI agents.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/NiranEC77/vcf-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server