Disclaimer: This is a community-maintained open-source project and is not affiliated with, endorsed by, or sponsored by VMware, Inc. or Broadcom Inc. "VMware" and "vSphere" are trademarks of Broadcom. Source code is publicly auditable at github.com/vmware-skills/VMware-VKS under the MIT license.
AI-powered VMware vSphere Kubernetes Service (VKS) management — 24 MCP tools.
Requires vSphere 8.x+ with Workload Management enabled. Companion skills: vmware-aiops (VM lifecycle), vmware-monitor (monitoring), vmware-storage (storage), vmware-nsx (NSX networking), vmware-nsx-security (DFW/firewall), vmware-aria (metrics/alerts/capacity), vmware-avi (AVI/ALB/AKO), vmware-harden (compliance baselines). | vmware-pilot (workflow orchestration) | vmware-policy (audit/policy)
CategoryCapabilitiesCountSupervisorCompatibility check, status, storage policies3NamespaceList, get, create with quotas, update, delete with TKC guard, VM classes6TKC ClustersList, get, versions, create, scale, upgrade, delete with workload guard7VM ServiceVM snapshots, VM groups + bootOrder, VM multi-NIC readout (vm-operator CRDs, read-only)3AccessSupervisor kubeconfig, TKC kubeconfig, Harbor registry, storage usage4PermissionsWhich account is in use and whether it holds each tool's vSphere privileges (read-only)1
bash
uv tool install vmware-vks==3.3.1
vmware-vks check
Use companion skills for:
vmware-aiopsvmware-monitorvmware-storagevmware-aviUser IntentRecommended SkillRead-only monitoringvmware-monitorStorage: iSCSI, vSANvmware-storageVM lifecycle, deploymentvmware-aiopsvSphere Kubernetes Service (vSphere 8.x+)vmware-vks ← this skillNSX networking: segments, gateways, NATvmware-nsxNSX security: DFW rules, security groupsvmware-nsx-securityAria Ops: metrics, alerts, capacity planningvmware-ariaMulti-step workflows with approvalvmware-pilotCompliance baselines (CIS / 等保 / PCI-DSS), drift detection, LLM remediation advisorvmware-harden ( uv tool install vmware-harden)Load balancer, AVI, ALB, AKO, Ingressvmware-avi ( uv tool install vmware-avi)Audit log queryvmware-policy ( vmware-audit CLI)
Pre-flight (judgment):
supervisor check returns pass/fail. If fail, no amount of TKC commands will work; resolve at vSphere/WCP layer first.access-info --tool create_namespace checks the vSphere side; TKC calls are decided by the namespace's view/edit permission, which it does not check.best-effort-* for dev, guaranteed-* for prod. A best-effort worker can be evicted under host pressure — production workloads need guaranteed.list_supervisor_storage_policies first and pass the returned policy ID (not the display name); creating a TKC against a missing policy fails after CP boot, leaving partial state.1 for dev, 3 for prod (HA). Cannot upgrade from 1→3 without recreating; choose right the first time.cluster.x-k8s.io/v1 when the Supervisor serves it, falls back to v1beta1 on vSphere 8.0). No manual selection needed; advanced callers can override via the api_version parameter on generate_tkc_yaml().Steps:
vmware-vks supervisor check --target prod → must passvmware-vks tkc versions -n <ns> → pick a non-EOL TKRvmware-vks namespace create dev --storage-policy <policy> --cpu <enough-for-cp+workers> (a dry run by default), then the same with --applyvmware-vks tkc create dev-cluster -n dev --version <tkr> --control-plane 1 --workers 3 --vm-class best-effort-large (a dry run by default), then the same with --applyphase=running (typically 10-15 min); do not assume success on apply returnvmware-vks kubeconfig get dev-cluster -n dev -o ./kubeconfig — writes an owner-only file; report the path, never paste the token into the agent contextJudgment: scaling is fast but reverse-scaling is destructive — workers are deleted, in-flight pods lost. Treat scale-down like a delete.
tkc get dev-cluster -n dev → record current worker count and any pending podstkc scale dev-cluster -n dev --workers 6 → safe, additive operationReady in kubectl get nodes before sending traffickubectl drain on the to-be-deleted nodes, THEN tkc scale --workers 3. Skipping drain causes pod restarts on remaining nodes — measurable user impact.Judgment: quota changes are atomic but consequences are not. Reducing quota below current usage doesn't evict pods — they keep running, but no new pods schedule, looking like a "namespace is broken" symptom.
namespace list → see all namespaces and their phasestorage -n dev → check current CPU/memory/storage usage; never reduce quota below current usage + 20% headroomnamespace update dev --cpu <new> --memory <new> --dry-run → preview, then realInsufficient cpu, quota is still the bottlenecktext
User (Natural Language)
↓
AI Agent (Claude Code / Goose / Cursor)
↓ reads SKILL.md
↓
vmware-vks CLI ─── or ─── vmware-vks MCP Server (stdio)
│
├─ Layer 1: pyVmomi → vCenter REST API
│ Supervisor status, storage policies, Namespace CRUD, VM classes, Harbor
│
└─ Layer 2: kubernetes client → Supervisor K8s API endpoint
TKC CR apply / get / delete (cluster.x-k8s.io/v1beta1)
Kubeconfig bearer token from POST /wcp/login (Supervisor JWT)
↓
vCenter Server 8.x+ (Workload Management enabled)
↓
Supervisor Cluster → vSphere Namespaces → TanzuKubernetesCluster
ScenarioRecommendedWhyLocal/small models (Ollama, Qwen)CLI~2K tokens vs ~8K for MCPCloud models (Claude, GPT-4o)EitherMCP gives structured JSON I/OAutomated pipelinesMCPType-safe parameters, structured output
All accept optional target parameter to specify a named vCenter.
list_namespaces, list_supervisor_storage_policies and list_vm_classes return the family
list envelope — {items, returned, limit, total, truncated, hint} — rather than a bare array.
Read the rows from items; truncated says whether the listing is complete, so it never has
to be guessed from the row count. These three read their collection in one un-paged call, so
total is the real count and truncated is always false.
CategoryToolTypeSupervisorcheck_vks_compatibilityReadget_supervisor_statusReadlist_supervisor_storage_policiesReadNamespacelist_namespacesReadget_namespaceReadcreate_namespaceWriteupdate_namespaceWritedelete_namespaceWritelist_vm_classesReadTKClist_tkc_clustersReadget_tkc_clusterReadget_tkc_available_versionsReadcreate_tkc_clusterWritescale_tkc_clusterWriteupgrade_tkc_clusterWritedelete_tkc_clusterWriteVM Servicelist_vm_service_snapshotsReadlist_vm_service_groupsReadlist_vm_service_network_interfacesReadAccessissue_supervisor_kubeconfigWrite (credential)issue_tkc_kubeconfigWrite (credential)get_harbor_infoReadlist_namespace_storage_usageReadPermissionsget_access_infoRead
create_namespace, create_tkc_cluster, delete_namespace, delete_tkc_cluster take confirm (default False). Without it they change nothing and return blast_radius: the spec or YAML plan to be created, or what a delete destroys (TKC clusters, VMs and PVCs in the namespace; node counts and running workloads of a cluster). Show it to the user; pass confirm=True only after they decide on what they saw.
confirm=True is refused while a blocker stands — TKC clusters inside a namespace, running workloads in a cluster (unless force=True), a name already taken — or when any part of the blast radius could not be read. confirmed and dry_run are deprecated aliases until the next minor release.
Credential access: issue_supervisor_kubeconfig and issue_tkc_kubeconfig are not reads. The kubeconfig embeds a Supervisor bearer token (JWT from /wcp/login) that acts as the configured vCenter account until it expires — typically hours, and not revoked when vmware-vks exits. So:
readOnlyHint: false (MCP clients ask first) and risk_level: medium (so an operator's min_risk_level: medium deny rule covers them).output_path (MCP) or -o <path> (CLI) and report only the path. The file is created owner-only (0600) — also when it replaces an existing file — and a symlink target is refused. Delete it when no longer needed.sensitive_result=True).Full capability details and safety features: see
references/capabilities.md
bash
# Supervisor
vmware-vks check [--config <path>]
vmware-vks preflight-auth [--target <name>] # live-validate POST /wcp/login (issue #13)
vmware-vks access-info [--tool <name>] [--target <name>] # what may this account do?
vmware-vks supervisor status <cluster-id> [--target <name>]
vmware-vks supervisor storage-policies [--target <name>]
# Namespace
vmware-vks namespace list [--target <name>]
vmware-vks namespace get <name> [--target <name>]
vmware-vks namespace create <name> --cluster <id> [--cpu <n>] [--memory <mb>] [--storage-policy <name>] [--apply]
vmware-vks namespace update <name> [--cpu <n>] [--memory <mb>] [--target <name>]
vmware-vks namespace delete <name> [--target <name>]
# TKC Clusters
vmware-vks tkc list [-n <namespace>] [--target <name>]
vmware-vks tkc create <name> -n <ns> [--version <v>] [--workers <n>] [--vm-class <name>] [--apply]
vmware-vks tkc scale <name> -n <ns> --workers <n> [--pool <name>] [--target <name>]
vmware-vks tkc upgrade <name> -n <ns> --version <v> [--target <name>]
vmware-vks tkc delete <name> -n <ns> [--skip-workload-check] [--target <name>]
# Kubeconfig
vmware-vks kubeconfig supervisor -n <namespace> [-o <path>] [--target <name>]
vmware-vks kubeconfig get <cluster-name> -n <namespace> [-o <path>] [--target <name>]
# Harbor & Storage
vmware-vks harbor [--target <name>]
vmware-vks storage -n <namespace> [--target <name>]
Full CLI reference with all flags and interactive creation: see
references/cli-reference.md
Workload Management must be enabled in vCenter. Check: vCenter UI → Workload Management. Requires vSphere 8.x+ with Enterprise Plus or VCF license.
The password is right. Either the session expired (run the command again; a new session is opened) or the account has no vSphere role, so vCenter shows no session for it and every call fails. VKS does not refuse such a login when it connects, because an account holding only Supervisor namespace permissions can look the same and still work; the error appears on the first call that needs a role. Assign the account a role (Read-Only or higher) on the vCenter root folder under Administration > Access Control > Global Permissions; Namespace and TKC work also needs Workload Management privileges.
List policies first: vmware-vks supervisor storage-policies, then pass the Policy ID column value (not the display name) as --storage-policy.
Check Supervisor events in vCenter. Common causes: insufficient resources on ESXi hosts, network issues with NSX-T, or storage policy not available on target datastore.
vCenter keeps two independent session stores, and this skill uses both. Namespace, storage-policy and Supervisor-status tools call the vSphere Automation REST API under /api, which authenticates with a session id from POST https://<vcenter>/api/session (HTTP Basic on that one call, then the id in a vmware-api-session-id header). The pyVmomi SOAP session under /sdk is a different store and its key is rejected there — sending it produced a 401 on every REST tool. A 401 is refreshed automatically once; if it persists, check whether a proxy between you and vCenter strips the vmware-api-session-id header. A 403, not a 401, is what an account short of Workload Management permissions gets.
Supervisor/TKC Kubernetes auth uses a JWT obtained from POST https://<supervisor>/wcp/login (HTTP Basic → JSON session_id bearer token), not the pyVmomi SOAP session key, and not the /api/session id above either — three separate credentials. To validate this end-to-end against your real Supervisor, run:
bash
vmware-vks preflight-auth [--target <name>]
It performs the real login (no mocks) and reports, per target: vCenter reachable → /wcp/login HTTP status → parseable session_id → does the JWT authenticate a trivial Supervisor K8s API call. A healthy result is all four steps ✓ PASS ending in target '<name>': /wcp/login auth flow validated end-to-end. (exit code 0). The login goes to the Supervisor API endpoint vCenter publishes, or to supervisor_host when that target sets it (vCenter itself answers 404 for /wcp/login on 9.1). On failure each step prints a teaching message — e.g. a 404 on /wcp/login means the wrong host (set supervisor_host) or an endpoint path that differs on your Supervisor version, a 401 on the K8s probe means session_id is not the bearer token on your version. It never tracebacks — every failure is status output.
Supervisor API endpoint must be reachable from the machine running vmware-vks. Check firewall rules for port 6443.
Verify the cluster is in "Running" phase before scaling. Clusters in "Creating" or "Updating" phase reject scale operations.
The namespace delete guard prevents deletion when TKC clusters exist inside. Delete all TKC clusters in the namespace first, then retry.
bash
uv tool install vmware-vks==3.3.1
mkdir -p ~/.vmware-vks
vmware-vks init
All tools are automatically audited via vmware-policy. Audit logs:
vmware-audit log --last 20
Full setup guide, security details, and AI platform compatibility: see
references/setup-guide.md
Operations are audited via vmware-policy:
@guarded writes and credential reads, @audited reads), is logged to ~/.vmware/audit.db (SQLite). The seven namespace/TKC write operations are also mirrored to ~/.vmware-vks/audit.log (JSON Lines)~/.vmware/rules.yaml (deny rules, maintenance windows, risk levels)vmware-audit log --last 20vmware-audit log --status deniedLocal files (sensitive, keep owner-only): ~/.vmware-vks/.env holds per-target passwords (b64-obfuscated, not encrypted; created 0600, vmware-vks doctor flags a wider mode). ~/.vmware/audit.db (+ WAL/SHM, 0600 in a 0700 directory) keeps operation history — resource names, parameters, results with credentials redacted — and rotates at 100 MB, keeping 5 archives. ~/.vmware-vks/audit.log (0600) is never rotated or pruned. Exported kubeconfigs are 0600 and are never cleaned up by the skill. Delete or rotate these yourself per your retention policy.
In-memory kubeconfig (v1.5.18+): for its own API calls the skill builds the Supervisor/TKC kubeconfig as a Python dict and loads it with load_kube_config_from_dict(); the bearer token (also cached in process memory, up to 8 h) is never written to a temp file. Only an explicit export ( output_path / -o) puts it on disk.
vmware-policy is automatically installed as a dependency — no manual setup needed.