VMware VDI (Horizon)
PYPI · VMWARE-VDI · SCANNED SEP 21
VMware/Omnissa Horizon VDI ops: pools, sessions, machines, images — 27 MCP tools.
Available components
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security100
- No malware found by supply-chain analysis.Pass
- No known CVEs affecting this package version or its production dependencies.Pass
- Runs hatchling.build at install time, a recognised native-build step with no shell scripting around it. View diagnostics → Pass
- 3 of 40 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency35
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Provenance check failed: no build-provenance attestation is published. See how to fix → View diagnostics → Fail
- License check failed: the license (MIT License) isn't a recognized OSI-approved license. See how to fix → Fail
- Actively maintained (last published 0 days ago).Pass
- Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability74
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 3852 tokens (~142/item across 27 items; 27 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management73
- Stability observed for 22 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- All 3 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
- An AI judge read all 28 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
How do I install the VMware VDI (Horizon) MCP server?
VMware VDI (Horizon) runs locally as a PyPI package, launched with uvx vmware-vdi. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
pypi · vmware-vdi
claude mcp add vmware-skills-vmware-vdi -- uvx vmware-vdi
{
"mcpServers": {
"vmware-skills-vmware-vdi": {
"command": "uvx",
"args": [
"vmware-vdi"
]
}
}
} {
"servers": {
"vmware-skills-vmware-vdi": {
"command": "uvx",
"args": [
"vmware-vdi"
]
}
}
} codex mcp add vmware-skills-vmware-vdi -- uvx vmware-vdi
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"vmware-skills-vmware-vdi": {
"type": "local",
"command": [
"uvx",
"vmware-vdi"
],
"enabled": true
}
}
} openclaw mcp add vmware-skills-vmware-vdi --command uvx --arg vmware-vdi
mcp_servers:
vmware-skills-vmware-vdi:
command: "uvx"
args: ["vmware-vdi"] {
"McpServers": {
"vmware-skills-vmware-vdi": {
"Transport": "stdio",
"Command": "uvx",
"Arguments": [
"vmware-vdi"
]
}
}
} assistant mcp add vmware-skills-vmware-vdi -t stdio -c uvx -a vmware-vdi
{
"mcpServers": {
"vmware-skills-vmware-vdi": {
"command": "uvx",
"args": [
"vmware-vdi"
]
}
}
} Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 21 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 70 to 73. That category is still filling its 30-day observation window: 21 days of observed history at the previous scan, 22 at this one. The score rises as the window fills, whether or not the server changes.
- 20 Sept 26 +15
- Tool safety: pass → unverified ▼ security
- Stability: 0.67 → unverified ▼ security
- Malware scan: unverified → pass ▲ security
- Capabilities: pass → unverified ▼ functional
- Tool coverage: 100 → unverified ▼ functional
- Schema quality: Schema quality not yet verified: we do not have a sandbox capture of the MCP schema this version of the package serves yet. functional
- Package version: 1.2.0 → 1.3.0 functional
- 19 Sept 26 −15
- Malware scan: pass → unverified ▼ security
- Schema quality: 111 → 137 ▼ functional
- Package version: 1.1.1 → 1.2.0 functional
- 18 Sept 26 +15
- Malware scan: unverified → pass ▲ security
- 16 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 53 to 57. That category is still filling its 30-day observation window: 16 days of observed history at the previous scan, 17 at this one. The score rises as the window fills, whether or not the server changes.
- 15 Sept 26 −15
- Malware scan: pass → unverified ▼ security
- Package version: 1.1.0 → 1.1.1 functional
- 14 Sept 26 +16
- Malware scan: unverified → pass ▲ security
- 12 Sept 26 +1
- Package version: 1.0.2 → 1.1.0 functional
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 21 Sept 2026 · Analysed pypi/vmware-vdi@1.3.0
Provenance No attestation
The registry publishes no build provenance for this version, so there is nothing to verify.
| Result | No attestation |
|---|---|
| Ecosystem | pypi |
Background: How many MCP packages publish verified provenance →
Install scripts 1 script
| Hook | Tier | Command |
|---|---|---|
| build_backend | allowlisted | hatchling.build |
Background: Why install scripts are a supply-chain risk →
Dependencies 40 packages
| Packages resolved | 40 |
|---|---|
| Stale | 3 |
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
ad_user_search ~77
[READ] Resolve AD users/groups by name to their SIDs — needed to entitle a pool (entitlement_add).
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Max principals to return (default 25). |
| name | string | yes | Name substring to search for. |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
app_pool_list ~69
[READ] List published application pools: id, name, farm, enabled, executable path. Paginated.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Page size (default 50). |
| offset | integer | – | Page offset. |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
entitlement_add ~194
[WRITE] Grant desktop-pool access to AD user/group SID(s). Get SIDs from ad_user_search. A bare call returns blast_radius (pool identity, which principals are already entitled and which are new) and grants nothing; confirm=True grants. Refused when the pool's current entitlements cannot be read. Show blast_radius to the user and wait for their decision. Do not set confirm=True on your own because the user asked for this earlier: they have not seen the blast radius yet. Audited.
| Name | Type | Req | Description |
|---|---|---|---|
| ad_user_or_group_ids | array | yes | AD SIDs to entitle (from ad_user_search). |
| confirm | boolean | – | False (default) returns the blast radius and changes nothing. True grants. |
| pool_id | string | yes | The desktop-pool id (from pool_list). |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
entitlement_list ~102
[READ] List the AD users/groups entitled to a desktop pool (who can access it). Paginated. A wrong pool id returns a teaching 404. Use pool_list for pool ids.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Page size (default 50). |
| offset | integer | – | Page offset. |
| pool_id | string | yes | The desktop-pool id (from pool_list). |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
entitlement_remove ~194
[WRITE] Revoke desktop-pool access from AD user/group SID(s). Get SIDs from entitlement_list. A bare call returns blast_radius (pool identity, which principals lose access and which were not entitled) and revokes nothing; confirm=True revokes. Refused when the pool's current entitlements cannot be read. Show blast_radius to the user and wait for their decision. Do not set confirm=True on your own because the user asked for this earlier: they have not seen the blast radius yet. Audited.
| Name | Type | Req | Description |
|---|---|---|---|
| ad_user_or_group_ids | array | yes | AD SIDs to remove (from entitlement_list). |
| confirm | boolean | – | False (default) returns the blast radius and changes nothing. True revokes. |
| pool_id | string | yes | The desktop-pool id (from pool_list). |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
event_list ~110
[READ] List Horizon audit events (newest first), optionally filtered by severity. Paginated. Each item: time, severity, type, module, user, machine, message. Use for "what went wrong recently".
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Page size (default 50). |
| offset | integer | – | Page offset. |
| severity | – | – | Filter by severity (e.g. ERROR, WARNING, AUDIT_FAIL). |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
farm_list ~71
[READ] List Horizon RDS farms: id, name, type, enabled, RDS server count. Paginated.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Page size (default 50). |
| offset | integer | – | Page offset. |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
health_summary ~86
[READ] One-glance Horizon VDI health: session totals by state, problem machines, pool availability. The first thing to call for "how is VDI right now?". Aggregates sessions, machines, and pools into a compact status. Drill into problems with machine_list --state or session_list.
| Name | Type | Req | Description |
|---|---|---|---|
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
image_list ~61
[READ] List instant-clone base VMs and snapshots (the golden-image catalog for pool_push_image).
| Name | Type | Req | Description |
|---|---|---|---|
| base_vm_id | – | – | Optionally scope snapshots to one base VM. |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
machine_get ~155
[READ] One Horizon desktop machine by id (teaching 404 on a wrong id). Same projection as one machine_list row — id, name, pool_id, state, assigned user, agent_version, base_image — fetched with a single GET instead of scanning the estate. Use it to re-check one machine after a write, or when you already hold an id.
| Name | Type | Req | Description |
|---|---|---|---|
| machine_id | string | yes | Horizon machine id (the opaque 'id' of a machine_list row, not the desktop's display name and not the vCenter VM name). A wrong id returns a 404 whose hint tells you to re-run machine_list for exact… |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
machine_list ~150
[READ] List Horizon desktop machines, filtered by pool id / state. Paginated. Each item: id, name, pool_id, state (AVAILABLE/CONNECTED/AGENT_UNREACHABLE/PROVISIONING/ ERROR/MAINTENANCE/…), assigned user, agent_version, base_image. Verify pair for the machine write tools.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Page size (default 50). |
| offset | integer | – | Page offset. |
| pool | – | – | Filter to one desktop-pool id. |
| state | – | – | Filter by machine state (e.g. AGENT_UNREACHABLE, ERROR). |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
machine_maintenance ~178
[WRITE] Enter (enabled=True) or exit (False) maintenance mode for machine(s). Maintenance drains the machine (no new sessions). A bare call returns blast_radius (machine ids, states, assigned users) and changes nothing; confirm=True applies. A machine whose state cannot be read is refused. Show blast_radius to the user and wait for their decision. Do not set confirm=True on your own because the user asked for this earlier: they have not seen the blast radius yet. Audited.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | False (default) returns the blast radius and changes nothing. True applies it. |
| enabled | boolean | yes | True enters maintenance; False exits. |
| machine_ids | array | yes | Machine ids (from machine_list). |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
machine_remove ~161
[WRITE] Remove machine(s) from their pool — for instant clones this DELETES the backing VM. A bare call returns blast_radius (machine ids, names, states, assigned users) and removes nothing; confirm=True removes. A machine whose state cannot be read is refused. Show blast_radius to the user and wait for their decision. Do not set confirm=True on your own because the user asked for this earlier: they have not seen the blast radius yet. Audited.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | False (default) returns the blast radius and changes nothing. True removes. |
| machine_ids | array | yes | Machine ids to remove (from machine_list). |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
machine_reset ~174
[WRITE] Hard-reset desktop machine(s) — the user loses unsaved state. A bare call returns blast_radius (machine ids, names, states, assigned users) and resets nothing; confirm=True resets. A machine whose state cannot be read is refused. Show blast_radius to the user and wait for their decision. Do not set confirm=True on your own because the user asked for this earlier: they have not seen the blast radius yet. For a graceful in-guest reboot use vmware-aiops (the vCenter VM). Audited.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | False (default) returns the blast radius and changes nothing. True resets. |
| machine_ids | array | yes | Machine ids to reset (from machine_list). |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
pool_get ~145
[READ] One desktop pool by id (teaching 404 on a wrong id). Same projection as one pool_list row — id, name, type, enabled, provisioning_enabled, assignment — fetched with a single GET instead of listing every pool. Use it to re-check one pool after a write, or when you already hold an id.
| Name | Type | Req | Description |
|---|---|---|---|
| pool_id | string | yes | Horizon desktop-pool id (the opaque 'id' of a pool_list row, not the pool's display name). A wrong id returns a 404 whose hint tells you to re-run pool_list for exact ids. |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
pool_list ~89
[READ] List Horizon desktop pools: id, name, type (AUTOMATED/MANUAL/RDS), enabled, assignment. The verify pair for pool_set_enabled and pool_push_image. Paginated envelope.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Page size (default 50). |
| offset | integer | – | Page offset. |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
pool_push_image ~309
[WRITE] Apply the pending image to an instant-clone pool — RECREATES EVERY DESKTOP in it. Highest blast radius in the family: the preview states affected-desktop and in-session counts before you confirm, plus blast_radius.occupancy — "determined" when those counts can be believed, "unknown" when sessions exist that cannot be attributed to any pool or farm. confirm=True schedules the apply. Show blast_radius to the user and wait for their decision. Do not set confirm=True on your own because the user asked for this earlier: they have not seen the blast radius yet. Audited.
| Name | Type | Req | Description |
|---|---|---|---|
| acknowledge_unknown_occupancy | boolean | – | Only consulted when the preview reports blast_radius.occupancy == "unknown", where in_session_count is a lower bound rather than a count and confirm=True is refused. Setting it True pushes on an unve… |
| confirm | boolean | – | False (default) returns the blast radius and changes nothing. True schedules the push. |
| logoff_policy | string | – | WAIT_FOR_LOGOFF (default) or FORCE_LOGOFF. |
| pool_id | string | yes | The pool id (from pool_list). |
| stop_on_error | boolean | – | Halt the rolling push on the first machine error (default True). |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
pool_set_enabled ~183
[WRITE] Enable or disable a desktop pool — disabling stops NEW sessions (existing keep running). Idempotent (matching state returns a noop). A bare call returns blast_radius (pool identity, current and new enabled state) and changes nothing; confirm=True applies. A pool whose current enabled state cannot be read is refused. Show blast_radius to the user and wait for their decision. Do not set confirm=True on your own because the user asked for this earlier: they have not seen the blast radius yet. Audited.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | False (default) returns the blast radius and changes nothing. True applies it. |
| enabled | boolean | yes | True enables; False disables. |
| pool_id | string | yes | The pool id (from pool_list). |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
pool_utilization ~69
[READ] Per-pool capacity: total / available / in-use / error machines and utilization %. The "am I running out of desktops?" view, sorted by utilization. Drill in with machine_list --pool.
| Name | Type | Req | Description |
|---|---|---|---|
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
session_disconnect ~179
[WRITE] Disconnect Horizon session(s) — state preserved, the user can reconnect. Less disruptive than logoff. Identify by session_ids OR user. A bare call returns blast_radius (session ids, count, affected users) and changes nothing; confirm=True disconnects. A session whose user cannot be read is refused. Show blast_radius to the user and wait for their decision. Do not set confirm=True on your own because the user asked for this earlier: they have not seen the blast radius yet. Audited.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | False (default) returns the blast radius and changes nothing. True disconnects. |
| session_ids | – | – | Session ids to disconnect. |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
| user | – | – | Disconnect all sessions of this AD user (substring match). |
No output schema declared.
No examples provided.
session_get ~79
[READ] Full detail for one Horizon session by id. A wrong id returns a teaching error ("run session_list for current ids"), not a traceback. Use session_list to discover ids.
| Name | Type | Req | Description |
|---|---|---|---|
| session_id | string | yes | The session id (from session_list). |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
session_list ~190
[READ] List Horizon VDI sessions, filtered by user / pool id / state. Paginated. Returns a {items, returned, limit, total, truncated, hint} envelope; each item has id, user, type (DESKTOP/APPLICATION), state (CONNECTED/DISCONNECTED/PENDING), protocol (BLAST/PCOIP/RDP), pool_id, machine_id, start_time. This is the verify pair for logoff/disconnect — get a session id or confirm a user's sessions here first.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Page size (default 50). |
| offset | integer | – | Page offset. |
| pool | – | – | Exact desktop-pool / farm id. |
| state | – | – | CONNECTED, DISCONNECTED, or PENDING. |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
| user | – | – | Substring-match the AD user name. |
No output schema declared.
No examples provided.
session_logoff ~197
[WRITE] Force-logoff Horizon session(s) — kicks the user, triggers profile write-back. Identify targets by explicit session_ids OR by user (all of that user's sessions). A bare call returns blast_radius — session ids, count and affected users — and logs off nothing; confirm=True logs off. A session whose user cannot be read is refused. Show blast_radius to the user and wait for their decision. Do not set confirm=True on your own because the user asked for this earlier: they have not seen the blast radius yet. Audited.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | False (default) returns the blast radius and changes nothing. True logs off. |
| session_ids | – | – | Session ids to log off (from session_list). |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
| user | – | – | Log off all sessions of this AD user (substring match); refuses if none match. |
No output schema declared.
No examples provided.
session_send_message ~132
[WRITE] Send a message to Horizon session(s) — e.g. "save your work, maintenance in 10 min". Low blast radius (informational only, no session disruption), so no confirm gate. Identify by session_ids OR user. Audited.
| Name | Type | Req | Description |
|---|---|---|---|
| message | string | yes | The text to display to the user(s). |
| message_type | string | – | INFO, WARNING, or ERROR. |
| session_ids | – | – | Session ids to message. |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
| user | – | – | Message all sessions of this AD user (substring match). |
No output schema declared.
No examples provided.
session_stats ~57
[READ] Session statistics: concurrency by state / protocol, current concurrent, busiest pools. The reporting counterpart to session_list — aggregate numbers, not per-session rows.
| Name | Type | Req | Description |
|---|---|---|---|
| target | – | – | Horizon target from config.yaml; omit to use the default. |
No output schema declared.
No examples provided.
task_cancel ~186
[WRITE] Cancel a running pool task (e.g. an in-progress image push). A bare call reads the task and returns blast_radius (task type, state, progress) and cancels nothing; confirm=True cancels. A task whose type or state cannot be read is refused. Work already applied is not rolled back. Show blast_radius to the user and wait for their decision. Do not set confirm=True on your own because the user asked for this earlier: they have not seen the blast radius yet. Audited.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | False (default) returns the blast radius and changes nothing. True cancels. |
| pool_id | string | yes | The desktop-pool id. |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
| task_id | string | yes | The task id (from task_status). |
No output schema declared.
No examples provided.
task_status ~116
[READ] Status of a pool's long task (image push / provisioning), or all tasks for the pool. Horizon tasks are pool-scoped. Give task_id (from pool_push_image or a prior task_status) for one task; omit it to list all tasks for the pool.
| Name | Type | Req | Description |
|---|---|---|---|
| pool_id | string | yes | The desktop-pool id. |
| target | – | – | Horizon target from config.yaml; omit to use the default. |
| task_id | – | – | A specific task id; omit to list all tasks for the pool. |
No output schema declared.
No examples provided.
What is the VMware VDI (Horizon) MCP server?
VMware VDI (Horizon) is an MCP server listed in the public MCP registry as io.github.vmware-skills/vmware-vdi. VMware/Omnissa Horizon VDI ops: pools, sessions, machines, images, 27 MCP tools. This page covers its PyPI package (vmware-vdi).
Is the VMware VDI (Horizon) MCP server safe to use?
VMware VDI (Horizon) scores 79 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 21 September 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the VMware VDI (Horizon) MCP server expose?
VMware VDI (Horizon) exposes 27 tools: app_pool_list, image_list, ad_user_search, entitlement_list, entitlement_add, and 22 more. Their descriptions and schemas cost roughly 3,713 tokens of context every time the server is loaded.
Is the VMware VDI (Horizon) MCP server still maintained?
VMware VDI (Horizon) is still listed as active in the MCP registry. We last reached this channel on 21 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.