Skip to content

Releases: vmware-skills/VMware-Monitor

v2.4.2 — an unreadable host is not down; a login refused for lack of a role says so (2026-10-19)

Choose a tag to compare

@zw008 zw008 released this 19 Oct 00:15

Found on a vCenter 8.0.3 lab with two restricted SSO accounts (follow-up to AIops#47).

  • A host this account cannot read is no longer reported as down. An account with Read-only on one VM sees that
    VM's host by name only: runtime.connectionState reads None. get_cluster_health_summary ranked it
    host_down / critical ("host None") and get_cross_vcenter_attention put it first. It is now counted in
    hosts_unreadable, raises a warning issue host_unreadable (ranked after a real outage), and moves the row to
    WARN (unknown is not OK either). Every surface shows "(N unreadable)": cluster card (amber, not red), totals strip,
    attention cards and totals, and the CLI lines.
  • get_ntp_status no longer calls an unreadable host unreachable. Instead of "vCenter cannot reach this host
    ... reconnect", the row has reachable: null, with hosts_unreadable and unreadable_note in the result.
    inventory hosts colours an unreadable state yellow, not red.
  • A login vCenter refuses with NoPermission gets the role error, not the raw fault. For an account with no
    permission anywhere, vCenter refuses the login itself (System.View on the root folder), so the 2.3.1 post-login
    check never ran and doctor/MCP showed the raw fault with a connectivity hint. It now raises the no-role error:
    the "no vSphere role / Global Permissions" remedy only for a vCenter target and System.View; an ESXi target or
    another privilege gets a neutral text naming the (sanitized) privilege. A wrong password (InvalidLogin) is
    unchanged.

v2.4.1 — fixes from real-hardware testing (2026-10-17)

Choose a tag to compare

@zw008 zw008 released this 17 Oct 14:07
  • get_vm_backup_snapshot_history on a standalone ESXi host answers instead of failing. Its error handler named
    vim.fault.InvalidArgument, a class pyVmomi does not have, so every call on ESXi ended in
    AttributeError: operation failed.. ESXi keeps no queryable task history; the tool now says so in
    history_unavailable and points at the vCenter that manages the host.
  • list_active_tasks with limit keeps the newest tasks. It kept the oldest (57 tasks, limit=40 dropped the 17
    newest). Running and queued tasks come first, then newest first.
  • get_datastore_capacity's view_note no longer blames a vCenter/ESXi gap on different VMs alone. On the test
    lab both listed the same 10 VMs and still reported different uncommitted space; the note now says how to tell the
    two cases apart (vm_count).
  • list_all_clusters rows carry the cluster moid (also a CLI column), the id the vLCM tools take and their
    errors send you to look up.
  • Error hints: doctor is suggested for connection, credential and proxy problems, not for a name that does not
    resolve or a bad argument. A reverse proxy answering HTML on the REST session call is named as such. Messages
    name MCP tools and parameters, with the CLI form in brackets.
  • Gate: every pyVmomi class named in an except clause or isinstance() must exist (family smoke).

v2.4.0 — roles for network callers (HLD §18)

Choose a tag to compare

@zw008 zw008 released this 16 Oct 07:25
  • Declares the role metadata vmware-policy ≥ 1.24.0 needs to apply roles to this server over HTTPS
    (HLD §18): how a missing target resolves. With an older vmware-policy nothing changes. Once an operator runs
    vmware-audit roles enable, a token's role decides which tools and targets it may use here; a refused call is
    audited as denied. See vmware-policy's README, "Roles for network callers".
  • A target-limited role is checked against the same config the connection uses: the copy the server's connection manager loaded on its first connection. Edit config.yaml and restart for both to see the change.
  • README and setup guide: one endpoint for several people or roles.

v2.3.1 — an account with no vSphere role is named, not passed (AIops#47)

Choose a tag to compare

@zw008 zw008 released this 16 Oct 00:19

Needs vmware-policy 1.23.0.

  • A login with no vSphere role fails at connect time with the reason. vCenter accepts the login but shows no
    session for it, and every call then fails with NotAuthenticated. The connection is now closed at once and
    doctor, the CLI and MCP tools say the account most likely has no vSphere role and to assign one (Read-Only or
    higher). Reported on vCenter 8.0.3; not yet reproduced on our own hardware.
  • Refused only when two signals agree: no session, and vCenter refuses a view of the root folder
    (NotAuthenticated / NoPermission). An account scoped to one folder can also show no session, and still
    connects; anything the check cannot read lets the login through.
  • The HTML snapshot's skipped-targets row no longer says unread targets are "not included in the status";
    they raise it.
  • NotAuthenticated later on names both causes: the session expired (retry), or the account's role was
    removed. It no longer says "verify connectivity and credentials".
  • attention never reports OK for targets it could not read. Any unread target makes the overall status at
    least WARN, none read makes it CRITICAL, and totals.status_reason (shown in the console and HTML) says how
    many targets were not read. A role-less target is listed as unreachable with reason NoVSphereRoleError.

v2.3.0 — calls on one target run side by side; `get_access_info`

Choose a tag to compare

@zw008 zw008 released this 15 Oct 14:48

Needs vmware-policy 1.22.0.

  • Calls no longer queue behind each other on a shared server. Served over --transport https/http,
    calls run side by side with up to VMWARE_MCP_POOL_SIZE (default 2) sessions per target; each call holds its
    own session for its whole run, so two calls never share one. Each session is a login on the target. A call
    that finds every session busy waits at most 300 s, then fails with a message saying so. stdio and the CLI
    keep one session per target, as before.
  • New tool get_access_info (CLI vmware-monitor access-info [--tool X] [--target T]): which account the
    server uses on a target, and whether it holds the privileges each tool needs. It asks vCenter about its own
    session (System.View is enough). Checked on the root folder: not_granted_at_root can still be granted on a
    cluster, folder or VM, and undetermined is never read as granted. 33 tools (was 32).

v2.2.0 — serve MCP over HTTPS

Choose a tag to compare

@zw008 zw008 released this 15 Oct 10:29

vmware-monitor mcp can now serve the network as well as stdio (HLD §16, via vmware-policy 1.21.0):

vmware-audit token create alice          # once per caller; shown once
vmware-monitor mcp --transport https --host 0.0.0.0 --port 8443 \
    --cert server.pem --key server-key.pem --public-name mcp.example.com

Connect a client and manage callers (Claude Code shown; any MCP client with streamable HTTP and custom headers works):

claude mcp add --transport http vmware-monitor https://mcp.example.com:8443/mcp \
    --header "Authorization: Bearer $VMWARE_MCP_TOKEN"
vmware-audit token list                  # names only
vmware-audit token revoke alice          # refused from its next request, no restart
  • Every request needs Authorization: Bearer <token>; the server will not start without a token, refuses Host or
    Origin values outside --public-name, and checks itself (unauthenticated requests must get 401) before it
    binds. --transport http binds loopback only, for a TLS-terminating reverse proxy.
  • Audit rows record the caller as token:<name> and the surface as mcp-https. Calls naming different targets
    run in parallel; calls naming no target run one at a time.
  • stdio remains the default; the vmware-monitor-mcp console script and python -m are unchanged.
  • Everyone who can reach the endpoint acts with this server's account; run one endpoint per privilege level.
  • Requires vmware-policy>=1.21.0 and mcp>=1.28.

v2.1.0 — `mcp --expose` options; the account is the boundary

Choose a tag to compare

@zw008 zw008 released this 15 Oct 06:49

vmware-monitor mcp accepts the family's new --expose / --allow-write options (vmware-policy 1.20.0). This server has
no write tools, so --expose read offers the same tools as the default; the options exist so every server in the
family can be started the same way. references/setup-guide.md now says why the service account must itself be
read-only: an agent with a shell can reach the platform without this skill. Requires vmware-policy>=1.20.0.

v2.0.0 — MCP tools renamed verb-first

Choose a tag to compare

@zw008 zw008 released this 14 Oct 05:48

Breaking for MCP clients. 23 of the 32 MCP tools have new names. The family now follows one naming
convention: the verb comes first (get_, list_, find_, scan_, investigate_), with a domain word
wherever a bare noun would collide with another skill's tool. The server exposes only the new names — there
are no aliases — so update any prompt, workflow or client config that calls a tool by its old name.

Old name New name
active_sessions list_active_sessions
active_tasks list_active_tasks
certificate_status get_certificate_status
cluster_health_summary get_cluster_health_summary
cluster_last_apply_result get_cluster_last_apply_result
cluster_patch_compliance get_cluster_patch_compliance
cross_vcenter_attention get_cross_vcenter_attention
datastore_capacity get_datastore_capacity
datastore_investigation_bundle investigate_datastore
host_investigation_bundle investigate_host
host_log_scan scan_host_logs
host_memory_tiering get_host_memory_tiering
host_performance get_host_performance
license_status get_license_status
ntp_status get_ntp_status
resource_pool_usage get_resource_pool_usage
snapshot_aging find_aging_snapshots
vcenter_deployment_size get_vcenter_deployment_size
vm_backup_snapshot_history get_vm_backup_snapshot_history
vm_info get_vm_info
vm_investigation_bundle investigate_vm
vm_list_snapshots list_vm_snapshots
vm_performance get_vm_performance

Unchanged: list_virtual_machines, list_esxi_hosts, list_all_datastores, list_all_clusters,
list_all_networks, get_alarms, get_events, get_host_sensors, get_host_services.

  • CLI commands are unchanged. Only the tool name each CLI read records in ~/.vmware/audit.db (its MCP
    twin's name) moves to the new name, so CLI and MCP rows for the same read still match.
  • Parameters, result shapes and annotations are unchanged; the server is still read-only by code.
  • Hints that point at vmware-aiops tools now use its 2.0 names (power_on_vm, power_off_vm,
    delete_vm_snapshot).
  • Deny rules in ~/.vmware/rules.yaml written with old names keep working with vmware-policy ≥ 1.18.0 (it
    matches both names); vmware-audit policy lists any rule that now matches more.

v1.16.0 — MCP instructions name the configured targets

Choose a tag to compare

@zw008 zw008 released this 20 Sep 14:48

initialize hands the client this server's instructions, and for a skill whose every tool takes a target that
text is the only place the client learns which targets exist. Until now this one shipped a static description that never named them. The model then
called tools with no target, got whatever the default was, and answered confidently about the wrong system —
measured in vmware-monitor on 2026-09-15, where a standalone ESXi host was the default, so "how many VMs does the
vCenter have" was answered from that host.

The instructions now carry, built from the loaded config on every server start:

  • Configured targets: — each configured target with its host, and which one answers when none is named.
  • Choosing a target: — how to pick one from what the user asked, and to ask rather than guess when the
    request does not say and the targets would answer differently.

A config that cannot be read is said out loud, not dropped. On a machine that has not run init yet — every
new install — this server now reports Configured targets: could not be read (FileNotFoundError) — run vmware-monitor doctor. instead of falling silent. A client shown no listing cannot
tell "this skill has no targets worth naming" from "this skill could not read them", and only the first reading
produces a confident answer about a system nobody chose. Only the error's type is included; its text quotes the
config path.

No tool, parameter or result shape changed. A new family gate (mcp_instructions_name_targets.py, in
family_smoke) probes every server under an empty HOME, so the check runs in the state a new user is in rather
than the one the developer happens to be in.

v1.15.1 — a stopped server exits even if its logout hangs; `activity tasks` mentions unreadable tasks beside readable ones

Choose a tag to compare

@zw008 zw008 released this 16 Sep 05:26

Corrections to 1.15.0, from an independent review on 2026-09-15.

A stopped server exits within five seconds, even if its logout hangs. 1.15.0 made the server log out when
Claude Code stops it: the first stop signal ignored further stop signals and ran the atexit logout. The logout
had no time limit. pyVmomi connects with httpConnectionTimeout=None, so a logout to a vCenter that stopped
answering, or one waiting on the SOAP connection lock a tool call held when the signal arrived, kept the server
running and deaf to every further stop signal until something sent SIGKILL. Before 1.15.0, SIGTERM at least
ended it.

  • The logout now runs on a worker thread and gets 5 seconds. If it has not finished, the server writes one line
    to stderr without blocking (a full pipe cannot hold the exit) and exits with 128 + signal anyway; vCenter or
    ESXi ends that session when it idles out.
  • New test: the real server with stdin held open, an atexit callback that blocks for ten minutes, then SIGINT
    and SIGTERM. The server must exit within 15 seconds and say it gave up on the logout. It failed on 1.15.0.
  • Lab, on this code: eight conversations against vCenter 8.0.3 and ESXi 8.0.3, including active_tasks on both,
    left no session behind; afterwards both session lists held only the counting call's own session.

activity tasks mentions unreadable tasks beside readable ones. 1.15.0 printed unreadable_note only when
no task could be read. With some tasks readable it printed their table and nothing else, which reads as "these
are all the tasks". The note is now printed under the table too. The MCP result was already right.

  • references/cli-reference.md said --target defaults to the first target; it now names default_target.