Skip to main content
Glama
matt-coppinger

Horizon MCP Server

Horizon MCP Server

MCP (Model Context Protocol) server for Omnissa Horizon VDI management. Exposes the Horizon REST API as MCP tools covering inventory, monitoring, configuration, entitlements, Active Directory, and help desk functions. Verified against the Horizon Server REST API spec for versions 2512 through 2606 — call get_api_coverage for the full list of supported tools and known gaps.

Quickstart

The fastest path to a working setup, using Claude Code with stdio transport:

  1. Clone and install:

    git clone https://github.com/matt-coppinger/horizon-mcp.git
    cd horizon-mcp
    uv sync
  2. Register the server with Claude Code (see Configuration below for what each variable means):

    claude mcp add horizon \
      -e HORIZON_BASE_URL=https://horizon.corp.example.com \
      -- uv run --project /absolute/path/to/horizon-mcp horizon-mcp

    Use the absolute path to where you cloned the repo. Omit HORIZON_ACCESS_TOKEN for now — you'll get one in the next step.

  3. Restart Claude Code, then get a token by asking it to call horizon_login (see Getting an Access Token) with your AD credentials.

  4. Verify it works — ask Claude Code to call list_desktop_pools or get_infrastructure_health. If you get real data back, you're set. The server keeps the tokens itself and renews the access token automatically when it expires, so you only log in again after the server restarts (or the refresh token expires). To persist the session across restarts, see Getting an Access Token.

Running the server standalone over HTTP instead (for remote/multi-user access, or in Docker)? See HTTP (remote) and Docker.

Related MCP server: vSphere-MCP-Pro

Requirements

  • Python 3.11+

  • uv (recommended) or pip

  • Horizon Connection Server 2512 or later

Installation

git clone https://github.com/matt-coppinger/horizon-mcp.git
cd horizon-mcp
uv sync

Configuration

The server reads configuration from environment variables:

Variable

Required

Description

HORIZON_BASE_URL

Yes

Connection Server URL, e.g. https://horizon.corp.example.com

HORIZON_ACCESS_TOKEN

Yes*

Bearer token — obtain via horizon_login tool

HORIZON_REFRESH_TOKEN

No

Refresh token the server uses to renew an expired access token automatically. Set it to persist a session across restarts (with it, HORIZON_ACCESS_TOKEN can be omitted)

HORIZON_EXPOSE_TOKENS

No

Set to true to make horizon_login / horizon_refresh_token return the full tokens (default: 8-character hints only), for copying into config

HORIZON_AUDIT_LOG

No

File to append the JSON-lines audit log to (default: stderr). See Audit log

HORIZON_VERIFY_SSL

No

Set to false to skip TLS cert verification (lab use only)

HORIZON_CONFIRMATION

No

elicit (default): destructive tools ask the user to confirm in the MCP client, and are refused if the client can't show the prompt. flag: fall back to a confirm=True argument for clients without elicitation. See Confirming destructive operations

HORIZON_MAX_BULK_DESTRUCTIVE

No

Most machines machine_action will rebuild, reset or archive in one call (default 20)

HORIZON_MAX_MACHINE_COUNT

No

Largest machine / RDS server count create_desktop_pool / create_rdsh_farm will accept (default 500)

MCP_TRANSPORT

No

stdio (default), streamable-http, or sse

MCP_HOST

No

Bind host for HTTP transport (default 127.0.0.1; the Docker image sets 0.0.0.0)

MCP_PORT

No

Port for HTTP transport (default 8000)

MCP_API_KEY

HTTP only

Required for HTTP transport — clients must send Authorization: Bearer <value>. The server refuses to start without it

MCP_ALLOW_UNAUTHENTICATED

No

Set to true to run HTTP transport without MCP_API_KEY (not recommended)

MCP_ALLOWED_HOSTS

No

Comma-separated host names the HTTP server answers to (Host header check). Defaults to loopback names when bound to loopback; unchecked otherwise

MCP_ALLOWED_ORIGINS

No

Comma-separated browser origins allowed to call the HTTP server, e.g. https://app.example.com. Loopback origins are allowed when bound to loopback

*HORIZON_ACCESS_TOKEN can also be obtained at runtime by calling the horizon_login tool, or from HORIZON_REFRESH_TOKEN.

Usage

stdio (Claude Desktop / Claude Code)

Add to your MCP client configuration:

Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "horizon": {
      "command": "uv",
      "args": ["run", "--project", "/path/to/HorizonMCP", "horizon-mcp"],
      "env": {
        "HORIZON_BASE_URL": "https://horizon.corp.example.com",
        "HORIZON_ACCESS_TOKEN": "your-access-token-here"
      }
    }
  }
}

Claude Code — register it with claude mcp add (add --scope project to write a shareable .mcp.json instead):

claude mcp add horizon \
  -e HORIZON_BASE_URL=https://horizon.corp.example.com \
  -e HORIZON_ACCESS_TOKEN=your-access-token-here \
  -- uv run --project /path/to/HorizonMCP horizon-mcp

HTTP (remote)

HTTP transport requires MCP_API_KEY — clients authenticate with Authorization: Bearer <MCP_API_KEY>, and the server refuses to start without it (set MCP_ALLOW_UNAUTHENTICATED=true to override, not recommended). It binds to 127.0.0.1 by default; set MCP_HOST=0.0.0.0 to accept connections from other machines.

MCP_TRANSPORT=streamable-http \
MCP_PORT=8000 \
MCP_API_KEY=your-secret-key \
HORIZON_BASE_URL=https://horizon.corp.example.com \
HORIZON_ACCESS_TOKEN=your-token \
horizon-mcp

The server exposes a single endpoint at http://host:8000/mcp.

Clients pass the key as a header. For Claude Code:

claude mcp add --transport http horizon http://your-server:8000/mcp \
  --header "Authorization: Bearer your-secret-key"

stdio transport always skips authentication regardless of MCP_API_KEY.

The HTTP server also checks Host and Origin headers to block DNS-rebinding attacks from web pages. When bound to loopback it only answers to localhost/127.0.0.1/::1; behind a reverse proxy or on a named host, list your host names in MCP_ALLOWED_HOSTS. Browser-based clients from other origins must be listed in MCP_ALLOWED_ORIGINS; non-browser MCP clients send no Origin and are unaffected.

HTTP transport security: For any non-localhost deployment, place the server behind a reverse proxy (nginx, Caddy, Traefik) that enforces TLS. Each user should run a separate server instance with their own HORIZON_ACCESS_TOKEN and MCP_API_KEY to maintain session isolation.

Docker

The provided Dockerfile runs the server with streamable-http transport (Docker containers don't have an interactive stdio channel for an MCP client to attach to, so HTTP is the practical option here).

docker build -t horizon-mcp .
docker run -d -p 8000:8000 \
  -e HORIZON_BASE_URL=https://horizon.corp.example.com \
  -e HORIZON_ACCESS_TOKEN=your-token \
  -e MCP_API_KEY=your-secret-key \
  horizon-mcp

Or with docker-compose.yml (reads HORIZON_BASE_URL, HORIZON_ACCESS_TOKEN, HORIZON_REFRESH_TOKEN, HORIZON_VERIFY_SSL, and MCP_API_KEY from your shell environment or a .env file):

HORIZON_BASE_URL=https://horizon.corp.example.com MCP_API_KEY=your-secret-key docker compose up -d

MCP_API_KEY is required — both docker-compose.yml and the server itself refuse to start without it, because a containerized deployment is reachable over the network by definition, so leaving the endpoint unauthenticated is not a safe default (see Security Notes). Point your MCP client at http://host:8000/mcp with the matching Authorization: Bearer header as shown above.

Getting an Access Token

If you don't have a token yet, omit HORIZON_ACCESS_TOKEN from the config and call horizon_login as the first tool:

Call horizon_login with:
  username: jsmith
  password: ******   ← treated as a secret, masked in server logs
  domain: CORP
  base_url: https://horizon.corp.example.com

The new session is active immediately. The server keeps the access and refresh tokens itself — the tool returns only their first 8 characters (access_token_hint, refresh_token_hint), so the tokens never enter the conversation.

When the access token expires (~8 hours) and Horizon answers a request with HTTP 401, the server refreshes it with the stored refresh token and retries the request once. If there's no refresh token, or Horizon rejects it, the tool call fails with a message asking you to call horizon_login again. horizon_refresh_token and horizon_logout use the stored refresh token when you don't pass one.

Persisting the session across restarts: tokens held in the server are lost when it restarts. To keep a session, set HORIZON_EXPOSE_TOKENS=true on the server, call horizon_login once — it then returns the full access_token and refresh_token — and put them in your MCP client config as HORIZON_ACCESS_TOKEN and HORIZON_REFRESH_TOKEN (the refresh token alone is enough; the server gets an access token from it on the first call). Then unset HORIZON_EXPOSE_TOKENS.

Security: Treat both tokens as passwords. If you expose them, clear them from the conversation after copying them to your config. Do not commit tokens to version control.

Available Tools

⚠️ = asks you to confirm before running — see Confirming destructive operations.

Auth

Tool

Description

horizon_login

Authenticate with AD credentials (password masked in logs); the server keeps the tokens and returns hints

horizon_refresh_token

Renew the access token now (the server also does this automatically on expiry)

horizon_logout

Invalidate current session

Inventory

Tool

Description

list_desktop_pools

List all VDI and RDS desktop pools (paginated)

get_desktop_pool

Get pool details

create_desktop_pool

Create a new desktop pool (VDI or RDS, automated or manual)

update_desktop_pool

Update an existing desktop pool's configuration

delete_desktop_pool

Delete a desktop pool and all its machines ⚠️

desktop_pool_action

Enable/disable a pool, or enable/disable-provisioning (⚠️ when disabling)

list_machines

List virtual desktops (filterable by pool, state; paginated)

get_machine

Get machine details

machine_action

Shutdown, restart, reset, rebuild, archive ⚠️; recover, enter/exit maintenance

assign_machine_users

Assign or unassign users to a dedicated (non-floating) desktop

list_rdsh_farms

List RDS farms (paginated)

get_rdsh_farm

Get farm details

create_rdsh_farm

Create a new RDS farm (automated or manual)

update_rdsh_farm

Update an existing RDS farm's configuration

delete_rdsh_farm

Delete an RDS farm and all its servers ⚠️

rdsh_farm_action

Enable or disable one or more RDS farms (⚠️ when disabling)

list_application_pools

List published application pools (paginated)

get_application_pool

Get application pool details

create_application_pool

Publish a new application pool from an RDS farm

update_application_pool

Update an existing application pool's configuration

delete_application_pool

Unpublish an application pool ⚠️

list_sessions

List active user sessions (paginated)

get_session

Get session details

disconnect_sessions

Disconnect sessions (keep running) ⚠️

logoff_sessions

Log off sessions (terminates apps) ⚠️

reset_or_restart_sessions

Hard-reset or gracefully restart the VMs backing sessions ⚠️

send_message_to_sessions

Send pop-up notification to sessions

Monitor

Tool

Description

get_infrastructure_health

Health across all components in one parallel call (summary, connection servers, gateways, vCenters, AD domains, farms)

get_metrics

Capacity metrics in one parallel call (pools, sessions, machines, system, RDS servers, license)

get_connection_server_health

Detailed health for a specific Connection Server

Config

Tool

Description

list_connection_servers

List connection servers

get_connection_server

Get connection server config

list_virtual_centers

List configured vCenters

get_environment_properties

Environment version and features

get_settings

Global Horizon settings

update_settings

Change a settings section: general, security, client, feature or agent-restriction ⚠️

get_global_policies

USB, clipboard, multimedia policies

update_global_policies

Change global policies ⚠️ (the prompt lists each field being changed)

list_licenses

License list and status

get_event_database

Event DB config

list_ic_domain_accounts

Instant clone domain accounts

list_image_management

Image management streams, versions, or tags (pass resource: streams|versions|tags; versions and tags also need stream_id from streams)

list_gateways

Registered UAGs

trigger_connection_server_backup

Trigger Connection Server backup

Entitlements

Tool

Description

list_pool_entitlements

All entitlements for desktop or application pools

get_pool_entitlement

Users/groups for a specific pool

set_pool_entitlements

Add, replace ⚠️, or remove ⚠️ entitlements (desktop or application) — replace is desktop-pool only, the Horizon API has no bulk-replace endpoint for application pools

External / Active Directory

Tool

Description

search_ad_users_or_groups

Find AD users and groups (paginated)

get_ad_user_or_group

Get AD entity details

list_ad_domains

List configured AD domains

list_ad_containers

AD containers (OUs) in a domain — rdn → ad_container_rdn for provisioning

get_domain_netbios_map

NETBIOS → DNS domain name map

list_audit_events

Administrative audit log (paginated)

list_base_vms

VMs available for pool base images

list_base_vm_snapshots

Snapshots of a base VM (snapshot_id for instant clone pools)

list_datastores

Datastores for provisioning (requires vcenter_id + host_or_cluster_id)

list_vm_folders

VM folders in vCenter

list_datacenters

Datacenters in a vCenter Server

list_hosts_or_clusters

Hosts and clusters in a datacenter

list_resource_pools

Resource pools on a host or cluster

list_network_labels

Network port groups on a host or cluster

list_network_interface_cards

NICs on a base VM or VM template (requires base_vm_id or vm_template_id; id → network_interface_card_id in nics)

list_vm_templates

VM templates for full/linked-clone pools

list_datastore_clusters

Storage DRS datastore clusters (requires vcenter_id + host_or_cluster_id)

list_customization_specifications

Sysprep/QuickPrep specs for OS customization during provisioning

Discovery

Tool

Description

get_api_coverage

Lists all tools, resources, and unsupported operations — call this to understand what can be managed via this server

Resources (read-only)

MCP Resources expose read-only Horizon data without consuming tool slots. Access them via horizon://<path> using your MCP client's resource protocol.

Config resources (horizon://config/...):

URI

Description

horizon://config/roles

RBAC roles and their privileges

horizon://config/permissions

Role-to-principal permission assignments

horizon://config/privileges

All selectable admin privileges

horizon://config/local-access-groups

Local access groups for admin delegation

horizon://config/federation-access-groups

CPA federation access groups

horizon://config/saml-authenticators

SAML 2.0 authenticator configurations

horizon://config/radius-authenticators

RADIUS authenticator configurations

horizon://config/gssapi-authenticators

GSSAPI/Kerberos authenticator configurations

horizon://config/jwt-authenticators

JWT authenticator configurations

horizon://config/app-volumes-managers

App Volumes Managers registered with Horizon

horizon://config/uem-servers

User Environment Manager servers

horizon://config/true-sso

TrueSSO connector configurations

horizon://config/true-sso-enrollment-servers

TrueSSO enrollment servers

horizon://config/compute-profiles

Compute profiles for provisioning

horizon://config/customization-specifications

Sysprep/QuickPrep specs (config view)

horizon://config/settings/general

General settings

horizon://config/settings/security

Security settings

horizon://config/settings/client

Client feature settings

horizon://config/settings/feature

Feature toggle settings

horizon://config/settings/agent-restriction

Allowed agent versions/types

horizon://config/syslog

Syslog configuration

horizon://config/ceip

CEIP enrollment status

horizon://config/url-redirection

URL content redirection rules

horizon://config/pre-logon-settings

Pre-logon banner/message settings

horizon://config/log-collector/log-levels

Component log levels

horizon://config/log-collector/tasks

Log collection tasks

horizon://config/gateway-access-users-or-groups

Users and groups with gateway access

horizon://config/unauthenticated-access-users

Users configured for unauthenticated (kiosk) access

horizon://config/users-or-groups-global-summary

Global summary of admin users and groups across pods

horizon://config/external-deployments

External deployments (e.g. Horizon Cloud links) registered with this pod

horizon://config/secondary-credentials

Secondary credentials configured for connection servers

horizon://config/message-clients

Message security mode clients registered with Horizon

horizon://config/rcx-servers

RCX (Remote Console) servers registered with Horizon

Monitor resources (horizon://monitor/...):

URI

Description

horizon://monitor/app-volumes-managers

App Volumes Manager health

horizon://monitor/event-database

Event database status

horizon://monitor/rds-servers

RDS server health and session load

horizon://monitor/saml-authenticators

SAML authenticator health

horizon://monitor/true-sso

TrueSSO health and certificate status

horizon://monitor/datastores/usage-metrics

Datastore usage per pool/farm

horizon://monitor/pods

Remote pod health (CPA)

horizon://monitor/pods/global-session-metrics

Aggregate session counts across pods

horizon://monitor/message-clients

Message client health

Help Desk

Tool

Description

diagnose_session

All session diagnostics in one parallel call: logon timing, display performance, historical performance, processes, remote applications

get_remote_assistance_ticket

MSRA ticket for remote support

end_remote_application

Force-close a published app in a session ⚠️

Horizon Filter Syntax

Most list tools accept a filter parameter using Horizon's JSON filter format:

// Equals
{"type": "Equals", "name": "state", "value": "AVAILABLE"}

// Contains (string)
{"type": "Contains", "name": "name", "value": "win11"}

// AND combination
{
  "type": "And",
  "filters": [
    {"type": "Equals", "name": "desktop_pool_id", "value": "pool-id"},
    {"type": "Equals", "name": "state", "value": "CONNECTED"}
  ]
}

Paginated List Results

Tools marked (paginated) in the tables above (list_desktop_pools, list_machines, list_rdsh_farms, list_application_pools, list_sessions, search_ad_users_or_groups, list_audit_events) take page (1-based) and size, and return an envelope rather than a bare list:

{
  "items": [ ... ],
  "count": 100,
  "page": 1,
  "size": 100,
  "pages_fetched": 1,
  "has_more": true,
  "next_page": 2,
  "truncated": false
}
  • has_more / next_page — call the tool again with page=next_page to continue. The Horizon REST API returns a bare array with no "more records" indicator, so has_more is inferred: it is true whenever a full page (size items) came back. When the total is an exact multiple of size, the next page simply comes back empty.

  • fetch_all=true — fetches successive pages starting at page, stopping at the first short page or after 10 pages / 5,000 items, whichever comes first. If it stops at the cap with more possibly remaining, truncated is true and next_page says where to resume. Prefer a filter when you only need a subset.

Creating Pools and Farms

create_desktop_pool and create_rdsh_farm accept a spec dict that maps directly to the Horizon REST API request body.

The nesting is not what the field names suggest. vcenter_id is top-level, not inside provisioning_settings. Datastores live under a separate top-level storage_settings block. AD/domain-join settings live under a separate top-level customization_settings block. Naming and machine count live under a separate top-level pattern_naming_settings block, and the count field is max_number_of_machines, not max_machine_count. The example below is verified against a live Horizon 2606 server (a real pool was created with this exact shape) — an earlier version of this doc had the wrong nesting throughout and would have produced a 400 on every field.

Automated Instant Clone desktop pool (minimum working example):

{
  "name": "MyPool",
  "display_name": "My Pool",
  "type": "AUTOMATED",
  "source": "INSTANT_CLONE",
  "user_assignment": "FLOATING",
  "naming_method": "PATTERN",
  "access_group_id": "<id from the horizon://config/local-access-groups resource>",
  "vcenter_id": "<id from list_virtual_centers>",
  "provisioning_settings": {
    "parent_vm_id": "<id from list_base_vms>",
    "base_snapshot_id": "<id from list_base_vm_snapshots>",
    "datacenter_id": "<id from list_datacenters>",
    "vm_folder_id": "<id from list_vm_folders>",
    "host_or_cluster_id": "<id from list_hosts_or_clusters>",
    "resource_pool_id": "<id from list_resource_pools>"
  },
  "storage_settings": {
    "datastores": [{"datastore_id": "<id from list_datastores>"}]
  },
  "customization_settings": {
    "customization_type": "CLONE_PREP",
    "ad_container_rdn": "<rdn from list_ad_containers>",
    "instant_clone_domain_account_id": "<id from list_ic_domain_accounts>"
  },
  "pattern_naming_settings": {
    "naming_pattern": "MyPool-{n:fixed=2}",
    "max_number_of_machines": 10
  }
}

nics is optional and top-level ([{"network_interface_card_id": "...", "network_label_assignment_specs": [...]}]) — if omitted, new machines simply inherit the parent image's existing network settings, which is fine for most cases.

create_rdsh_farm requires access_group_id directly, and nests everything else one level deeper, under a top-level automated_farm_settings object: automated_farm_settings.vcenter_id, .provisioning_settings, .storage_settings, .customization_settings, .pattern_naming_settings (with max_number_of_rds_servers instead of max_number_of_machines), plus a required max_session_type (LIMITED | UNLIMITED — max_sessions is required when LIMITED). This shape is verified live against a real Horizon 2606 server.

Resource ID lookup chain — follow this sequence to resolve all IDs before calling create_desktop_pool or create_rdsh_farm:

list_virtual_centers
  ├─ list_customization_specifications(vcenter_id)   ← Sysprep spec ID (SYS_PREP only)
  ├─ list_vm_templates(vcenter_id)                   ← template_id (full/linked-clone pools)
  │    └─ list_network_interface_cards(vcenter_id, vm_template_id=...)  ← optional, nics
  └─ list_datacenters(vcenter_id)
       ├─ list_vm_folders(vcenter_id, datacenter_id)
       └─ list_hosts_or_clusters(vcenter_id, datacenter_id)
            ├─ list_datastores(vcenter_id, host_or_cluster_id)
            ├─ list_datastore_clusters(vcenter_id, host_or_cluster_id)
            ├─ list_resource_pools(vcenter_id, host_or_cluster_id)
            └─ list_network_labels(vcenter_id, host_or_cluster_id)  ← optional, nics
list_base_vms(vcenter_id)                            ← parent_vm_id (instant-clone pools)
  ├─ list_base_vm_snapshots(vcenter_id, base_vm_id)  ← base_snapshot_id
  └─ list_network_interface_cards(vcenter_id, base_vm_id)  ← optional, nics
horizon://config/local-access-groups (resource)      ← access_group_id (always required)
list_ad_domains
  └─ list_ad_containers(domain_id)                   ← ad_container_rdn (instant clone)
list_ic_domain_accounts                              ← instant_clone_domain_account_id (instant clone)

create_application_pool uses explicit parameters instead — pass name, farm_id, executable_path, and optional fields directly.

For updates, retrieve the current config with get_desktop_pool / get_rdsh_farm / get_application_pool, modify the relevant fields, and pass the result to the corresponding update_* tool. get_desktop_pool and get_rdsh_farm return every field their update_* schema needs, and the unchanged get-then-update round trip is verified live against Horizon 2606 for both pools and farms.

Delete operations (delete_desktop_pool, delete_rdsh_farm, delete_application_pool) ask you to confirm in the client, naming the pool or farm. Call get_desktop_pool / get_rdsh_farm and list_sessions first so you know what will be affected.

Confirming destructive operations

Tools marked ⚠️ pause and ask you to confirm before they run, using MCP elicitation: your MCP client shows a prompt describing exactly what will happen (for example "Delete desktop pool Sales (id), all of its machines, and end any active sessions in it") with Proceed and Cancel. The AI model can't answer this prompt for you, so a prompt-injected or mistaken model can't push a destructive operation through on its own — unlike a confirm=True argument, which the model sets itself.

Tool

Asks when

delete_desktop_pool, delete_rdsh_farm, delete_application_pool

Always

machine_action

shutdown, restart, reset, rebuild, archive (not recover or maintenance mode)

logoff_sessions, disconnect_sessions, reset_or_restart_sessions

Always

end_remote_application

Always

desktop_pool_action, rdsh_farm_action

Disabling (not enabling)

set_pool_entitlements

replace or remove (not add)

update_global_policies, update_settings

Always — the prompt lists each field that changes, old → new

If your client doesn't support elicitation, these tools are refused by default. If you can't switch clients, set HORIZON_CONFIRMATION=flag on the server to accept a confirm=True argument instead — be aware the model can set that argument itself, so only do this with a client that asks you to approve each tool call.

These tools, plus the update_* tools and assign_machine_users, also carry destructiveHint=True, so clients that gate tool calls on MCP annotations will prompt before running them.

Audit log

The server writes one JSON line per event to stderr, or appends to the file named by HORIZON_AUDIT_LOG. It never writes to stdout, which stdio transport uses for the MCP protocol. Each line has a UTC timestamp (ts), the event type and the tool that triggered it:

  • confirmation — every confirmation decision: the summary shown to the user and the outcome (approved, cancelled, refused because the client can't prompt, or in flag mode approved / missing_confirm).

  • api_request — every POST, PUT and DELETE sent to Horizon: method, path, and the HTTP status (or the exception type as error), plus retried if the token was refreshed first. GETs aren't logged.

  • auth — login, logout and token refresh (manual or automatic) and their status.

Request bodies, passwords, usernames, tokens and Authorization headers are never logged.

Running Tests

uv sync --all-extras --all-groups
uv run pytest -q          # unit tests
uv run ruff check src     # lint
uv run pyright src        # type check

CI runs all of these on every pull request (tests on Python 3.11–3.13), plus a pip-audit scan of the locked dependencies.

The unit tests are offline. The live integration tests in tests/live/ are collected but skipped unless you point them at a server — see below.

Live integration tests

⚠️ Use a lab, never production. The read-only sweep changes nothing, but the opt-in write tests disable/enable a farm, publish and delete application pools, change entitlements, write settings back, and (with the destructive flag) provision and delete a real RDS farm.

tests/live/ spawns the real server over MCP stdio (the way Claude Desktop / Code run it), logs in through horizon_login, and calls tools exactly as a client would. Destructive tools are confirmed through real MCP elicitation: the test's handler approves a prompt only if it names an ID the test itself created (or HZ_TEST_FARM's ID), or — for the settings round trips — says no fields differ. Everything else is cancelled, and each test asserts that every prompt it saw was expected.

Test

Needs

What it does to the environment

test_read_only.py — one check per read-only tool, chaining IDs from list results into get calls; a check is skipped with a reason when the lab has nothing to feed it (e.g. no active sessions)

the four required vars

Nothing (logs in, reads, logs out)

test_writes.py::test_rdsh_farm_action_and_noop_update

HZ_LIVE_WRITES=1, HZ_TEST_FARM

Disables then re-enables the test farm (or the reverse if it starts disabled), writes its config back unchanged; restores the original enabled state in a finally

test_writes.py::test_application_pool_lifecycle

HZ_LIVE_WRITES=1, HZ_TEST_FARM

Publishes a uniquely named app pool (mcp-live-<random>) on the test farm, renames and restores its display name, deletes it

test_writes.py::test_application_pool_entitlements_add_remove

HZ_LIVE_WRITES=1, HZ_TEST_FARM, HZ_TEST_GROUP

Same kind of throwaway app pool; entitles the group, removes it again, deletes the pool

test_writes.py::test_update_global_policies_noop, test_update_settings_general_noop

HZ_LIVE_WRITES=1

Reads global policies / general settings and writes the identical object back; asserts nothing changed (writes the original back if anything did)

test_destructive.py::test_create_and_delete_rdsh_farm

HZ_LIVE_WRITES=1, HZ_LIVE_DESTRUCTIVE=1, HZ_BASE_VM, HZ_SNAPSHOT

Creates a throwaway 1-server instant-clone farm (mcp-live-<random>), deletes it with delete_rdsh_farm, polls until it's gone. Provisions a real VM — expect this to take many minutes.

Tests only ever modify HZ_TEST_FARM and resources they create themselves, and created resources are always deleted in teardown. If a teardown fails, the test prints MANUAL CLEANUP MAY BE NEEDED with the resource's name and ID.

Environment variables

Variable

Purpose

HZ_BASE_URL, HZ_USERNAME, HZ_DOMAIN, HZ_PASSWORD

Required — without all four, every live test is skipped

HZ_VERIFY_SSL

false for a lab with a self-signed certificate (default true)

HZ_LIVE_WRITES=1

Enable the reversible write tests

HZ_LIVE_DESTRUCTIVE=1

Additionally enable the farm create/delete test

HZ_TEST_FARM

Name of a dedicated test RDS farm the write tests may modify and publish apps from

HZ_TEST_GROUP

AD group (name or SID) to entitle to the test app pool

HZ_TEST_APP_PATH

Executable for the test app pool (default C:\Windows\System32\notepad.exe)

HZ_BASE_VM, HZ_SNAPSHOT

Base VM and snapshot (name or ID) for the throwaway farm. Use the snapshot taken after the Horizon Agent was installed

HZ_VCENTER, HZ_DATACENTER, HZ_CLUSTER, HZ_RESOURCE_POOL, HZ_VM_FOLDER, HZ_DATASTORE, HZ_ACCESS_GROUP, HZ_IC_DOMAIN_ACCOUNT

Optional (name or ID) — otherwise the first one listed is used

HZ_AD_CONTAINER

Optional AD container RDN for the throwaway farm's servers

HZ_LIVE_PROVISION_TIMEOUT

Seconds to wait for each farm provisioning/teardown step (default 1800)

HZ_LIVE_REPORT

Write an HTML report (secrets redacted) to this path, e.g. .live-reports/report.html (ignored by git)

HZ_LIVE_SERVER_LOG

Where to write the server's stderr (default: a temp file, printed at the end of the run)

Running

# Read-only sweep
export HZ_BASE_URL=https://<connection-server> HZ_USERNAME=<user> HZ_DOMAIN=<domain> HZ_VERIFY_SSL=false
read -rs HZ_PASSWORD && export HZ_PASSWORD
uv run pytest tests/live -v -rs

# Plus reversible writes, with an HTML report
HZ_LIVE_WRITES=1 HZ_TEST_FARM=<test-farm> HZ_TEST_GROUP=<ad-group> \
  HZ_LIVE_REPORT=.live-reports/report.html uv run pytest tests/live -v -rs

# Plus the farm create/delete test (slow — provisions a VM)
HZ_LIVE_WRITES=1 HZ_LIVE_DESTRUCTIVE=1 HZ_BASE_VM=<base-vm> HZ_SNAPSHOT=<agent-snapshot> \
  uv run pytest tests/live/test_destructive.py -v -s

Add -s to watch each tool call and confirmation prompt as it happens. -m "not live" deselects the suite entirely.

End-to-end lifecycle test

⚠️ Lab only, never production. This test provisions VMs, deletes pools and farms, restarts machines, changes entitlements and (optionally) logs off a real user session.

tests/live/test_lifecycle.py exercises every tool the server registers against resources it creates itself, then deletes them. One command does the whole run:

  1. Read-only sweep — the test_read_only.py checks, in their own server process.

  2. Auth & discovery — horizon_login (checks only token hints come back), get_api_coverage, the vCenter/AD lookups for placement, HZ_TEST_GROUP and HZ_TEST_USER.

  3. Cleanup — deletes leftovers from earlier runs: application pools first, then desktop pools and farms, polling until each is gone.

  4. Provision — a desktop pool, an RDS farm and an application pool (see footprint below), waiting for the machine and the RDS server to be AVAILABLE and failing fast on a provisioning error.

  5. Reads of the new items, then desktop pool updates (rename + restore; disable/enable; disable/enable provisioning), entitlements (desktop add → replace → remove, application add → remove, each verified), machine admin (assign/unassign HZ_TEST_USER, maintenance mode), farm & app pool (no-op farm update, disable/enable, app rename + restore) and config (no-op global policies and general settings round trips, one Connection Server backup).

  6. User sessions (optional, below), then machine power actions: restart, reset, recover, rebuild, archive, shutdown — each waits for AVAILABLE first. recover / rebuild / archive may not apply to an instant clone; a clean Horizon rejection is recorded as NA with its error, not a failure.

  7. Teardown (always, in a finally) — deletes the app pool, desktop pool and farm, polls until they're gone, and prints MANUAL CLEANUP MAY BE NEEDED: … if anything is left.

  8. Refresh & logout — horizon_refresh_token, a call with the new token, horizon_logout, and a check that calls are refused afterwards.

Footprint: instant clones only — one AUTOMATED / INSTANT_CLONE / DEDICATED desktop pool with a single machine provisioned up front, one AUTOMATED farm with a single RDS server, and one application pool (HZ_TEST_APP_PATH) on that farm.

Cleanup is prefix-only. Everything the run creates is named <prefix>vdi-<tag>, <prefix>farm-<tag> and <prefix>app-<tag> (HZ_E2E_PREFIX, default mcp-e2e-; the test refuses a prefix shorter than 5 characters or with anything but letters, digits, - and _). The cleanup phase deletes only application pools, desktop pools and farms whose name starts with that prefix, and nothing else. The confirmation handler approves only prompts that name the ID of such an item, or of a machine or session inside one (plus the settings no-op round trips, which say that nothing changes); everything else is cancelled and fails the test.

Coverage: at the end every registered tool gets a verdict — PASS, FAIL, SKIP (with a reason), NA (Horizon cleanly rejected an action that doesn't apply), or KNOWN (a documented quirk, e.g. update_settings general rejecting its own restricted_client_data). The test fails if any tool failed or was neither called nor skipped with a reason, if a prompt was unexpected, or if anything was left behind. The table is printed at the end and is the first section of the HTML report (HZ_LIVE_REPORT). The lab may have no event database (list_audit_events → SKIP) or no image streams (versions/tags → SKIP).

User sessions. REST can't start a session, so with HZ_E2E_WAIT_FOR_SESSION=1 the test entitles HZ_TEST_USER to the pool and the app, prints which ones to open, and waits (HZ_E2E_SESSION_TIMEOUT, default 900s) for the sessions to appear. Open both the desktop and the app: the desktop session gets get_session, diagnose_session, get_remote_assistance_ticket (redacted), send_message_to_sessions, disconnect_sessions and reset_or_restart_sessions (restart); the app session gets end_remote_application (on an app found by diagnose_session) and logoff_sessions. With one session, reset_or_restart_sessions is skipped with a reason. Without the flag, the session tools are skipped with the reason "needs a real user session".

Duration: roughly 20–60 minutes, dominated by instant-clone provisioning (twice: the pool and the farm) and the machine restart/reset waits; add the time you take to connect when waiting for a session.

Variable

Purpose

HZ_LIVE_E2E=1

Required — enables the test (plus the four required HZ_* connection variables)

HZ_POOL_BASE_VM, HZ_POOL_SNAPSHOT

Required — desktop pool base VM and snapshot (name or ID). Use the snapshot taken after the Horizon Agent was installed — the wrong one fails with AGENT_CUSTOMIZATION_FAULT

HZ_FARM_BASE_VM, HZ_FARM_SNAPSHOT

Required — RDS farm base VM and snapshot; falls back to HZ_BASE_VM / HZ_SNAPSHOT when neither is set

HZ_TEST_GROUP

Required — AD group (name or SID) for the entitlement steps

HZ_TEST_USER

Required — AD user (login name, DOMAIN\user, user@domain or SID) to assign, entitle and (optionally) connect as

HZ_E2E_PREFIX

Name prefix for everything created and the only thing cleanup deletes (default mcp-e2e-)

HZ_E2E_WAIT_FOR_SESSION=1

Wait for you to connect as HZ_TEST_USER, then test the session tools

HZ_E2E_SESSION_TIMEOUT

Seconds to wait for a session (default 900)

HZ_E2E_SKIP_BACKUP=1

Don't trigger a Connection Server backup

HZ_E2E_POLL_INTERVAL

Seconds between state polls (default 15)

HZ_LIVE_PROVISION_TIMEOUT

Seconds to wait for each provisioning, power action and delete (default 1800)

HZ_TEST_APP_PATH, HZ_VCENTER, HZ_DATACENTER, HZ_CLUSTER, HZ_RESOURCE_POOL, HZ_VM_FOLDER, HZ_DATASTORE, HZ_ACCESS_GROUP, HZ_IC_DOMAIN_ACCOUNT, HZ_AD_CONTAINER, HZ_LIVE_REPORT

As above (shared by the pool and the farm)

export HZ_BASE_URL=https://<connection-server> HZ_USERNAME=<admin-user> HZ_DOMAIN=<domain> HZ_VERIFY_SSL=false
read -rs HZ_PASSWORD && export HZ_PASSWORD
HZ_LIVE_E2E=1 \
  HZ_POOL_BASE_VM=<desktop-base-vm> HZ_POOL_SNAPSHOT=<desktop-agent-snapshot> \
  HZ_FARM_BASE_VM=<rdsh-base-vm> HZ_FARM_SNAPSHOT=<rdsh-agent-snapshot> \
  HZ_TEST_GROUP=<ad-group> HZ_TEST_USER=<ad-user> \
  HZ_E2E_WAIT_FOR_SESSION=1 HZ_LIVE_REPORT=.live-reports/e2e.html \
  uv run pytest tests/live/test_lifecycle.py -v -rs

The test streams its progress (and the "connect now" instructions) even without -s. To see every phase and tool call without a lab, run the dry run against the offline fake Horizon in tests/live/fake_horizon.py: uv run python -m tests.live.lifecycle --plan (add --no-session to plan without the session step). The same dry run runs in the unit tests (tests/test_lifecycle_plan.py), so a new tool the lifecycle doesn't cover fails CI.

Releases

Versions follow Semantic Versioning and are tagged vX.Y.Z on main. See CHANGELOG.md for what changed in each release, including breaking changes.

Security Notes

  • Store credentials in your MCP client's env block, not in code or config files tracked by git.

  • In production, always keep HORIZON_VERIFY_SSL=true (default).

  • Passwords passed to horizon_login are typed as SecretStr and masked in server-side logs.

  • Access and refresh tokens stay inside the server process: login and refresh return only 8-character hints, and expired tokens are renewed automatically, so tokens don't pass through the conversation. HORIZON_EXPOSE_TOKENS=true returns the full tokens for copying into config — leave it off otherwise, and treat the tokens as passwords.

  • The server holds one Horizon session (from HORIZON_ACCESS_TOKEN / HORIZON_REFRESH_TOKEN or the last horizon_login) shared by every client connected to it. For multiple users, run a separate instance per user with its own tokens and MCP_API_KEY, behind a reverse proxy that enforces TLS.

  • Destructive-operation decisions and every mutating Horizon request are recorded in an audit log (stderr or HORIZON_AUDIT_LOG), without request bodies or secrets.

  • Destructive operations ask the user to confirm in the MCP client and are refused if the client can't prompt — see Confirming destructive operations.

  • HTTP transport requires MCP_API_KEY, binds to 127.0.0.1 by default, and validates Host/Origin headers against DNS rebinding.

  • IDs passed to tools are percent-encoded before being placed in Horizon API paths, so an ID can't redirect a request to a different endpoint.

Available Tools

72 tools
assign_machine_usersA
DestructiveIdempotent

Assign or unassign users to a dedicated desktop machine.

Only applicable to machines in dedicated (non-floating) desktop pools. A machine can only have one assigned user at a time in most pool configurations.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesassign: assign users to this dedicated desktop. unassign: remove existing user assignment.
user_idsYesAD user IDs to assign or unassign. Use search_ad_users_or_groups to find IDs.
machine_idYesMachine ID — obtain from list_machines

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=true, and closed-world read/write status. The description adds useful behavioral context by disclosing pool eligibility and the one-user-per-machine constraint in most configurations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three short sentences, front-loads the core action, and follows with two relevant constraints. Every sentence adds useful context with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with rich annotations, complete parameter schema, and an output schema, the description is largely complete: it covers the action, eligibility, and cardinality caveat. It lacks only a pointer to alternatives or related tools, which is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already explains action, user_ids, and machine_id in detail. The description adds no parameter-level meaning beyond what the schema provides, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb pair (assign/unassign) and resource (users to a dedicated desktop machine), and scopes it to dedicated non-floating pools. This clearly distinguishes it from sibling tools that manage machines, pools, or AD objects.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear applicability constraint: only dedicated (non-floating) desktop pools. It does not name an alternative tool or explicitly state when not to use it beyond that pool-type exclusion.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_application_poolC

Publish a new application pool from an RDS farm.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesInternal name (no spaces recommended)
farm_idYesRDS farm ID — obtain from list_rdsh_farms
versionNoApplication version string
publisherNoPublisher name shown in the app catalog
display_nameNoUser-visible display name (defaults to name)
executable_pathYesFull path to the executable or .lnk shortcut, e.g. C:\ProgramData\Microsoft\Windows\Start Menu\Programs\MyApp.lnk
enable_pre_launchNoPre-launch the app before the user connects
multi_session_modeNoMulti-session mode: DISABLED (one session per user), ENABLED_DEFAULT_OFF, or ENABLED_DEFAULT_ON.DISABLED
enable_client_restrictionsNoRestrict which clients can launch the app

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the safety profile (readOnly=false, destructive=false, idempotent=false), so the description only needs to add context beyond that. It adds almost none: no note on what happens with duplicate names, required permissions, whether publishing is reversible, or side effects on the target farm.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero filler, correctly sized for a one-line summary. It is efficient, though its brevity leaves the definition thin overall rather than earning a 5 for well-structured completeness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and annotations carry the safety profile. However, for a 9-parameter mutation tool with a required farm dependency, the description omits creation semantics and side effects, leaving it only minimally complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all 9 parameters, including the multi_session_mode enum and executable_path format, are already documented in the schema. The description contributes no parameter meaning beyond that, which is the expected baseline of 3 when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Publish a new application pool') plus its source ('from an RDS farm'), which is enough to separate it from create_desktop_pool, create_rdsh_farm, and update_application_pool. It stops short of explicitly naming the siblings it is not, so it lands at 4 rather than 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no when-to-use guidance, no prerequisites (e.g. that an RDS farm must already exist), and no routing to alternatives. The only prerequisite hint, 'obtain from list_rdsh_farms', lives in the farm_id schema description, not in the tool description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_desktop_poolA

Create a new desktop pool.

CAUTION: Provisioning an AUTOMATED pool immediately begins creating VMs in vCenter. Always confirm with the user before calling this.

ParametersJSON Schema
NameRequiredDescriptionDefault
specYesFull pool specification, verified against a live Horizon server (2606). Required top-level keys: name, type (AUTOMATED | MANUAL | RDS), source (INSTANT_CLONE | LINKED_CLONE | VIRTUAL_CENTER | RDS | UNMANAGED), user_assignment (FLOATING | DEDICATED), naming_method (SPECIFIED | PATTERN), access_group_id (required for AUTOMATED/MANUAL pools — get one from the horizon://config/local-access-groups resource). AUTOMATED pools ALSO require these — all top-level, NOT nested under provisioning_settings, despite what that name suggests: vcenter_id (from list_virtual_centers); provisioning_settings: {parent_vm_id (list_base_vms), base_snapshot_id (list_base_vm_snapshots), datacenter_id (list_datacenters), vm_folder_id (list_vm_folders), host_or_cluster_id (list_hosts_or_clusters), resource_pool_id (list_resource_pools)}; storage_settings: {datastores: [{datastore_id}]} (list_datastores); customization_settings: {customization_type: 'CLONE_PREP' for instant clone, ad_container_rdn (list_ad_domains + list_ad_containers), instant_clone_domain_account_id (list_ic_domain_accounts)}; pattern_naming_settings: {naming_pattern, max_number_of_machines} when naming_method='PATTERN'. nics is optional and top-level (network_interface_card_id + network_label_assignment_specs) — if omitted, new machines simply inherit the parent image's existing network settings.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare a non-read-only, non-idempotent, non-destructive mutation, but the description adds genuinely valuable behavioral context beyond them: an AUTOMATED pool immediately begins creating VMs in vCenter and requires user confirmation. It stops short of covering auth/permission needs or the fact that each call produces a distinct new pool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action and followed by the critical caution. Every sentence earns its place with zero redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need no explanation, and the schema fully specifies the complex 'spec' object. The description covers the key provisioning risk, though it omits auth/permission prerequisites and any mention of idempotency behavior that would round it out.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the 'spec' object is exhaustively documented inline (required keys, nested settings, cross-referenced sibling tools for IDs). The description adds no parameter meaning of its own, so the baseline of 3 for high-coverage schemas applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Create) and resource (desktop pool), clearly distinct from sibling creation tools like create_rdsh_farm and create_application_pool. An agent immediately knows this tool's job.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'Always confirm with the user before calling this' directive is a useful usage guardrail, but it does not tell the agent when to choose this tool over alternatives (e.g. create_rdsh_farm for RDSH workloads) or what prerequisites must be gathered first. Usage is implied rather than fully specified.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_rdsh_farmA

Create a new RDS farm.

CAUTION: Provisioning an AUTOMATED farm immediately begins creating VMs in vCenter. Always confirm with the user before calling this.

ParametersJSON Schema
NameRequiredDescriptionDefault
specYesFull farm specification, verified live against a real Horizon server (2606). Required top-level keys: name, type (AUTOMATED | MANUAL), access_group_id (from the horizon://config/local-access-groups resource). AUTOMATED farms require an automated_farm_settings object — NOT the same shape as create_desktop_pool's provisioning_settings, and nested one level deeper — containing: vcenter_id (list_virtual_centers), max_session_type (LIMITED | UNLIMITED — max_sessions is required when LIMITED); provisioning_settings: {parent_vm_id (list_base_vms), base_snapshot_id (list_base_vm_snapshots), datacenter_id (list_datacenters), vm_folder_id (list_vm_folders), host_or_cluster_id (list_hosts_or_clusters), resource_pool_id (list_resource_pools)}; storage_settings: {datastores: [{datastore_id}]} (list_datastores); customization_settings: {instant_clone_domain_account_id (list_ic_domain_accounts), ad_container_rdn (list_ad_domains + list_ad_containers)}; pattern_naming_settings: {naming_pattern, max_number_of_rds_servers}. settings.desktop_id links the farm to its RDS desktop pool.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare the generic non-read-only/non-destructive flags. The description adds genuinely useful behavioral context: an AUTOMATED farm immediately begins creating VMs in vCenter and should be user-confirmed first — a side effect the flags alone do not convey. It says nothing about permissions or failure/rollback behavior, keeping it below 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short blocks: the purpose is front-loaded, and the caution follows with no filler or redundancy. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A create operation whose full spec is exhaustively documented in the schema, with an output schema present so return values need no description. The description supplies the critical side-effect caveat. Minor gap: no mention of the login/prerequisite context, though siblings cover that.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the single `spec` parameter is documented in exceptional depth inside the schema, including required keys, enum values, and pointer tools (list_base_vms, list_datacenters, etc.). The description adds no parameter meaning beyond that, so the baseline 3 for full schema coverage applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource ("Create a new RDS farm") that an agent can distinguish from create_desktop_pool and the other create_* siblings by resource type. It stops short of explicitly differentiating itself from siblings like update_rdsh_farm or delete_rdsh_farm, so it does not reach the top band.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the verb and reinforced by the warning to confirm with the user before provisioning an AUTOMATED farm, which is a real precondition. However, it never names alternatives (e.g., create_desktop_pool vs. this) or states when a farm is the right choice over a pool, leaving the routing decision to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_application_poolA
Destructive

Delete a published application pool.

CAUTION: Users will immediately lose access to this application. Always confirm with the user before calling this.

ParametersJSON Schema
NameRequiredDescriptionDefault
confirmNoOnly used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.
pool_idYesApplication pool ID — obtain from list_application_pools

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and non-idempotent behavior, so the bar is lower. The description adds material context: users immediately lose access, and user confirmation is required. It stops short of describing reversibility or required privileges.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the verb and resource in one sentence, then immediately follows with the caution and confirmation requirement. No filler text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive delete with an output schema, the description supplies the critical behavioral caveat and confirmation requirement. It leaves minor gaps such as whether deletion is reversible, but annotations and schema cover most of what an agent needs.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents pool_id and confirm. The description adds no parameter-level meaning beyond that baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb ('Delete') and resource ('published application pool'), clearly distinct from sibling deletes for desktop pools and RDSH farms. The scope is explicit enough to route correctly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a clear precondition: always confirm with the user before calling. It warns of immediate loss of access, but does not name alternative deletion tools or when not to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_desktop_poolA
Destructive

Delete a desktop pool and all of its machines.

CAUTION: This is irreversible. All machines in the pool are deleted and any active user sessions are terminated. Always confirm with the user before calling this.

ParametersJSON Schema
NameRequiredDescriptionDefault
confirmNoOnly used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client. Before deleting, call get_desktop_pool and list_sessions (filtered by desktop_pool_id) so you can tell the user what will be affected.
pool_idYesDesktop pool ID — obtain from list_desktop_pools

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true and non-idempotent, but the description adds the crucial facts the annotations cannot convey: the operation is irreversible, all machines go, and active user sessions are terminated. That is exactly the extra context an agent needs before a destructive call.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short parts: the action with scope first, then a front-loaded CAUTION that earns every word. No filler, no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive mutation tool with an output schema already present, the description covers purpose, irreversibility, affected entities, and the confirmation obligation. Nothing an agent needs to decide and call safely is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema itself documents pool_id source and the confirm/HORIZON_CONFIRMATION semantics in detail, so the description need not repeat it. Baseline 3 applies since the description adds nothing beyond the schema for parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (delete) and resource (desktop pool) plus the blast radius ('and all of its machines'). It is clearly distinguishable from siblings like delete_rdsh_farm and delete_application_pool without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use guidance by mandating user confirmation before calling, and the schema reinforces this with the get_desktop_pool/list_sessions pre-check. It does not name a direct alternative, but none is really needed for a terminal delete.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_rdsh_farmA
Destructive

Delete an RDS farm and all of its servers.

CAUTION: This is irreversible. All servers in the farm are deleted and any active user sessions are terminated. Always confirm with the user before calling this.

ParametersJSON Schema
NameRequiredDescriptionDefault
confirmNoOnly used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client. Before deleting, call get_rdsh_farm and list_sessions so you can tell the user what will be affected.
farm_idYesFarm ID — obtain from list_rdsh_farms

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false; the description adds genuinely new behavioral detail beyond them — that the operation is irreversible, that every server in the farm is removed, and that active user sessions are terminated. It omits permission requirements, but the destruction semantics are well disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences: the effect first, then the caution. The destructive consequence and the confirmation requirement are front-loaded with zero filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive tool with an output schema, full annotation coverage, and complete parameter documentation, the description supplies everything an agent needs: what is destroyed, that it cannot be undone, and that user confirmation is mandatory.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters (farm_id, confirm) are documented in the schema, including the HORIZON_CONFIRMATION/elicitation nuance. The description adds no parameter-level detail, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Delete) and resource (RDS farm) and scopes it further with 'and all of its servers'. This clearly distinguishes it from the sibling mutation tools (update_rdsh_farm, rdsh_farm_action) and from delete_desktop_pool/delete_application_pool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit usage guidance ('Always confirm with the user before calling this') and points, via the schema, at the read-first workflow (get_rdsh_farm, list_sessions). It does not explicitly contrast with alternative farm-management siblings, so it stops short of the top score.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

desktop_pool_actionA
DestructiveIdempotent

Enable, disable, or toggle provisioning for one or more desktop pools.

enable/disable controls whether new user sessions can be established. enable-provisioning/disable-provisioning controls whether new VMs are provisioned. Disabling provisioning is the correct way to pause scale-out during maintenance.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesenable: allow new sessions. disable: prevent new sessions (existing sessions continue). enable-provisioning: resume VM provisioning. disable-provisioning: pause VM provisioning — use during maintenance windows.
confirmNoOnly used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.
pool_idsYesList of desktop pool IDs to act on

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=true, so the safety bar is partly covered. The description adds real behavioral nuance beyond that: disabling sessions leaves existing sessions running, and provisioning vs. session control are separate concerns. It does not mention the confirmation flow, slighting an otherwise solid disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tightly scoped sentences, front-loaded with the high-level action list before the per-action semantics. Every sentence earns its place, with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists and annotations cover the mutation profile, so the description need not explain returns. It covers the action semantics well but omits the confirm-parameter behavior and batch semantics for multiple pool_ids, minor gaps for a multi-target action tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including a fully documented enum for action, so the schema already carries the parameter semantics. The description largely restates the action semantics rather than adding format or syntax beyond the schema, matching the baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (enable/disable/toggle) and resource (provisioning for desktop pools), and clarifies the two distinct control surfaces: session admission versus VM provisioning. It is clear, though it does not explicitly differentiate itself from the sibling update_desktop_pool tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear per-action context for when to use each mode, and explicitly states that disabling provisioning is the correct way to pause scale-out during maintenance. It stops short of naming an alternative tool or stating exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

diagnose_sessionA
Read-only

Retrieve diagnostic information for a user session in a single call.

Fetches any combination of: logon timing breakdown, real-time display protocol metrics, 15-minute historical performance, running processes, and active remote applications. Results are keyed by aspect name; a failed aspect returns {"error": ""} rather than failing the whole call.

The help desk endpoints take the session's internal_session_id, not its id (verified live: passing the id returns "Session with requested id was not found"), so this looks the session up first to get it.

ParametersJSON Schema
NameRequiredDescriptionDefault
aspectsNoDiagnostic data to retrieve: logon_timing, display_performance, historical_performance, processes, remote_applications. Defaults to all aspects.
session_idYesSession ID to diagnose

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With readOnlyHint/openWorldHint already covering the safety profile, the description adds genuine behavior: results are keyed by aspect name, a failed aspect returns {"error": ...} instead of aborting the call, and the tool internally resolves internal_session_id. It stops short of permissions or performance/rate-limit context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short paragraphs, front-loaded with purpose and aspect list, then error semantics, then the ID caveat. Each sentence carries information, though the 'verified live' anecdote is slightly more verbose than needed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return formatting need not be restated, and the description covers the remaining essentials: what aspects exist, what partial failure looks like, and the ID resolution quirk. Nothing needed to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description goes beyond it by warning that the underlying help desk endpoints need internal_session_id, not session_id, and that the tool transparently performs that lookup — non-obvious semantics the schema does not capture.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Retrieve diagnostic information for a user session') and enumerates the exact diagnostic aspects it can return, which cleanly separates it from the sibling read tools get_session and list_sessions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Establishes clear context ('in a single call', fetching any combination of aspects) so the agent knows this is the aggregated diagnostic path, but names no explicit exclusions or alternatives such as get_session.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

disconnect_sessionsA
Destructive

Disconnect one or more user sessions (sessions remain active, clients are disconnected).

The user's applications keep running. Use logoff_sessions to fully terminate sessions.

ParametersJSON Schema
NameRequiredDescriptionDefault
confirmNoOnly used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.
session_idsYesList of session IDs to disconnect. The session remains active but the client is disconnected.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, so the safety profile is covered. The description adds genuinely useful nuance beyond them: the session remains active and the user's applications keep running, which softens and disambiguates the 'destructive' hint. It does not discuss confirmation flow or permissions, but the confirm parameter schema covers the former.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with zero waste; the core behavior (sessions stay active, clients disconnect) is front-loaded and the routing hint to logoff_sessions follows. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be described, and annotations plus schema cover safety and parameters. The description supplies the one non-obvious behavioral fact (apps keep running, session survives) and the correct alternative, leaving nothing an agent needs missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (session_ids and confirm) are fully documented in the schema itself. The description adds no syntax, format, or batching detail beyond what the schema provides, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (disconnect) and resource (user sessions) with clear scope (one or more), and explicitly distinguishes itself from the sibling logoff_sessions. An agent can tell it apart from logoff_sessions, reset_or_restart_sessions, and send_message_to_sessions without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It names the alternative explicitly ('Use logoff_sessions to fully terminate sessions') and gives the condition that selects it, so the choice between disconnect and logoff is unambiguous. The parenthetical also clarifies when this tool is the right fit (sessions must remain active).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

end_remote_applicationA
Destructive

Terminate a specific remote application running in a session.

CAUTION: The application will be force-closed. Unsaved data will be lost. Confirm with the user before calling this.

ParametersJSON Schema
NameRequiredDescriptionDefault
confirmNoOnly used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.
session_idYesSession ID
remote_application_idYesRemote application ID to terminate. Use diagnose_session with aspects=['remote_applications'] to find IDs.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, so the description earns credit for going beyond the flag: it states the application is force-closed and that unsaved data will be lost, which tells the agent the concrete consequence rather than a generic 'destructive' label. It also flags the user-confirmation obligation, which is real workflow context not captured by annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences: purpose first, then the CAUTION, then the required action. Every sentence carries distinct information and nothing is padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and full parameter documentation in the schema, the description only needs to carry purpose and risk, which it does. The one remaining gap is that it never situates the tool relative to the session-termination siblings, which matters for a mutation with irreversible effects.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including the confirm parameter's HORIZON_CONFIRMATION behavior and a pointer to diagnose_session for finding remote_application_id. The description adds no parameter meaning beyond what the schema already documents, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (terminate) and resource (a remote application running in a session), with the scope narrowed to a single identified application. It is reasonably distinguishable from the session-level siblings like logoff_sessions and disconnect_sessions, though it never explicitly contrasts itself with them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear precondition for calling — confirm with the user first — but offers no guidance on when to use this versus logoff_sessions, disconnect_sessions, or reset_or_restart_sessions, which are the nearest alternatives for ending session activity. Usage is implied rather than routed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_ad_user_or_groupB
Read-only

Get detailed information about a specific AD user or group.

ParametersJSON Schema
NameRequiredDescriptionDefault
ad_idYesAD user or group ID

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds little behavioral context beyond the read nature, and because it operates on a known ID it does not disclose failure behavior (e.g., what happens for an unknown ID). With annotations carrying the load, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler or redundancy. It is appropriately short for a simple lookup tool, though it errs toward minimalism rather than earning full marks.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple (one param) and an output schema exists, so return values need not be explained. The main gap is the absence of routing information relative to the search sibling and any note on identifier sourcing, leaving the definition adequate but not fully rounded.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for the single ad_id parameter, and the input schema already documents it as 'AD user or group ID'. The description adds no syntax or format detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb (Get) and resource (AD user or group) scoped to 'a specific' item, which distinguishes it from the plural search_ad_users_or_groups and list_ad_* siblings. The phrase 'detailed information' is somewhat vague about what is actually returned, but the core purpose is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use guidance and no mention of the sibling search_ad_users_or_groups that an agent would logically use first to obtain the ad_id. The word 'specific' weakly implies a known identifier is required, but the routing condition is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_api_coverageA
Read-only

List all available Horizon MCP tools, resources, and unsupported operations.

Call this to understand what can be managed via this MCP server before attempting a task, or to accurately inform users which Horizon features are and are not supported.

Returns three sections: tools — all callable tools grouped by function resources — read-only MCP Resources (horizon://) for config and monitor data not_yet_supported — Horizon API operations not yet implemented

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds the return shape (tools/resources/not_yet_supported), which is useful context, but since an output schema exists this partly duplicates structured data and adds nothing about limits or resource URI semantics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded purpose statement followed by a compact usage note and an indented section breakdown. Every sentence earns its place with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema already exists, the description goes slightly beyond what is required by naming all three sections. It remains silent on the horizon:// resource addressing scheme and any size or pagination expectations, so it is complete but not exhaustive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4; there are no inputs whose meaning could be explained further.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: list all available Horizon MCP tools, resources, and unsupported operations. This is a meta/discovery tool clearly distinguishable from the operational siblings (get_settings, list_machines, etc.), and the three-section breakdown makes its scope unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to call it: before attempting a task, or when informing users which features are supported. That is strong positive guidance, but no when-not condition or alternative discovery path is named (there is effectively no sibling alternative, so the gap is minor).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_application_poolB
Read-only

Get detailed information about a specific application pool.

ParametersJSON Schema
NameRequiredDescriptionDefault
pool_idYesApplication pool ID — obtain from list_application_pools

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds nothing beyond that — no error behavior, no note about what happens with an invalid pool_id, and no additional operational context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single efficient sentence with the resource front-loaded and no wasted words. It is appropriately sized, though it is so terse that it leaves useful routing information out.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and the read-only annotations cover safety. With a single fully documented parameter, the definition is largely complete, missing only sibling routing guidance.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema itself explains that pool_id is 'obtain from list_application_pools'. The description adds no further parameter meaning, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get') and resource ('application pool') with the scope qualifier 'specific'. It is clear what the tool does, though it never names the sibling list_application_pools as the counterpart the way a stronger definition would.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use guidance, no prerequisites, and no mention of alternatives such as list_application_pools. Usage is only implied by the word 'specific', which is not enough to route an agent confidently.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_connection_serverC
Read-only

Get configuration details for a specific Connection Server.

ParametersJSON Schema
NameRequiredDescriptionDefault
server_idYesConnection server ID

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, covering the safety profile. The description adds nothing beyond that – no mention of error behavior for invalid IDs, auth requirements, or whether config data is cached/live.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single efficient sentence with no filler, front-loading the verb and resource. It is appropriately sized for a simple getter, though it could have used the space to route against the list sibling.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and annotations cover the read-only nature. Still, for a tool with a closely related sibling it omits the disambiguation that would make it fully self-sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter exists and it is fully documented in the schema (100% coverage). The description adds no syntax or format detail for server_id, so baseline 3 applies; the schema does all the work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Get) and resource (configuration details for a Connection Server), which is clear. However it does not distinguish itself from the sibling list_connection_servers, which an agent must infer from the plural name alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this versus list_connection_servers, nor any prerequisites such as needing a valid server_id or prior login. The agent must infer the single-vs-list distinction from names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_connection_server_healthB
Read-only

Get detailed health information for a specific Connection Server.

ParametersJSON Schema
NameRequiredDescriptionDefault
server_idYesConnection server ID

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds nothing beyond the basic purpose - no note on what 'detailed' includes, latency, permissions, or error behavior - so it earns only a minimum-viable score.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero waste. It is appropriately terse for a simple read tool, though it is so minimal that conciseness comes at the cost of coverage.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations covering safety, a 100%-covered schema, and an output schema handling return values, the core needs are met. However, missing routing guidance relative to get_connection_server and get_infrastructure_health leaves a real gap for a tool in a crowded sibling set.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with the single server_id parameter fully documented in the schema. The description adds no syntax, format, or lookup guidance beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Get detailed health information for a specific Connection Server.' An agent can tell it retrieves health data rather than config, but the description offers no differentiation from close siblings like get_connection_server or get_infrastructure_health.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus get_connection_server or get_infrastructure_health, nor any prerequisites or conditions. The agent must infer usage entirely from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_desktop_poolA
Read-only

Get detailed configuration and status of a specific desktop pool.

Uses the v13 endpoint (not v1) specifically so this response contains every field update_desktop_pool's schema can require — verified live, zero gap. Earlier versions of this tool used v1, whose response is missing most of those fields, making a real get-then-update round trip impossible without guessing at values Horizon never returns.

ParametersJSON Schema
NameRequiredDescriptionDefault
pool_idYesDesktop pool ID — obtain from list_desktop_pools

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds substantial behavioral context beyond annotations: it explains the v13 endpoint choice, why older v1 responses lack fields, and that the completeness was verified live with zero gap for update compatibility.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence front-loads the purpose efficiently. The second paragraph is somewhat detailed about endpoint version history, but it earns its place by justifying the tool's completeness guarantee for update workflows. No significant waste, though it could be tightened.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter get tool with an output schema and read-only annotations, the description is complete enough to call correctly. It covers purpose, parameter origin via schema, and why the response is suitable for update round trips. Return value details are appropriately left to the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the single parameter's description already tells the agent to obtain pool_id from list_desktop_pools. The tool description does not add syntax or format details beyond the schema, so this is the baseline score when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Get detailed configuration and status of a specific desktop pool.' This clearly distinguishes it from the sibling list_desktop_pools, which lists pools rather than retrieving one pool's full configuration.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides important context for when to use this tool: it uses the v13 endpoint so the response contains all fields that update_desktop_pool may require, making a get-then-update round trip possible. However, it does not explicitly state when to prefer this over list_desktop_pools or other get tools, nor does it give formal exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_domain_netbios_mapA
Read-only

Get a mapping of domain NETBIOS names to DNS names for all configured domains.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, covering the safety profile. The description adds the scope ('all configured domains') and the mapping direction (NETBIOS->DNS), which is useful, but nothing about auth needs, caching, or edge cases. With annotations carrying the safety burden, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler; the resource and scope are stated immediately and every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the return shape needn't be explained, and annotations cover the safety profile for this parameterless getter. The description is nearly complete, with only usage routing to sibling tools left implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, so the baseline of 4 applies. No parameter semantics are needed and none are missing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Get') and a precise resource: a NETBIOS-to-DNS name mapping across all configured domains. This is clearly distinguishable from siblings like list_ad_domains, which enumerate domains rather than produce a name-correspondence map.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The scope ('for all configured domains') is implied usage context, but there is no explicit when-to-use guidance and no mention of alternatives such as list_ad_domains for domain enumeration. An agent can infer the use case but is not routed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_environment_propertiesA
Read-only

Get environment-level properties including version, FIPS mode, and feature flags.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safe read-only nature is covered. The description adds useful scope context by naming the categories of properties returned, but it does not disclose anything further about behavior (e.g. whether values are live vs cached). With annotations carrying the safety profile, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that names the action, the resource, and the concrete contents with no filler. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-parameter read tool with an output schema, the description is close to complete: it tells the agent what scope of data it returns while the output schema carries the structure. The only gap is the absence of any sibling disambiguation, which is minor given the distinct name.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is no parameter semantics to document; the schema is empty and coverage is vacuously complete. Baseline 4 applies since the description has nothing it must compensate for.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Get environment-level properties') and enumerates the returned fields (version, FIPS mode, feature flags), so the agent knows exactly what this retrieves. However, it does not differentiate from similarly named siblings such as get_settings or get_api_coverage, leaving some ambiguity about which environment-scoped read tool to pick.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisites, and no mention of alternatives despite several overlapping sibling reads (get_settings, get_api_coverage, get_infrastructure_health). The agent must infer usage purely from the tool name and field list.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_event_databaseA
Read-only

Get the configuration and connection status of the Horizon event database.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds the useful detail that the response covers both configuration and connection status, but says nothing about auth requirements or what a failed/disconnected status looks like.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler; every word earns its place and the resource and scope come first.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only tool with an output schema that carries the return shape, the description is sufficient. Nothing needed to invoke the tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate. Baseline 4 applies for a no-arg tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Get') and resource ('the Horizon event database') with the exact scope of what is retrieved: configuration and connection status. No sibling tool covers the event database, so there is no ambiguity to resolve against the long list of get_* tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no when-to-use guidance, no prerequisites (e.g. that a horizon_login session is needed), and no alternatives. The agent must infer that this is a diagnostic call for checking event database connectivity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_global_policiesA
Read-only

Get global VDI policies including USB redirection, multimedia redirection, clipboard settings, and other environment-wide policy settings.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered by structured data. The description adds the useful 'environment-wide' scoping detail, but adds no further behavioral context such as whether results include inherited/default policies or how large the payload may be.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single well-formed sentence with the resource stated first and the enumeration trailing; every clause earns its place. Slightly list-heavy at the end but far from verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation, and a parameterless read-only call carries few unknowns. The only missing piece is routing context versus get_settings and update_global_policies.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, which is the baseline-4 case; there is no parameter semantics to communicate and the description correctly does not invent any. Score reflects the neutral baseline rather than added value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear verb (Get) plus specific resource (global VDI policies), with an enumeration of the concrete policy categories it returns (USB redirection, multimedia redirection, clipboard). It does not, however, explicitly differentiate itself from the sibling get_settings or acknowledge the paired update_global_policies, so an agent must infer the distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the name and scope; there is no statement of when to call this instead of get_settings, nor any prerequisite or exclusion. With no parameters a caller cannot misuse it badly, but alternative-routing guidance is absent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_infrastructure_healthA
Read-only

Get health and status across Horizon infrastructure in a single call.

Components:

  • summary: overall health rollup across all component types

  • connection_servers: per-server reachability, load, and tunnel counts

  • gateways: Unified Access Gateway connectivity status

  • virtual_centers: vCenter Server connectivity and health

  • ad_domains: Active Directory domain reachability and bind status

  • farms: RDS farm health and server capacity

Results are keyed by component name. A failed component returns its error as a string rather than failing the whole call.

ParametersJSON Schema
NameRequiredDescriptionDefault
componentsNoComponents to check: summary, connection_servers, gateways, virtual_centers, ad_domains, farms. Defaults to all.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds genuinely useful behavioral context beyond that: results are keyed by component name, and a failed component surfaces its error as a string instead of failing the whole call — important partial-failure semantics for an aggregator.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The opening sentence front-loads the capability, and the bulleted component list is easy to scan. It is somewhat long given the component names already appear as schema enum values, but each bullet adds a short gloss that earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and annotations covering safety, the description is nearly complete — it explains scope, component coverage, keying, and partial-failure behavior. It omits authentication/rate-limit context, which is a minor gap for a read-only health aggregator.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single 'components' parameter is already well documented with allowed values and the all-components default. The description restates the same component list without adding selection syntax or semantics beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get health and status across Horizon infrastructure') and scopes it as an aggregate check 'in a single call', which implicitly separates it from per-component siblings like get_connection_server_health and list_virtual_centers. The component enumeration further pins down exactly what is covered.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'single call' framing and component list imply this is the aggregate overview tool, but the description never states when to prefer it over the narrower per-component health/list tools, nor any prerequisites such as prior authentication. Usage is inferable but not explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_machineC
Read-only

Get detailed information about a specific machine.

ParametersJSON Schema
NameRequiredDescriptionDefault
machine_idYesMachine ID — obtain from list_machines

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds nothing beyond that — no auth requirements, no behavior when the machine_id is invalid or the machine is absent. With annotations carrying the load, the description is essentially silent on behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler or redundancy. It is appropriately sized, though its brevity reflects thin content rather than disciplined editing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and a one-param getter has modest requirements. Still, the definition leaves the agent without any usage context, prerequisites, or failure behavior for a tool that fetches a specific entity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single machine_id parameter is already documented with a useful hint ('obtain from list_machines'). The description adds no further parameter meaning, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (get) and resource (machine) with clear scope ('detailed information'). It is distinguishable from list_machines by the singular resource and 'detailed' qualifier, but it never explicitly names or contrasts with its siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no mention of prerequisites, and no reference to alternatives such as list_machines (to discover an ID) or machine_action (to change state). The agent must infer all routing from the tool name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_metricsA
Read-only

Get performance and capacity metrics across the Horizon environment in a single call.

Scopes:

  • pools: session and machine counts per desktop pool

  • sessions: aggregate connected/disconnected/pending session totals

  • machines: aggregate machine state counts across all pools

  • system: CPU and memory metrics for connection servers

  • rds_servers: RDS server state counts across all farms

  • license: current and peak license usage

Results are keyed by scope name. A failed scope returns its error as a string rather than failing the whole call.

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNoMetric scopes to retrieve: pools, sessions, machines, system, rds_servers, license. Defaults to all.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description goes further and discloses non-obvious behavior: results are keyed by scope name, and a failed scope returns its error as a string rather than failing the whole call. That partial-failure contract is exactly the kind of runtime behavior an agent cannot infer from structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded in the first sentence, followed by a scannable scope list and two closing sentences on result shape and failure handling. No filler or redundancy; each sentence carries distinct information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value structure need not be restated. The description covers scope semantics, keying of results, and error behavior, giving the agent everything needed to invoke it correctly and interpret partial results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the enum values themselves are already documented, establishing a baseline of 3. The description adds genuine meaning by explaining what each scope actually measures (e.g., 'system: CPU and memory metrics for connection servers'), which enriches selection of scope values beyond the bare enum.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource ('Get performance and capacity metrics') and enumerates exactly what each scope returns (pool counts, session totals, machine states, CPU/memory, RDS states, license usage). This makes the tool's purpose unambiguous. It does not, however, explicitly differentiate itself from siblings that also surface health/state data such as get_infrastructure_health or get_connection_server_health, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the enumeration of scopes and the 'in a single call' framing, which signals an aggregate/multi-metric use case. But there is no explicit when-to-use, when-not-to-use, or named alternative (e.g., why pick this over get_connection_server_health). Guidance is inferable but not stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_pool_entitlementB
Read-only

Get the users and groups entitled to access a specific pool.

ParametersJSON Schema
NameRequiredDescriptionDefault
pool_idYesPool ID to retrieve entitlements for
pool_typeYesType of pool

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safe read-only nature is covered. The description adds no behavioral details beyond what the annotations and output schema provide, but it does not contradict them either.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single well-formed sentence with no wasted words, clearly front-loading the verb and the resource.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple read-only nature, full schema coverage, annotations, and an existing output schema, the description is largely complete. It misses only an explicit tie-break against sibling entitlement tools, which is a minor gap for a straightforward getter.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents both pool_id and pool_type, including the enum for pool_type. The description adds no syntax or format detail beyond what the schema already supplies, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get') and resource ('users and groups entitled to access a specific pool'), making the purpose clear. It does not, however, differentiate itself from the sibling list_pool_entitlements tool, which likely also deals with pool entitlements.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no explicit guidance on when to use this tool versus alternatives such as list_pool_entitlements or set_pool_entitlements. Usage is implied only by the phrase 'specific pool', but no when-not or alternative routing is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_rdsh_farmB
Read-only

Get detailed information about a specific RDS farm.

Uses the v10 endpoint (not v1) so this response contains every field update_rdsh_farm's schema can require — verified live, zero gap (mirrors the same fix applied to get_desktop_pool).

ParametersJSON Schema
NameRequiredDescriptionDefault
farm_idYesFarm ID — obtain from list_rdsh_farms

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds a genuine behavioral fact (v10 endpoint yields a superset of update_rdsh_farm's fields), but much of the second paragraph is developer meta-commentary ('verified live, zero gap', 'mirrors the same fix applied to get_desktop_pool') rather than agent-facing behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence is well front-loaded and sufficient. The second paragraph mixes one useful fact (v10 completeness) with self-referential justification ('mirrors the same fix applied to get_desktop_pool') that does not help an agent invoke the tool, so it only partially earns its space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no explanation, annotations cover the safety profile, and the single parameter is fully documented. The description adds the endpoint-version rationale needed to trust round-tripping into update_rdsh_farm, making it largely complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter and schema description coverage is 100%, so the schema already documents farm_id and its source. The description adds no parameter-level syntax or format detail beyond that, which is the baseline 3 case.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Get detailed information about a specific RDS farm'), and the get/list contrast with list_rdsh_farms is reinforced by the schema parameter note ('obtain from list_rdsh_farms'). It does not explicitly name the sibling in the prose, so it falls just short of 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The v10 rationale implies a read-then-update workflow (it guarantees the fields update_rdsh_farm needs), and the schema points to list_rdsh_farms for obtaining the ID. However, there is no explicit 'use this when / not when' statement or named alternative, so usage is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_remote_assistance_ticketA
Read-only

Generate a Microsoft Remote Assistance ticket for a user session.

Returns an MSRA connection ticket that allows a help desk technician to view and control the user's desktop session.

ParametersJSON Schema
NameRequiredDescriptionDefault
session_idYesSession ID

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the bar is lower, and the description adds meaningful security-relevant context: the returned ticket grants a technician view AND control of the desktop session. That consequence is not derivable from the schema or annotations and is genuinely useful, though it omits any expiry/lifetime or scoping details for the ticket.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, purpose front-loaded, second sentence supplying the behavioral consequence. No filler, no repetition of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return-value documentation is not required, and the description nevertheless characterizes the return. Annotations cover the safety profile, so for a one-parameter tool this is largely complete; the only real omission is when-to-use guidance.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single parameter (session_id) is fully documented in the schema, so the description adds nothing about parameter meaning. Baseline 3 applies when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Generate a Microsoft Remote Assistance ticket for a user session') and clarifies the artifact produced. It is distinguishable from session-management siblings like get_session or diagnose_session, though it doesn't explicitly contrast with them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description says what the tool produces but gives no guidance on when to reach for it versus the many sibling session tools (get_session, diagnose_session, etc.). No prerequisites, no exclusions, no named alternatives — usage is left entirely to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_sessionB
Read-only

Get detailed information about a specific user session.

ParametersJSON Schema
NameRequiredDescriptionDefault
session_idYesSession ID — obtain from list_sessions

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds nothing beyond that: it does not say what 'detailed information' comprises, whether the session must be active, or what happens when the ID is unknown, so it contributes no behavioral context of its own.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One short, front-loaded sentence with no filler or redundancy. It is efficient, though its brevity is partly under-specification rather than tight writing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter read tool with an output schema and read-only annotations, the definition is close to sufficient: returns need not be described and safety is declared. The only meaningful gap is the absent distinction from list_sessions and diagnose_session.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single parameter is fully documented there, including its provenance ('obtain from list_sessions'), so the baseline of 3 applies. The description adds no format, validation, or sourcing detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a clear verb (Get) and resource (detailed information about a specific user session), so the agent knows it is a point lookup by ID. It does not, however, distinguish itself from close siblings like list_sessions or diagnose_session, leaving the agent to infer where 'detail' ends and 'diagnosis' begins.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance, no prerequisites, and no mention of alternatives such as list_sessions (for enumerating) or diagnose_session (for troubleshooting). The only routing hint, 'obtain from list_sessions', lives in the schema rather than the description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_settingsA
Read-only

Get the global Horizon configuration settings.

Includes client session timeouts, pre-launch settings, display protocol defaults, HTML Access settings, and other global options.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds useful scope context by naming what kinds of settings are bundled into the global response, but says nothing about authentication requirements or the size/shape of the payload.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with the core action front-loaded and the enumeration following as supporting detail. No filler, no repetition of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description still usefully sketches the breadth of the response. The remaining gap is sibling disambiguation against get_environment_properties and get_global_policies, which an agent needs to choose the right call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4. Nothing in the description is needed to explain inputs, and the enumeration of returned setting categories is the only meaningful content.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Get) and resource (global Horizon configuration settings), then enumerates the concrete categories returned (session timeouts, pre-launch, display protocol, HTML Access). This distinguishes it from a generic settings tool, but it never contrasts itself with the closely related get_environment_properties or get_global_policies siblings, so an agent still has to infer which one holds a given setting.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance, no prerequisites, and no mention of the update_settings sibling that pairs with this read. The read-only nature is only implied by the verb 'Get', leaving the agent to guess between this tool, get_environment_properties, and get_global_policies.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

horizon_loginA

Authenticate to Horizon and activate the session for this server.

The tokens are kept server-side: subsequent tool calls work immediately, and when the access token expires (~8 hours) the server renews it automatically with the refresh token. Only short token hints are returned.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesAD domain name, e.g. CORP or corp.example.com
base_urlNoHorizon server URL, e.g. https://horizon.corp.example.com. Defaults to HORIZON_BASE_URL env var if not provided.
passwordYesAD password — masked in logs and server-side traces
usernameYesAD username (without domain prefix)

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations only give a bare safety profile (not read-only, not idempotent, closed-world), while the description adds genuinely useful behavior: tokens are held server-side, the session persists across subsequent calls, the server auto-renews with the refresh token after ~8 hours, and only short token hints come back. That is exactly the context an agent cannot derive from the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with the action and scoped by 'for this server'. The closing note about short token hints is slightly redundant given the output schema exists, but nothing is padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no explanation, and the session/refresh behavior is well covered for an auth tool. The remaining gap is the absence of any guidance on what to do on credential failure or how this interacts with horizon_refresh_token and horizon_logout, plus the fact that four params are accepted while only three are required is never discussed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including defaults, format, and writeOnly masking for the password, so the schema already carries the parameter semantics. The description adds no parameter-level detail such as domain format or base_url fallback, which is the expected baseline 3 when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb (Authenticate) and resource (Horizon) plus the side effect of activating a server-side session, which cleanly separates it from the read-oriented siblings like list_connection_servers. It does not explicitly name horizon_refresh_token or horizon_logout, so sibling differentiation is left implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The token-lifecycle sentence ('subsequent tool calls work immediately', auto-renewal at ~8 hours) implies this is a one-time entry point rather than something to call repeatedly, but there is no explicit when-to-use statement, no precondition checklist, and no pointer to horizon_refresh_token as the alternative once a session exists.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

horizon_logoutB

Invalidate the current Horizon session (access + refresh tokens).

ParametersJSON Schema
NameRequiredDescriptionDefault
base_urlNoHorizon server URL. Defaults to HORIZON_BASE_URL env var.
refresh_tokenNoRefresh token to invalidate. Omit to use the one the server stored at login.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false and destructiveHint=false, so the state-changing nature is covered. The description adds genuinely useful detail that both access AND refresh tokens are invalidated, but says nothing about auth requirements, whether an already-invalid session errors, or idempotency behavior (annotations claim idempotentHint=false, which is questionable for a logout but not contradicted).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence with zero filler that conveys the exact effect of the call. Nothing is wasted and nothing essential is buried.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation, and both parameters are documented in the schema. For a simple token-invalidation tool with full annotation coverage, the description is nearly sufficient; only the routing versus sibling session tools is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: base_url and the optional refresh_token override are fully documented in the schema, including the 'omit to use the stored token' fallback. The description adds no parameter-level meaning beyond that, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (invalidate) and resource (current Horizon session, access + refresh tokens), which is more precise than 'logout' alone. It implicitly differs from logoff_sessions (which terminates user sessions on machines) but never names that sibling or horizon_refresh_token, so differentiation is left to inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisites, and no mention of alternatives such as horizon_login (to start a session) or logoff_sessions (to end a user's remote session). The agent must guess the routing from the description's scope alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

horizon_refresh_tokenA

Exchange the refresh token for a new access token.

Rarely needed: the server already refreshes an expired access token automatically.

ParametersJSON Schema
NameRequiredDescriptionDefault
base_urlNoHorizon server URL. Defaults to HORIZON_BASE_URL env var.
refresh_tokenNoRefresh token to use. Omit to use the one the server stored at login (normally what you want).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare non-read-only, non-idempotent, non-destructive, closed-world. The description adds that automatic refresh normally supersedes this call, which is useful behavior context, but omits whether the stored refresh token is rotated/invalidated and what happens on an invalid token.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, zero waste, with the primary action stated first and the caveat immediately after. Nothing to trim.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and fully documented optional parameters, the description need not explain return values. It covers the main practical concern (when it's needed at all); only edge-case failure behavior is unaddressed, which is minor here.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters (base_url, refresh_token) are documented in the schema, including the 'omit to use the stored token' default. The description adds no parameter-level meaning beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (exchange) and resource (refresh token for access token), so the operation is unambiguous. It does not explicitly differentiate itself from horizon_login/horizon_logout, but the token-exchange semantics are distinct enough on their own.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-not guidance: 'Rarely needed: the server already refreshes an expired access token automatically.' That tells the agent the default path is automatic refresh and this tool is the exception, which is exactly the routing information needed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_ad_containersA
Read-only

List AD containers (OUs) available in a domain for pool provisioning.

The rdn (relative distinguished name) from these results is used as ad_container_rdn in create_desktop_pool's customization_settings (or create_rdsh_farm's automated_farm_settings.customization_settings) to control which OU newly provisioned computers are placed in — NOT provisioning_settings. This is the OU picker equivalent of what the Horizon Console shows during pool creation.

ParametersJSON Schema
NameRequiredDescriptionDefault
domain_idYesAD domain ID — obtain from list_ad_domains

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds the meaningful behavioral context that this is the API equivalent of the Horizon Console OU picker, i.e., a discovery step feeding a provisioning flow. It does not discuss pagination or result size, but the output schema exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose, then downstream usage. The long parenthetical naming both create_desktop_pool and create_rdsh_farm paths is dense but earns its place by preventing a wrong-parameter mistake. Slightly verbose but no filler sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A single-parameter read tool with full schema coverage, an output schema, and annotations covering safety. The description covers the remaining risk (where the rdn is consumed and where it is not), which is exactly the gap needed for correct end-to-end use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

One parameter (domain_id) with 100% schema description coverage, and the schema already says 'obtain from list_ad_domains'. The description's mention of ad_container_rdn refers to another tool's parameter, so it adds no meaning beyond the schema for this tool's own input. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List AD containers (OUs)') plus scope ('available in a domain'), and clarifies the OU concept to separate it from list_ad_domains or search_ad_users_or_groups. An agent can identify exactly what this returns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells the agent where the result goes: the rdn becomes ad_container_rdn in create_desktop_pool's customization_settings (or create_rdsh_farm's automated_farm_settings.customization_settings), and explicitly warns it is NOT provisioning_settings. That is precise downstream routing plus an exclusion.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_ad_domainsA
Read-only

List all Active Directory domains configured in the Horizon environment.

Returns domain details including trust relationships, status, and bind accounts.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds a summary of what the response contains (trust relationships, status, bind accounts), which is some useful context, but since an output schema exists this is largely duplicated and no operational notes (auth scope, environment assumptions) are added.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action and scope, and the second sentence only adds return-value detail. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter read tool with annotations and an output schema, the description is nearly sufficient. The only missing element is any usage routing versus neighboring AD-related tools, which is a minor gap given the simplicity of the operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so per the scoring baseline the schema carries no semantic burden the description must compensate for. Nothing confusing or misleading is present.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List all Active Directory domains configured in the Horizon environment') and names the returned detail set (trust relationships, status, bind accounts). It is clearly distinguishable from siblings like list_ad_containers or list_ic_domain_accounts, though it does not explicitly contrast itself with them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the resource scope: an agent needing the AD domain inventory would pick this. However, the description names no alternatives, prerequisites, or conditions under which this tool should not be used.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_application_poolsA
Read-only

List published application pools in the environment.

Returns {items, count, page, size, pages_fetched, has_more, next_page, truncated}. If has_more is true there may be more results: call again with page=next_page (or narrow the filter), or pass fetch_all=true to fetch pages automatically (stops after 10 pages or 5000 items and sets truncated=true). Never treat a result with has_more=true as the complete list.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number (1-based)
sizeNoResults per page (max 1000)
filterNoHorizon filter JSON string
fetch_allNoFetch successive pages automatically (up to 10 pages / 5000 items). Prefer a filter when you only need a subset.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the read-only annotation, the description discloses the return shape, pagination behavior, automatic fetch limits (10 pages / 5000 items), and the critical warning that has_more=true means the result is not the complete list. This is rich operational context that helps an agent avoid incorrect assumptions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose, then efficiently covers return fields and pagination handling. Every sentence earns its place; there is no redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with an output schema and annotations, this description is complete enough. It explains the key pagination semantics and the has_more warning, so an agent has all the context needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all parameters are already documented. The description still adds value by explaining fetch_all's automatic stopping limits and truncated flag, and by recommending a filter when only a subset is needed, going beyond the schema's basic definitions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'List published application pools in the environment.' It clearly distinguishes this plural list operation from single-item siblings like get_application_pool and from other list tools such as list_desktop_pools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives useful guidance for handling pagination and fetch_all, but it does not explicitly state when to choose this tool over alternatives like get_application_pool or list_desktop_pools. Usage is implied rather than contrasted with siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_audit_eventsA
Read-only

List Horizon audit events (administrative actions and system events).

Useful for reviewing recent changes, troubleshooting, and compliance auditing.

Returns {items, count, page, size, pages_fetched, has_more, next_page, truncated}. If has_more is true there may be more results: call again with page=next_page (or narrow the filter), or pass fetch_all=true to fetch pages automatically (stops after 10 pages or 5000 items and sets truncated=true). Never treat a result with has_more=true as the complete list.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number (1-based)
sizeNoResults per page (max 1000)
filterNoHorizon filter JSON to narrow results by event type, user, or time range
fetch_allNoFetch successive pages automatically (up to 10 pages / 5000 items). Prefer a filter when you only need a subset.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, but the description adds critical pagination behavior: has_more semantics, next_page continuation, fetch_all auto-fetch limits (10 pages / 5000 items), and the truncated flag. It also warns never to treat has_more=true results as complete, which is exactly the kind of behavioral disclosure that prevents agent error.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action and then provides pagination guidance efficiently. The explicit return-field list is somewhat redundant because an output schema exists, but the pagination sentences are essential and well-integrated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the read-only annotations and an output schema, the description still supplies the key operational context an agent needs: use cases, return structure, pagination continuation, auto-fetch limits, and truncation warning. Nothing important for correct invocation appears to be missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description goes beyond the schema by explaining how to use page=next_page, how fetch_all behaves, and why a filter is preferred when a subset is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: list Horizon audit events, scoped to administrative actions and system events. The sibling tools do not include another audit-event lister, so the tool is clearly distinguishable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context with review, troubleshooting, and compliance-auditing use cases. It does not explicitly state when not to use it or name alternative tools, so it falls short of full when/when-not routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_base_vmsA
Read-only

List VMs in vCenter that can be used as base images for instant clone pools/farms.

ParametersJSON Schema
NameRequiredDescriptionDefault
vcenter_idYesvCenter ID to list VMs from. Use list_virtual_centers to get IDs.
datacenter_idNoDatacenter ID to filter by (optional)

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds the meaningful filter that only instant-clone-eligible VMs are returned, but says nothing about pagination, empty results, or result richness beyond what the output schema carries.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence that front-loads the action and the qualifying scope with zero filler. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with a complete schema, an output schema, and annotations covering safety, the description is sufficient to invoke it correctly. It would be fully complete with a brief note on when to prefer it over the vm_templates or base_vm_snapshots siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both vcenter_id and datacenter_id are fully documented in the schema, with the vcenter_id description even pointing to list_virtual_centers. The description adds no parameter-level meaning beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb (List) plus resource (VMs in vCenter) plus a clear scope qualifier (usable as base images for instant clone pools/farms). This distinguishes it from nearby siblings like list_vm_templates and list_base_vm_snapshots, though it never names them explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'base images for instant clone pools/farms' phrasing implies when the tool is relevant, and the schema notes list_virtual_centers for obtaining IDs. However there is no explicit when-to-use/when-not, nor any routing to the template/snapshot siblings an agent might confuse it with.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_base_vm_snapshotsA
Read-only

List snapshots of a base VM that can be used as the image for an instant clone pool or farm.

The result's id is used as base_snapshot_id in create_desktop_pool's or create_rdsh_farm's provisioning_settings when source is INSTANT_CLONE.

CAUTION: don't just pick the first or most recent result. The chosen snapshot must have been taken AFTER the Horizon Agent (with Instant Clone support) was installed and configured on the VM — a snapshot from before that point will provision machines that fail customization (observed live: Horizon reports "AGENT_CUSTOMIZATION_FAULT ... IC Agent missing"). If multiple snapshots exist, check their names/descriptions for one indicating the agent is installed (e.g. containing "agent") rather than an earlier generic checkpoint (e.g. "clean"). When in doubt, ask the user which snapshot to use.

ParametersJSON Schema
NameRequiredDescriptionDefault
base_vm_idYesBase VM ID — obtain from list_base_vms
vcenter_idYesvCenter ID — obtain from list_virtual_centers

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations mark this as a safe read-only operation, and the description adds critical behavioral context beyond that: snapshots taken before Horizon Agent installation will cause AGENT_CUSTOMIZATION_FAULT / IC Agent missing, so names should be checked for agent-related indicators. This is exactly the kind of failure-mode transparency an agent cannot infer from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the tool's purpose, then the downstream usage, then a focused caution. Every sentence earns its place by preventing a known provisioning failure or clarifying snapshot selection.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value details are appropriately left out of the description. The description covers the remaining agent needs: what the tool lists, how the output connects to create_desktop_pool/create_rdsh_farm, and the snapshot-selection pitfall.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema description coverage is 100%, so both vcenter_id and base_vm_id are already documented in the schema. The description adds useful downstream meaning for the returned id, but it does not further explain the input parameters beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Starts with a specific verb and resource: 'List snapshots of a base VM.' It immediately explains the snapshots' purpose as images for instant clone pools or farms, which clearly distinguishes it from sibling tools such as list_base_vms and list_vm_templates.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when and how to use the result: the returned id becomes base_snapshot_id in create_desktop_pool or create_rdsh_farm when source is INSTANT_CLONE. It also warns against naive selection and says to ask the user when in doubt, covering when-not and alternative decision paths.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_connection_serversB
Read-only

List all Horizon Connection Servers in the pod.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds only the pod-scoping context; it says nothing about result volume, pagination, or ordering for what could be a multi-item listing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One short sentence, front-loaded and free of filler. It is appropriately terse for a zero-argument listing tool, though it is arguably too terse to earn a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation. For a zero-param, read-only enumeration the description is largely sufficient; the only gap is routing between this and the singular/health/backup connection-server siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4. There is nothing for the description to clarify and nothing is misrepresented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (Horizon Connection Servers) with scope limited to 'the pod'. It implicitly contrasts with the singular get_connection_server sibling, but never names it, so differentiation is left to inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance and no alternatives named. With siblings like get_connection_server, get_connection_server_health, and trigger_connection_server_backup, an agent gets no explicit signal about when this enumeration is the right choice over those.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_customization_specificationsA
Read-only

List vCenter customization specifications (Sysprep/QuickPrep) available for pool provisioning.

The customization_specification_id from these results is used in create_desktop_pool and create_rdsh_farm provisioning_settings to apply OS customization (hostname, domain join, license key) to provisioned VMs.

ParametersJSON Schema
NameRequiredDescriptionDefault
vcenter_idYesvCenter ID — obtain from list_virtual_centers

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds meaningful context beyond annotations by explaining what the specs are (Sysprep/QuickPrep) and how the id is consumed downstream (hostname, domain join, license key). It says nothing about ordering or filtering, but that is minor given the read-only nature.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with what the tool returns, then the downstream purpose. No filler, and every clause carries information the agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity, one-parameter read-only lister with an output schema present, the description covers identity, prerequisite, and consumer. Return-value details are rightly left to the output schema, so nothing needed to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single vcenter_id parameter already documents its source ('obtain from list_virtual_centers'). The description adds no further parameter syntax or format detail, so the baseline 3 for high-coverage schemas applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource: 'List vCenter customization specifications (Sysprep/QuickPrep) available for pool provisioning.' It names the OS-customization domain and scopes it to pool provisioning, which cleanly separates it from sibling listers like list_vm_templates or list_base_vms.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence supplies the usage context: the returned customization_specification_id feeds create_desktop_pool and create_rdsh_farm provisioning_settings. That effectively tells the agent when to call it (prior to pool/farm creation), though it states no exclusions or explicit alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_datacentersA
Read-only

List datacenters in a vCenter Server.

The datacenter ID is required by list_vm_folders, list_hosts_or_clusters, and create_desktop_pool / create_rdsh_farm provisioning_settings.

ParametersJSON Schema
NameRequiredDescriptionDefault
vcenter_idYesvCenter ID — obtain from list_virtual_centers

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds the downstream-dependency rationale, which is useful, but says nothing about result size, pagination, or behavior when the vCenter has no datacenters.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, both earning their place: the first names the operation, the second explains the value of the output. Nothing is padded or redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be described, and the parameter is fully documented. Purpose plus downstream usage is sufficient for an agent to call this correctly; only minor behavioral detail (e.g. empty results) is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single parameter already documents its origin ('obtain from list_virtual_centers'), so the schema does the heavy lifting. The description adds no syntax or format detail beyond that, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with scope ('List datacenters in a vCenter Server'), which an agent can distinguish from other list_* tools by resource. It stops short of explicit sibling differentiation beyond naming downstream consumers.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence explains why you would call this: the datacenter ID feeds list_vm_folders, list_hosts_or_clusters, and provisioning settings for create_desktop_pool / create_rdsh_farm. That is clear context for sequencing, though there are no explicit when-not conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_datastore_clustersA
Read-only

List datastore clusters (Storage DRS pods) available on a host or cluster.

Use the datastore_cluster_id in create_desktop_pool or create_rdsh_farm provisioning_settings when using Storage DRS for automated datastore placement.

ParametersJSON Schema
NameRequiredDescriptionDefault
vcenter_idYesvCenter ID — obtain from list_virtual_centers
host_or_cluster_idYesHost or cluster ID — obtain from list_hosts_or_clusters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds the useful constraint that results are scoped to a host or cluster and that this feeds provisioning, but says nothing about pagination or result size. With annotations and an output schema carrying most of the load, a 3 is apt.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: the first identifies the resource and its scope, the second states the downstream use. Nothing is redundant and the essential scope is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with an output schema, full parameter coverage, and safety annotations, the description is complete. It supplies the one thing structured fields cannot: why the agent would call this and what to do with the returned id.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters document their source tools (list_virtual_centers, list_hosts_or_clusters). The description adds no input-parameter detail beyond what the schema states, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('List datastore clusters') and disambiguates from the near-name sibling list_datastores by glossing the resource as 'Storage DRS pods'. An agent can distinguish this from listing plain datastores without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent downstream: the returned datastore_cluster_id feeds create_desktop_pool or create_rdsh_farm provisioning_settings when using Storage DRS. It gives clear context but no explicit when-not-to-use rule (e.g., when plain datastores suffice).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_datastoresA
Read-only

List datastores available in vCenter for desktop pool or farm provisioning.

ParametersJSON Schema
NameRequiredDescriptionDefault
vcenter_idYesvCenter ID. Use list_virtual_centers to get IDs.
host_or_cluster_idYesHost or cluster ID. Use list_hosts_or_clusters to get IDs.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds only that datastores are provisioning-relevant; it says nothing about filtering, pagination, or result scope, though an output schema exists to carry return details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single compact sentence with the action and scope front-loaded and no filler. Slightly terse given it omits any routing to related list tools.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter read tool with 100% schema coverage and an output schema covering returns, the description is sufficient to call it correctly. It only lacks sibling differentiation against list_datastore_clusters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and both parameters document their own purpose plus pointer tools (list_virtual_centers, list_hosts_or_clusters). The description adds no additional meaning beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ("List") and resource ("datastores") with scope ("available in vCenter") and a use context ("for desktop pool or farm provisioning"). It does not distinguish itself from the closely named sibling list_datastore_clusters, which an agent would need to choose between.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase "for desktop pool or farm provisioning" implies when the result is useful, but there is no explicit when-to-use, prerequisite, or alternative (e.g., list_datastore_clusters) guidance. Usage is inferable, not stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_desktop_poolsA
Read-only

List all desktop pools (VDI and RDS) in the Horizon environment.

Returns {items, count, page, size, pages_fetched, has_more, next_page, truncated}. If has_more is true there may be more results: call again with page=next_page (or narrow the filter), or pass fetch_all=true to fetch pages automatically (stops after 10 pages or 5000 items and sets truncated=true). Never treat a result with has_more=true as the complete list.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number (1-based)
sizeNoResults per page (max 1000)
filterNoHorizon filter JSON string. Example: {"type":"Contains","name":"name","value":"dev"} — see Horizon REST API docs for full filter syntax.
fetch_allNoFetch successive pages automatically (up to 10 pages / 5000 items). Prefer a filter when you only need a subset.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds real behavioral context beyond that: automatic pagination stops after 10 pages / 5000 items and sets truncated=true, and a has_more=true result must not be treated as complete. It overlaps somewhat with the declared output schema by enumerating the return fields, which slightly dilutes the added value.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded purpose sentence followed by return contract and a clear pagination warning; every sentence is actionable and the critical 'never treat has_more=true as complete' caution is stated plainly. The enumerated return-field list is mildly redundant given a declared output schema, which keeps this from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations, a full output schema, and 100% parameter description coverage, the structured fields carry most of the burden and the description fills the remaining pagination/truncation gap well. It stops short of noting session/auth prerequisites or distinguishing this list from the RDSH-farm and application-pool listings, which is the only real hole for a tool with this many lookalike siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so a baseline of 3 is warranted; the description rises above that by explaining how parameters interact with returned fields (has_more -> page=next_page) and by tying fetch_all to its 10-page/5000-item cap and truncated flag. The filter parameter itself is left entirely to the schema and external Horizon REST docs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List all desktop pools') and scopes it to 'VDI and RDS' pools in the Horizon environment, so an agent knows the resource type. It does not, however, differentiate itself from siblings that look similar — get_desktop_pool (single item), list_rdsh_farms, or list_application_pools — so the reader must infer the boundary themselves.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives strong operational guidance on how to consume results (call again with page=next_page, narrow the filter, or pass fetch_all=true) and explicitly warns not to treat has_more=true as a complete list. It says nothing about when to choose this tool over the sibling listing tools or about prerequisites such as an active Horizon session, so alternative-routing guidance is absent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_gatewaysA
Read-only

List all registered Unified Access Gateways.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds only the 'all registered' scoping note; it says nothing about result volume, whether unreachable gateways are included, or pagination behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence that front-loads the action and resource. Nothing redundant or padded; every word carries meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no explanation, and annotations cover the safety profile for a zero-parameter read. The only real gap is the absence of any usage or prerequisite context, which is minor for a simple inventory call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there are no parameter semantics to document and the baseline of 4 applies. The description correctly implies an unfiltered full listing, consistent with the empty schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and resource ('registered Unified Access Gateways') with a scope qualifier ('all'). It does not differentiate itself from siblings, though no sibling enumerates gateways, so confusion risk is low.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to use this tool, what prerequisites exist, or how it relates to neighboring inventory tools like get_infrastructure_health or list_connection_servers. Usage must be inferred entirely from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_hosts_or_clustersA
Read-only

List hosts and clusters in a vCenter datacenter.

The host_or_cluster_id is required by list_datastores, list_resource_pools, list_network_labels, and create_desktop_pool / create_rdsh_farm provisioning_settings.

ParametersJSON Schema
NameRequiredDescriptionDefault
vcenter_idYesvCenter ID — obtain from list_virtual_centers
datacenter_idYesDatacenter ID — obtain from list_datacenters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds useful dependency context (the ID feeds other calls), but discloses no permission requirements, rate limits, or scoping behavior beyond that. With annotations carrying the safety signal, this is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core purpose and followed by a single high-value dependency note. No filler, and the most important clause (what it lists) comes first.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and annotations cover safety. The description covers purpose and downstream usage, leaving only minor gaps (e.g., relationship to adjacent hierarchy levels) unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters (vcenter_id, datacenter_id) are documented in the schema with sourcing hints. The description adds no parameter-level meaning beyond what the schema provides, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('List hosts and clusters') and scopes it precisely ('in a vCenter datacenter'). This clearly separates it from sibling listers such as list_datacenters and list_virtual_centers, which operate at different levels of the hierarchy.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence supplies real usage context by naming the downstream consumers of the returned host_or_cluster_id (list_datastores, list_resource_pools, list_network_labels, create_desktop_pool, create_rdsh_farm), telling the agent why to call this first. It stops short of explicit when-not guidance, but there is no direct alternative for this resource.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_ic_domain_accountsA
Read-only

List instant clone domain accounts used for provisioning instant clone desktops.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds no behavioral traits beyond that, such as whether accounts are filtered, whether credentials are returned, or any authentication or rate-limit context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence with no wasted words. It states the action and resource immediately and ends without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter list tool with an output schema and read-only annotations, the description is largely sufficient. It identifies the resource clearly, though it could add a brief usage note to be fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero input parameters, so per the rubric the baseline is 4. The description does not need to explain parameters, and it adds no misleading information.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List') and a precise resource ('instant clone domain accounts'), and scopes it to accounts used for provisioning instant clone desktops. This distinguishes it from the many generic list_* siblings. An agent can identify the exact resource without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to use this tool versus alternatives, nor any conditions or prerequisites. Usage is only implied by the tool name and resource description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_image_managementA
Read-only

List image management streams, versions, or tags.

Versions and tags belong to a stream, so Horizon requires a stream ID for them (verified live — omitting it returns 400 "im_stream_id parameter is missing"). List streams first, then pass a stream's id as stream_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
resourceYesImage management resource to list: streams (publishing pipelines), versions (published images), tags (pool targets).
stream_idNoImage stream ID — required for versions and tags. Obtain from resource='streams'.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds real value by disclosing the verified failure mode (omitting stream_id returns 400 'im_stream_id parameter is missing'), which is behavioral detail not present in the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler, front-loaded with the resource list and followed by the dependency workflow. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described. With annotations covering safety and the schema covering both params, the description supplies the only missing operational piece — the stream_id prerequisite and its error behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%; both parameters, including the enum values, are already documented in the schema. The description reinforces the stream_id dependency but adds no syntax/format detail beyond it, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (image management streams, versions, or tags), and enumerates the three listable resource types. It is clear what the tool returns, though it does not explicitly distinguish itself from any similarly-named sibling (none of which overlap in this domain).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit sequencing guidance: list streams first, then pass a stream's id as stream_id for versions/tags. It states the condition under which stream_id is required. No alternatives exist among siblings, so there is little else to route against.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_licensesA
Read-only

List all Horizon licenses and their status, mode, and expiry information.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds nothing beyond the resource scope, and enumerating 'status, mode, expiry' duplicates what the existing output schema already conveys.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One efficient sentence with the resource front-loaded. It is appropriately sized, though the trailing field list is partly redundant with the output schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A parameterless read-only list tool with an output schema and clear annotations needs little prose; the description is complete enough for correct invocation, with only minor missing context about scope.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Zero parameters, so baseline is 4; there is nothing for the description to disambiguate and no parameter semantics are required.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource ('List all Horizon licenses') with the returned attributes named (status, mode, expiry). It is clear what the tool does, though it does not differentiate itself from siblings beyond the unique license resource.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The listing intent is self-evident and there are no competing license siblings, but the description offers no explicit when-to-use context or exclusions (e.g., whether it covers all license types or requires an admin session).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_machinesA
Read-only

List machines (virtual desktops) in the environment.

To filter by pool, use: filter={"type":"Equals","name":"desktop_pool_id","value":""} To filter by state, use: filter={"type":"Equals","name":"state","value":"AVAILABLE"}

Returns {items, count, page, size, pages_fetched, has_more, next_page, truncated}. If has_more is true there may be more results: call again with page=next_page (or narrow the filter), or pass fetch_all=true to fetch pages automatically (stops after 10 pages or 5000 items and sets truncated=true). Never treat a result with has_more=true as the complete list.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number (1-based)
sizeNoResults per page (max 1000)
filterNoHorizon filter JSON string. Example: {"type":"Equals","name":"desktop_pool_id","value":"<pool-id>"}
sort_byNoField name to sort by, e.g. name
order_byNoSort direction: ASC or DESC
fetch_allNoFetch successive pages automatically (up to 10 pages / 5000 items). Prefer a filter when you only need a subset.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false. The description goes well beyond them by disclosing pagination semantics, truncation behavior, automatic fetch limits (10 pages / 5000 items), and the critical warning that has_more=true means the list is incomplete.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose, then gives filter examples, return information, and pagination guidance in a compact, well-structured form. Every sentence supports correct invocation or result interpretation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a paginated list tool with a full input schema, read-only annotations, and an output schema, the description supplies complete operational context: filtering syntax, return shape, pagination controls, and the safety warning about incomplete results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters. The description still adds practical meaning by giving exact filter JSON examples and explaining how page, next_page, and fetch_all interact, which is more than the schema alone provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: listing machines (virtual desktops) in the environment. Clear enough to distinguish from mutation tools like machine_action, but it does not explicitly differentiate itself from get_machine or list_desktop_pools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides concrete usage guidance for filtering by pool and state, and explains pagination behavior. It does not explicitly state when to choose this over sibling tools such as get_machine or list_desktop_pools, but the operational context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_network_interface_cardsA
Read-only

List the network interface cards (NICs) on a base VM or VM template.

Horizon requires either base_vm_id (instant-clone pools/farms, optionally with base_snapshot_id) or vm_template_id (full-clone pools) — verified live, omitting both returns 400.

Each result's id is the network_interface_card_id in the top-level nics array of create_desktop_pool / create_rdsh_farm: "nics": [{"network_interface_card_id": "", "network_label_assignment_specs": [...]}]

ParametersJSON Schema
NameRequiredDescriptionDefault
base_vm_idNoBase VM ID — obtain from list_base_vms. Either this or vm_template_id is required.
vcenter_idYesvCenter ID — obtain from list_virtual_centers
vm_template_idNoVM template ID — obtain from list_vm_templates. Either this or base_vm_id is required.
base_snapshot_idNoBase snapshot ID — obtain from list_base_vm_snapshots (optional, with base_vm_id)

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds real behavioral context beyond that: the live-verified 400 failure mode when neither ID is supplied, and the fact that each result's id maps to network_interface_card_id consumed by pool/farm creation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short blocks, first sentence front-loads the core action. The embedded JSON snippet for the nics array is slightly bulky but earns its place by showing the exact field name to reuse. Minimal waste overall.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be explained, and the description still goes further by tying results to create_desktop_pool / create_rdsh_farm. Preconditions are fully covered, though it does not mention ordering, pagination, or empty-result behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter is already documented in the schema, including the either/or requirement for base_vm_id and vm_template_id. The description restates that requirement rather than adding new syntax or format detail, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the network interface cards (NICs)') and immediately narrows the scope to base VMs or VM templates. No sibling tool lists NICs, and the qualifier makes it unmistakable which entities are covered.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete usage conditions: Horizon requires either base_vm_id (instant-clone pools/farms, optionally with base_snapshot_id) or vm_template_id (full-clone pools), and notes that omitting both returns a 400. It also points to the downstream consumers (create_desktop_pool / create_rdsh_farm). It stops short of naming an alternative tool to use instead, so it is clear context rather than full when/when-not routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_network_labelsA
Read-only

List network labels (port groups / distributed port groups) available on a host or cluster.

Network label IDs are used in the nics array of create_desktop_pool and create_rdsh_farm provisioning_settings: "nics": [{"nic_id": "", "network_label_id": ""}]

ParametersJSON Schema
NameRequiredDescriptionDefault
vcenter_idYesvCenter ID — obtain from list_virtual_centers
host_or_cluster_idYesHost or cluster ID — obtain from list_hosts_or_clusters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds genuine behavioral context beyond that: the semantic nature of the resource (port group vs distributed port group) and the downstream consumption pattern of the returned IDs. It omits pagination/filtering behavior, keeping it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose sentence is front-loaded and the second block is a compact JSON snippet showing exactly how the returned ID is consumed, which earns its space. Slightly dense, but no filler sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and the parameter provenance is documented in the schema. Description covers purpose, scope and cross-tool integration; only minor gaps remain (e.g., behavior when no labels match).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters already carry provenance hints (obtain from list_virtual_centers / list_hosts_or_clusters). The description only reinforces the host-or-cluster scoping already implied by the schema, adding no format or validity detail. Baseline 3 when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Starts with a specific verb ("List") plus resource ("network labels") and disambiguates the concept as "port groups / distributed port groups", scoped to "a host or cluster". An agent can distinguish it from siblings like list_network_interface_cards or list_hosts_or_clusters without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the operational context well: the returned IDs feed the nics array of create_desktop_pool and create_rdsh_farm, which tells the agent when this tool belongs in a workflow. It does not state exclusions or name an alternative, so it stops short of full when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_pool_entitlementsA
Read-only

List entitlements for all pools of the given type.

Returns which users and groups are entitled to each pool. Use get_pool_entitlement for a specific pool's details.

ParametersJSON Schema
NameRequiredDescriptionDefault
pool_typeYesType of pool

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered there. The description adds useful return-shape context ("which users and groups are entitled to each pool"), but says nothing about pagination, result size, or how entitlements are ordered. Given the annotations carry the safety burden, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with zero waste: the primary scope statement is front-loaded, followed by the return contents and the sibling pointer. Nothing needs to be re-read or clipped.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description needn't detail return format, and annotations cover the safety profile; the one required param is fully documented in the schema. What remains missing is minor guidance such as result size or whether entitlements can be filtered by user or group, but nothing essential to a correct call is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single pool_type parameter already carries an enum and description. The phrase "of the given type" in the description maps directly onto that enum but adds no syntax or semantics beyond it. Baseline 3 is correct when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (entitlements for pools of a given type), and explicitly scopes it to all pools rather than one. It names the sibling get_pool_entitlement as the single-pool alternative, so an agent can distinguish the two without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent to get_pool_entitlement for a specific pool's details, giving a clear use case for the alternative. It does not, however, mention set_pool_entitlements as the mutation counterpart, so the read-only vs. write boundary is left implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_rdsh_farmsA
Read-only

List all RDS (Remote Desktop Session Host) farms in the environment.

Returns {items, count, page, size, pages_fetched, has_more, next_page, truncated}. If has_more is true there may be more results: call again with page=next_page (or narrow the filter), or pass fetch_all=true to fetch pages automatically (stops after 10 pages or 5000 items and sets truncated=true). Never treat a result with has_more=true as the complete list.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number (1-based)
sizeNoResults per page (max 1000)
filterNoHorizon filter JSON string
fetch_allNoFetch successive pages automatically (up to 10 pages / 5000 items). Prefer a filter when you only need a subset.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only and non-open-world safety, so the bar is lower, and the description still adds meaningful pagination behavior: the fetch_all cap of 10 pages / 5000 items and the truncated flag. It does not cover auth or rate limits, but the pagination disclosure is genuinely valuable beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the verb and resource, and the pagination guidance is appropriately dense. The explicit field list {items, count, page, size, ...} duplicates the output schema and is the one redundant segment.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema and full schema coverage exist, so return-value detail is largely redundant, yet the description supplies the pagination contract an agent actually needs to call this correctly. Nothing essential is missing for a read-only list tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description restates fetch_all's behavior (10 pages / 5000 items) and page=next_page, which the schema already documents, adding little new meaning for the four parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) plus a precise resource (RDS / Remote Desktop Session Host farms), and even expands the acronym. It is plainly distinguishable from the singular sibling get_rdsh_farm without needing to open a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear operational guidance for following pagination (page=next_page, narrow the filter, or fetch_all=true) and a strong 'never treat has_more=true as complete' rule. It does not explicitly compare itself to sibling list/get tools, so it falls short of the top tier.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_resource_poolsA
Read-only

List resource pools on a host or cluster.

The resource_pool_id is required by create_desktop_pool and create_rdsh_farm provisioning_settings.

ParametersJSON Schema
NameRequiredDescriptionDefault
vcenter_idYesvCenter ID — obtain from list_virtual_centers
host_or_cluster_idYesHost or cluster ID — obtain from list_hosts_or_clusters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds downstream-consumption context (who needs the ID) but no behavior beyond that, such as result scoping per host/cluster, so a baseline 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with zero padding. The core action is front-loaded and the follow-on dependency is stated immediately after.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter read-only list tool with full schema coverage, an output schema, and annotations, this covers what an agent needs to invoke it correctly and understand why. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters already document where their values come from (list_virtual_centers, list_hosts_or_clusters). The description adds nothing parameter-specific, so the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource with scope ('List resource pools on a host or cluster'), which clearly distinguishes it from siblings like list_desktop_pools and list_rdsh_farms. It stops short of explicitly naming an alternative, but the purpose is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence gives a concrete reason to call it: the returned resource_pool_id is required by create_desktop_pool and create_rdsh_farm provisioning settings, effectively routing the agent to call this before those tools. No when-not guidance or exclusions are given, but the usage context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_sessionsA
Read-only

List active user sessions in the environment.

Common filter fields: user_name, desktop_pool_id, machine_name, client_name, state. Session states: CONNECTED, DISCONNECTED, PENDING.

Returns {items, count, page, size, pages_fetched, has_more, next_page, truncated}. If has_more is true there may be more results: call again with page=next_page (or narrow the filter), or pass fetch_all=true to fetch pages automatically (stops after 10 pages or 5000 items and sets truncated=true). Never treat a result with has_more=true as the complete list.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number (1-based)
sizeNoResults per page (max 1000)
filterNoHorizon filter JSON string. Example: {"type":"Equals","name":"desktop_pool_id","value":"<id>"} or {"type":"Equals","name":"user_name","value":"jsmith"}
sort_byNoField to sort by, e.g. user_name, start_time
order_byNoSort direction: ASC or DESC
fetch_allNoFetch successive pages automatically (up to 10 pages / 5000 items). Prefer a filter when you only need a subset.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds genuine behavioral context beyond that: return shape, pagination termination limits (10 pages / 5000 items), the truncated flag, and an explicit warning never to treat has_more=true as complete. It does not cover auth or rate-limit behavior, keeping it at 4.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, then compactly organized into filter fields, states, and the return/pagination contract. Every sentence earns its place and there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a paginated list tool with an output schema, the description supplies exactly what the schema cannot: how to interpret has_more/next_page/truncated and how to continue. Nothing an agent needs to call and iterate correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaning the schema lacks: the session state enum values (CONNECTED, DISCONNECTED, PENDING) and the field names accepted by the opaque filter JSON (user_name, desktop_pool_id, machine_name, client_name, state). It does not document sort_by/order_by interactions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List active user sessions') plus scope ('in the environment'), which is clear and actionable. It does not explicitly differentiate from siblings like get_session or diagnose_session, so it falls short of the 5 bar for sibling distinction, but the purpose itself is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Offers real usage context: common filter fields, valid session states, and explicit pagination guidance (call again with page=next_page, narrow the filter, or fetch_all=true). It never explicitly says when-not to use it vs alternatives such as get_session, so it is clear but not fully routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_virtual_centersA
Read-only

List all vCenter Servers configured in the Horizon environment.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safe-read profile is covered. The description adds only the environment scoping ('configured in the Horizon environment') and implies no filtering (zero params), but says nothing about pagination or result size; with an output schema present, the remaining gap is modest.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that states the action and scope with no filler. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only list tool with annotations covering safety and an output schema covering return values, the description supplies what an agent needs. A brief note on ordering or result volume would make it complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to document and the baseline of 4 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and a distinct resource (vCenter Servers) scoped to the Horizon environment. The resource is unambiguous and clearly separable from siblings like list_connection_servers or list_datacenters, though it does not explicitly name an alternative to differentiate against.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisites, and no mention of alternatives among the many list_* siblings. Usage is only implied by the resource name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_vm_foldersA
Read-only

List VM folders in a vCenter datacenter for use in pool/farm configuration.

ParametersJSON Schema
NameRequiredDescriptionDefault
vcenter_idYesvCenter ID
datacenter_idYesDatacenter ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds that both a vCenter and datacenter scope are needed, but discloses nothing further about pagination, volume, or permissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero waste; the purpose and its intended use are both conveyed efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the parameters are fully documented in the schema. For a simple scoped read tool this is essentially complete, with only minor opportunity to note relationship to sibling inventory tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both vcenter_id and datacenter_id. The description only implies the vCenter/datacenter scoping, adding no format or syntax detail beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (VM folders) scoped to a vCenter datacenter, and distinguishes itself from the many sibling list_* tools by resource type. It is clear what is returned, though it does not explicitly differentiate from related inventory tools like list_base_vms or list_datastores.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Adds the context of use ('for use in pool/farm configuration'), telling the agent this feeds pool/farm provisioning. It does not name alternatives or state when not to use it, but the usage context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_vm_templatesA
Read-only

List VM templates available in vCenter for use as pool base images.

Templates are used for full-clone or linked-clone desktop pools (source=FULL_CLONE or LINKED_CLONE). Use the template_id in create_desktop_pool provisioning_settings instead of parent_vm_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
vcenter_idYesvCenter ID — obtain from list_virtual_centers
datacenter_idNoDatacenter ID — obtain from list_datacenters (optional)

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations supply readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds real context beyond that: what these templates are for (pool base images), which pool clone modes consume them, and how the returned IDs are used downstream. It does not mention scope, permissions, or pagination.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with what the tool lists, followed by the applicability constraint and the next-step instruction. No filler or restatement of the name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description covers purpose, applicability, and next step for a simple two-parameter read tool. Minor gap: no note on scope of listing (per-datacenter vs per-vCenter) or whether results can be empty.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% (vcenter_id and datacenter_id both documented with sources and optionality), so the schema carries the parameter burden. The description adds no parameter syntax or format detail, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb + resource ('List VM templates available in vCenter') plus the intended purpose ('use as pool base images'). It does not explicitly distinguish itself from the sibling list_base_vms / list_base_vm_snapshots, which an agent could easily confuse with templates, but the purpose itself is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clear downstream guidance: 'Use the template_id in create_desktop_pool provisioning_settings instead of parent_vm_id' names the consuming tool and the field alternative. It also scopes applicability to FULL_CLONE or LINKED_CLONE pools. No explicit when-not-to-use case is given, but the routing context is strong.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

logoff_sessionsA
Destructive

Log off one or more user sessions, terminating their running applications.

CAUTION: This will close all running applications in the session. Unsaved data will be lost. Always confirm with the user before calling this.

ParametersJSON Schema
NameRequiredDescriptionDefault
forcedNoIf true, log off locked sessions. If false, locked sessions are skipped.
confirmNoOnly used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.
session_idsYesList of session IDs to log off

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, but the description adds concrete impact detail beyond them: running applications are closed and unsaved data is lost. The explicit user-confirmation requirement is useful behavioral context. It stops short of explaining interaction with the forced/confirm parameters, which the schema covers.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences with the action front-loaded and the caution clearly delineated. Efficient, though the warning repeats the destructive implication already carried by the annotations, adding slight redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and rich annotations, the description only needs to supply safety and confirmation context, which it does. The missing piece is routing among sibling session-termination tools, a minor gap for this otherwise complete definition.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters including forced and confirm are already documented in the schema. The description adds only that multiple sessions can be targeted via 'one or more', which is marginal value beyond the schema baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (log off) plus resource (user sessions) and clarifies the effect (terminating running applications). It does not explicitly differentiate itself from close siblings like disconnect_sessions or reset_or_restart_sessions, leaving the agent to infer the distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a clear precondition (always confirm with the user) but gives no guidance on when to choose this over disconnect_sessions or other session-terminating siblings. Usage is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

machine_actionA
Destructive

Perform a bulk action on one or more machines.

Actions:

  • shutdown: gracefully power off (use force=true to override active sessions)

  • restart: reboot the machine (use force=true to override active sessions)

  • reset: hard reset (power cycle) — may cause data loss

  • rebuild: re-provision the machine from the pool's image

  • recover: recover a machine stuck in an error state

  • enter_maintenance: put machine into maintenance mode (prevents new sessions)

  • exit_maintenance: take machine out of maintenance mode

  • archive: initiate machine archival

CAUTION: rebuild and reset are destructive and will discard unsaved user data. Always confirm with the user before calling these actions.

ParametersJSON Schema
NameRequiredDescriptionDefault
forceNoForce the operation even if sessions are active. Only applies to shutdown and restart — raises an error for other actions.
actionYesAction to perform on the machines
confirmNoOnly used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.
machine_idsYesList of machine IDs to act on

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations give only a blanket destructiveHint=true; the description goes further by naming which specific actions are destructive (reset, rebuild), warning that unsaved user data is discarded, noting reset is a hard power cycle, that maintenance mode prevents new sessions, and that force only applies to shutdown/restart. This is materially more useful than the annotation alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded one-line purpose followed by a compact per-action bullet list and a caution block; every sentence carries information and a reader can scan to the relevant action immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists, the description need not cover return values, and it supplies everything else an agent needs: the full action vocabulary, which actions are destructive, force applicability, and confirmation behavior. No material gap remains for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and each parameter is already documented in the schema, including force's restriction to shutdown/restart. The prose repeats that force overrides active sessions but adds no syntax, format, or edge-case detail beyond the structured fields, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (bulk action) and resource (machines) and enumerates the exact action set. It is clearly distinguishable from sibling action tools like desktop_pool_action and rdsh_farm_action by scoping to machines.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Each action carries inline guidance (force semantics, when to use recover, that maintenance blocks new sessions) and there is an explicit caution plus a directive to confirm destructive actions with the user. What is missing is routing guidance against alternatives such as desktop_pool_action or when to use single-machine tools instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

rdsh_farm_actionA
DestructiveIdempotent

Enable or disable one or more RDS farms.

Disabling a farm prevents new sessions from being routed to it without terminating existing sessions — useful for draining a farm before maintenance.

Unlike desktop pools, farms have no bulk enable/disable endpoint, and Horizon's farm update schema requires several fields beyond "enabled" (verified live — a naive partial-body PUT gets rejected). So this fetches each farm's full current state first, changes only "enabled", and PUTs the complete spec back — a real get-then- update round trip, not a guess. Reports per-farm results if any still fail.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesenable: allow new sessions to this farm. disable: prevent new sessions (existing sessions continue until they end).
confirmNoOnly used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.
farm_idsYesList of RDS farm IDs to act on

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial behavior beyond annotations: disable does not terminate existing sessions, there is no bulk endpoint, Horizon's farm update schema rejects partial bodies, so it does a real get-then-update round trip, and it reports per-farm failures. Annotations already flag destructive/idempotent, and the description enriches rather than repeats them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action then layers rationale. Most sentences earn their place, though the 'verified live — a naive partial-body PUT gets rejected' aside is slightly editorial for a tool description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so returns need not be explained, and the description still notes per-farm result reporting. For a mutation tool with full annotations and complete schema, everything an agent needs to call it correctly is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all three parameters (action enum, farm_ids, confirm) are already documented in the schema. The description reinforces the action semantics but adds no new syntax or format detail beyond the structured fields, matching the baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (enable/disable) and resource (RDS farms) with scope (one or more). It is clearly distinguishable from siblings like update_rdsh_farm (spec editing) and desktop_pool_action (different resource).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete use case — draining a farm before maintenance — and contrasts with desktop pools which have a bulk endpoint. It does not explicitly say when to prefer this over update_rdsh_farm, so it stops short of full alternative-routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

reset_or_restart_sessionsA
Destructive

Reset or restart the virtual machine backing one or more sessions.

CAUTION: Both actions will terminate the user's session. reset is a hard power-cycle and may cause data loss. restart attempts a graceful reboot but the session will still end. Always confirm with the user before calling this.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesreset: hard power-cycle the VM (immediate, may cause data loss). restart: graceful reboot of the VM (user is logged off first).
confirmNoOnly used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.
session_idsYesList of session IDs to act on

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and non-idempotent, and the description adds the crucial consequences: both actions terminate the session, reset may cause data loss, restart still ends the session even though it is graceful. This is exactly the extra consequence detail a destructive tool needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short lines, each earning its place: purpose first, then the two per-action cautions, then the confirmation requirement. No filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive two-action tool with an output schema already present, the description covers impact, reversibility implications, and the confirmation prerequisite. Nothing an agent needs to call it safely is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including the action enum semantics and the confirm-flag behavior, so the schema already carries parameter meaning. The description reinforces reset-vs-restart but adds no syntax or values beyond what the schema provides; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Reset or restart the virtual machine backing one or more sessions') and immediately distinguishes the two modes operationally (hard power-cycle vs graceful reboot). An agent can tell exactly what this does and how reset differs from restart without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear when-to-use guidance for the two actions and a strong precondition ('Always confirm with the user before calling this'). It does not, however, route the agent against siblings like logoff_sessions, disconnect_sessions, or machine_action, which is the main gap.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_ad_users_or_groupsA
Read-only

Search for AD users and groups in the Horizon environment.

Use the returned 'id' field when setting pool entitlements.

Common filter fields: name, login_name, group, domain. Example filters: Find user by login: {"type":"Equals","name":"login_name","value":"jsmith"} Find by display name: {"type":"Contains","name":"name","value":"John"} Groups only: {"type":"Equals","name":"group","value":"true"}

Returns {items, count, page, size, pages_fetched, has_more, next_page, truncated}. If has_more is true there may be more results: call again with page=next_page (or narrow the filter), or pass fetch_all=true to fetch pages automatically (stops after 10 pages or 5000 items and sets truncated=true). Never treat a result with has_more=true as the complete list.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number (1-based)
sizeNoResults per page (max 1000)
filterNoHorizon filter JSON. Example to search by name: {"type":"Contains","name":"name","value":"john"} or by login: {"type":"Equals","name":"login_name","value":"jsmith"}
fetch_allNoFetch successive pages automatically (up to 10 pages / 5000 items). Prefer a filter when you only need a subset.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint and openWorldHint; the description goes well beyond them by disclosing pagination semantics, the truncation flag, the 10-page/5000-item ceiling on fetch_all, and the rule never to treat has_more=true as a complete list. This is exactly the operational context an agent needs and cannot get from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads purpose, then examples, then return-shape and pagination rules in a scannable block. It runs a bit long and partially repeats the schema's filter example, but no sentence is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, yet the description still summarizes the return envelope and the has_more/next_page contract that governs correct repeated invocation. Combined with the filter and fetch_all guidance, nothing needed to call this tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so the baseline is 3, but the description adds real meaning: it enumerates common filter field names (name, login_name, group, domain) and links fetch_all's stop conditions to the truncated flag. The filter examples duplicate the schema's example somewhat, keeping this from a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Search) and resource (AD users and groups) scoped to the Horizon environment, and adds the downstream purpose (use the returned 'id' when setting pool entitlements). An agent can distinguish this from get_ad_user_or_group (single lookup) and list_ad_domains without opening another schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete filter recipes for the three main retrieval patterns (by login, by display name, groups only) plus explicit pagination guidance (call again with page=next_page, narrow the filter, or use fetch_all). It does not explicitly name the closest sibling (get_ad_user_or_group) or say when a single-record fetch is preferable, so it stops just short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_message_to_sessionsA

Send a pop-up notification message to one or more active user sessions.

ParametersJSON Schema
NameRequiredDescriptionDefault
messageYesMessage text to display to the user(s)
session_idsYesList of session IDs to message
message_typeNoMessage severity/icon displayed in the notificationINFO

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false, and idempotentHint=false. The description adds useful context that this is a pop-up notification delivered to active sessions, but omits notable behavior: what happens on retry (non-idempotent duplicates), whether offline/inactive sessions are skipped, and any delivery guarantees.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single well-formed sentence with zero filler, front-loading the action and target. Nothing redundant or missing for the sentence's scope.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations covering the safety profile and a 100%-documented schema plus an output schema, the description is nearly complete for a simple notification tool. Minor gaps remain around session-state preconditions and retry behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including the message_type enum with a documented default, so the schema carries the parameter burden. The description adds no syntax, format, or constraint details beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (send), resource (pop-up notification message), and scope (one or more active user sessions). An agent can distinguish this from sibling session tools like disconnect_sessions or logoff_sessions without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'active user sessions' implies a precondition, but there is no explicit when-to-use, when-not-to-use, or alternative guidance. No mention of how this differs from other session-management siblings or what to do if sessions are inactive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

set_pool_entitlementsA
Destructive

Add, replace, or remove entitlements for a desktop or application pool.

CAUTION: action='replace' removes any existing entitlements not in the provided list. CAUTION: action='remove' immediately revokes access for the specified principals. Always confirm with the user before using replace or remove.

NOTE: action='replace' is only supported for desktop pools — the Horizon API has no bulk-replace endpoint for application pools.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesadd: merge with existing entitlements. replace: overwrite all existing entitlements with this list. remove: revoke access for the specified users/groups.
confirmNoOnly used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.
pool_idYesPool ID to modify entitlements for
pool_typeYesType of pool
ad_user_or_group_idsYesAD user or group IDs. Use search_ad_users_or_groups to find IDs.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true and idempotentHint=false, but the description goes well beyond them: it spells out exactly what replace destroys (entitlements not in the list), that remove immediately revokes access, the mandatory user-confirmation step, and an API-level limitation on replace for application pools. This is precisely the extra context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The opening sentence front-loads the purpose, followed by two scoped cautions and one limitation note. Every sentence earns its place; no restatement of the tool name or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive mutation tool, the description covers destruction semantics, confirmation requirements, and API constraints, while annotations handle the safety profile and an output schema exists to describe returns. Nothing an agent needs to invoke it safely is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds a genuine constraint absent from the schema: the interaction between action='replace' and pool_type (desktop-only). That cross-parameter rule meaningfully enriches parameter semantics beyond the field descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb set (add/replace/remove) against a named resource (entitlements for a desktop or application pool), which distinguishes it immediately from read-only siblings like list_pool_entitlements and get_pool_entitlement. An agent can tell what the tool does without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear behavioral guidance for each action mode and adds two decisive constraints: confirm before replace/remove, and replace is unsupported for application pools. It stops short of naming sibling alternatives (e.g., list_pool_entitlements, search_ad_users_or_groups) that would round out tool-level routing, so it is strong but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

trigger_connection_server_backupA

Initiate an immediate backup of one or more Connection Servers.

CAUTION: This triggers an active backup operation, not a validation check. If no server_ids are provided, all Connection Servers are backed up.

ParametersJSON Schema
NameRequiredDescriptionDefault
server_idsNoConnection server IDs to back up. If omitted, all Connection Servers are backed up.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false and idempotentHint=false, so the write/side-effect profile is covered. The description adds real value beyond that by warning that this performs an actual backup rather than a validation check, which is exactly the kind of trap an agent could fall into.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action, then a clearly labeled CAUTION that earns its place by preventing a mis-invocation. No filler, though the second sentence partially duplicates the schema's parameter description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation, and the mutation semantics, default scope, and the non-validation warning are all present. Minor gaps are the absence of permission/auth requirements and of any note about the consequences of repeated invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single parameter's description already documents the 'omit to back up all servers' behavior, so the description's restatement adds little. Baseline 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Initiate') and resource ('backup of one or more Connection Servers') with unambiguous scope. It is clearly distinguishable from read-oriented siblings such as list_connection_servers and get_connection_server_health.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The caution correctly disambiguates this from a validation check and the description notes the no-argument default of backing up all servers, which is genuine usage context. However, it names no alternatives and gives no prerequisites or conditions under which a targeted backup is preferable to a full one.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_application_poolA
DestructiveIdempotent

Update an existing application pool's configuration.

Horizon returns supported_file_types_data with both its auto-discovered file_types and enable_auto_update_file_types=true, then rejects that combination on update ("file_types cannot be set when enable_auto_update_file_types is enabled", verified on 2606). So when auto-update is on, file_types is dropped here: Horizon manages that list itself.

ParametersJSON Schema
NameRequiredDescriptionDefault
specYesUpdated application pool specification. Retrieve the current config with get_application_pool, modify the relevant fields, and pass the result here.
pool_idYesApplication pool ID — obtain from list_application_pools

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is covered. The description goes beyond that by disclosing a non-obvious silent data-loss behavior: file_types is dropped from the payload whenever enable_auto_update_file_types is enabled, because Horizon rejects that combination on update. This is exactly the kind of hidden side effect that annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The opening sentence is front-loaded and complete. The second paragraph is denser and slightly meandering in its preamble about what Horizon returns before reaching the actionable rule, but every sentence carries information the caller needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained. However, for a destructive update tool the description does not state whether 'spec' is a full replacement or a partial patch (the schema only implies read-modify-write), nor does it mention permission requirements. The critical file_types gotcha is well covered, but these gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning about the nested 'spec' object — specifically that its file_types member may be silently stripped. That informs how an agent should build the spec payload in a way the schema does not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Update an existing application pool's configuration.' This clearly distinguishes it from create_application_pool, delete_application_pool, and get_application_pool by name alone. It stops short of explicitly contrasting itself with those siblings in prose, but the operation is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use or when-not-to-use guidance, nor a named alternative. The only implied guidance is that this applies to an 'existing' pool (as opposed to create), and the schema mentions retrieving current config first with get_application_pool. A conditional caveat about auto-update is given, but not framed as selection guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_desktop_poolA
DestructiveIdempotent

Update an existing desktop pool's configuration.

ParametersJSON Schema
NameRequiredDescriptionDefault
specYesUpdated pool specification. Retrieve the current config with get_desktop_pool, strip the read-only/immutable fields listed below, modify what you intend to change, and pass the rest through unchanged — verified live against a real server to require no guessing. Fields to remove from get_desktop_pool's response before sending (present there but rejected or meaningless here): id, name, type, source, naming_method, vcenter_id, vcenter_name, farm_id, user_assignment, created_at, updated_at, delete_in_progress, and the num_machines/num_sessions/num_application_sessions/user_group_count/application_count counters. Everything else from get_desktop_pool — including display_assigned_machine_name, display_machine_alias, access_group_id, enable_provisioning, stop_provisioning_on_error, transparent_page_sharing_scope, session_type, and pattern_naming_settings, none of which earlier versions of get_desktop_pool used to return — can be passed straight through.
pool_idYesDesktop pool ID — obtain from list_desktop_pools

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false. The schema's spec description adds valuable behavioral context: the tool requires fetching the current config and stripping specific immutable/counter fields, with a verified list of fields to remove. This goes beyond the annotations by explaining the required preparation workflow and the consequences of sending immutable fields, though it omits permission requirements and exact update semantics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no wasted words. It is appropriately concise for a tool whose detailed parameter semantics are delegated to the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the rich input schema (detailed spec construction), the presence of an output schema, and annotations covering safety/intent, the one-sentence description is largely sufficient. The main gap is the lack of any usage context (when to choose update over create/delete or other pool actions), but the schema's guidance compensates for most of the mechanical completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The tool description itself adds no parameter details beyond the schema, which already fully documents both parameters (including the extensive spec construction guidance). While the schema is rich, the description does not supplement it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Update') and resource ('existing desktop pool's configuration'), clearly distinguishing it from create/delete/get siblings by implication. However, it does not explicitly name alternative tools or scope the update (e.g., full replacement vs. partial), leaving some ambiguity in differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description itself provides no when-to-use or when-not-to-use guidance. The detailed workflow for constructing the spec (retrieve with get_desktop_pool, strip fields, modify, pass through) is embedded in the schema property description, not the tool description, so usage is only implied via the 'Update' verb and the sibling set.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_global_policiesA
DestructiveIdempotent

Update global VDI policies (USB redirection, clipboard, multimedia redirection).

Always call get_global_policies first to read current values. Only modify the specific fields you intend to change — pass the full object back.

ParametersJSON Schema
NameRequiredDescriptionDefault
specYesUpdated global policies object. Call get_global_policies first, modify only the fields you intend to change, then pass the full object here.
confirmNoOnly used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is covered. The description adds meaningful procedural context: read current values first and preserve unmodified fields, which helps avoid accidental destructive changes. It does not further explain the destructive implications or confirmation behavior, but that is largely covered by annotations and schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the action and scope, followed by the critical usage constraint. Every sentence earns its place with no repetition or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is a mutation with nested object input, but the description covers the key behavioral requirement: read first and preserve unmodified fields. Annotations cover safety, the output schema covers return values, and the input schema documents both parameters in full. Nothing essential for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters are already documented. The description's guidance about passing the full object and modifying only specific fields largely repeats the spec parameter's schema description rather than adding new semantic detail. Baseline 3 is appropriate when schema coverage does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Update global VDI policies', and it narrows the scope with concrete examples (USB redirection, clipboard, multimedia redirection). This distinguishes it from the sibling get_global_policies and from broader update_settings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit sequencing: always call get_global_policies first, then modify only intended fields, then pass the full object back. That is a clear when/how-to-use instruction rather than vague context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_rdsh_farmC
DestructiveIdempotent

Update an existing RDS farm's configuration.

ParametersJSON Schema
NameRequiredDescriptionDefault
specYesUpdated farm specification. Retrieve the current config with get_rdsh_farm, modify the relevant fields, and pass the result here. Omit read-only fields such as id, type, and source.
farm_idYesFarm ID — obtain from list_rdsh_farms

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the full safety profile (destructiveHint=true, idempotentHint=true, readOnlyHint=false), and the description is consistent with them, so no contradiction. However, the description itself adds nothing beyond those annotations — no note that changes overwrite existing config, what happens to omitted fields, or any permission requirement.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence with zero padding, front-loaded with the action. It is efficient rather than padded, though its brevity borders on under-specification for a mutation tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists and the annotations cover the safety profile, so the description need not explain return values or risk. Still, for a destructive update taking a nested, free-form spec object, the description is minimally adequate — the real guidance is delegated entirely to the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the nested spec parameter is thoroughly documented (fetch via get_rdsh_farm, omit read-only fields like id, type, source). The description contributes nothing to parameter meaning, so the baseline 3 for full schema coverage is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Update an existing RDS farm's configuration'), so the agent knows exactly what object is mutated. It does not, however, differentiate itself from the many other update_* siblings (update_desktop_pool, update_application_pool, update_settings); the name alone carries that distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no when-to-use, prerequisites, or alternative guidance. The useful workflow hint ('retrieve the current config with get_rdsh_farm, modify, pass here') lives in the schema parameter description, not in the tool description the agent reads first.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_settingsA
DestructiveIdempotent

Update a Horizon settings section.

setting_type maps to these resources and endpoints: general → horizon://config/settings/general security → horizon://config/settings/security client → horizon://config/settings/client feature → horizon://config/settings/feature agent-restriction → horizon://config/settings/agent-restriction

Always read the current settings first and only modify the fields you intend to change.

general: Horizon returns restricted_client_data entries that have only a "type", but rejects them on update with "Restricted client version must be set for client type " (verified on 2606), so passing the settings back unchanged fails. Give every restricted_client_data entry a "version" before calling this.

ParametersJSON Schema
NameRequiredDescriptionDefault
specYesUpdated settings object. Read current values first, modify only the fields you intend to change, then pass the full object here.
confirmNoOnly used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.
setting_typeYesSettings section to update. Read current values via the corresponding horizon://config/settings/<type> resource before modifying.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=true, readOnlyHint=false, so the safety profile is covered. The description adds genuinely non-structured behavior: the confirmation flow that depends on HORIZON_CONFIRMATION, and a subtle server-side quirk where general-section restricted_client_data entries are rejected unless a 'version' is supplied. That is real value beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action and a scannable setting_type→endpoint table, followed by the ordering rule and the general-section caveat. Slight redundancy exists because the schema's setting_type description already mentions reading via the resource URI, but the length is justified by the trap it documents.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need no explanation, and the description covers the mutation preconditions and the one known failure mode. It leaves some ambiguity about behavior on partial/invalid spec (e.g. whether omitted fields reset) for a destructive, idempotent update, which keeps it from a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3; the description adds meaning by mapping each setting_type enum value to a concrete resource URI and by clarifying that spec must be the full updated object rather than a patch. This is more than the schema alone conveys.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Update a Horizon settings section') and enumerates all five sections with their backing resource URIs, so an agent can tell exactly what domain this mutates. It does not explicitly contrast itself with the read-only sibling get_settings or the unrelated update_global_policies, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear precondition ('Always read the current settings first and only modify the fields you intend to change') that routes the agent through get_settings before calling. It stops short of explicitly naming when-not-to-use or spelling out the alternative tool by name, keeping it at 4 rather than 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 27 tool updatesv0.2.0
    • Changedcreate_desktop_pool1 field changed
      • changedInput schema / properties / spec / description
        Previous value: -"Full pool specification. Required keys: name, type (AUTOMATED | MANUAL), source (INSTANT_CLONE | VIRTUAL_CENTER | RDS), user_assignment (FLOATING | DEDICATED). AUTOMATED pools also require provisioning_settings with: virtual_center_id, parent_vm_id, snapshot_id, datacenter_id, vm_folder_id, host_or_cluster_id, resource_pool_id, datastores ([{datastore_id}]), nics ([{nic_id, network_label_id}]), naming_pattern, max_machine_count. Use list_virtual_centers, list_base_vms, list_base_vm_snapshots, list_datacenters, list_vm_folders, list_hosts_or_clusters, list_datastores, list_resource_pools, and list_network_labels to look up all required IDs."New value: +"Full pool specification, verified against a live Horizon server (2606). Required top-level keys: name, type (AUTOMATED | MANUAL | RDS), source (INSTANT_CLONE | LINKED_CLONE | VIRTUAL_CENTER | RDS | UNMANAGED), user_assignment (FLOATING | DEDICATED), naming_method (SPECIFIED | PATTERN), access_group_id (required for AUTOMATED/MANUAL pools — get one from the horizon://config/local-access-groups resource). AUTOMATED pools ALSO require these — all top-level, NOT nested under provisioning_settings, despite what that name suggests: vcenter_id (from list_virtual_centers); provisioning_settings: {parent_vm_id (list_base_vms), base_snapshot_id (list_base_vm_snapshots), datacenter_id (list_datacenters), vm_folder_id (list_vm_folders), host_or_cluster_id (list_hosts_or_clusters), resource_pool_id (list_resource_pools)}; storage_settings: {datastores: [{datastore_id}]} (list_datastores); customization_settings: {customization_type: 'CLONE_PREP' for instant clone, ad_container_rdn (list_ad_domains + list_ad_containers), instant_clone_domain_account_id (list_ic_domain_accounts)}; pattern_naming_settings: {naming_pattern, max_number_of_machines} when naming_method='PATTERN'. nics is optional and top-level (network_interface_card_id + network_label_assignment_specs) — if omitted, new machines simply inherit the parent image's existing network settings."
    • Changedcreate_rdsh_farm1 field changed
      • changedInput schema / properties / spec / description
        Previous value: -"Full farm specification. Required keys: name, type (AUTOMATED | MANUAL), source (INSTANT_CLONE | RDS). AUTOMATED farms also require provisioning_settings with the same fields as create_desktop_pool (virtual_center_id, parent_vm_id, snapshot_id, datacenter_id, vm_folder_id, host_or_cluster_id, resource_pool_id, datastores, nics, naming_pattern, max_machine_count). settings.desktop_id links the farm to its RDS desktop pool. Use list_virtual_centers, list_base_vms, list_base_vm_snapshots, list_datacenters, list_vm_folders, list_hosts_or_clusters, list_datastores, list_resource_pools, and list_network_labels to look up all required IDs."New value: +"Full farm specification, verified live against a real Horizon server (2606). Required top-level keys: name, type (AUTOMATED | MANUAL), access_group_id (from the horizon://config/local-access-groups resource). AUTOMATED farms require an automated_farm_settings object — NOT the same shape as create_desktop_pool's provisioning_settings, and nested one level deeper — containing: vcenter_id (list_virtual_centers), max_session_type (LIMITED | UNLIMITED — max_sessions is required when LIMITED); provisioning_settings: {parent_vm_id (list_base_vms), base_snapshot_id (list_base_vm_snapshots), datacenter_id (list_datacenters), vm_folder_id (list_vm_folders), host_or_cluster_id (list_hosts_or_clusters), resource_pool_id (list_resource_pools)}; storage_settings: {datastores: [{datastore_id}]} (list_datastores); customization_settings: {instant_clone_domain_account_id (list_ic_domain_accounts), ad_container_rdn (list_ad_domains + list_ad_containers)}; pattern_naming_settings: {naming_pattern, max_number_of_rds_servers}. settings.desktop_id links the farm to its RDS desktop pool."
    • Changeddelete_application_pool1 field changed
      • changedInput schema / properties / confirm / description
        Previous value: -"Must be explicitly True to proceed. Obtain explicit user approval before setting."New value: +"Only used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client."
    • Changeddelete_desktop_pool1 field changed
      • changedInput schema / properties / confirm / description
        Previous value: -"Must be explicitly True to proceed. Before setting this, call get_desktop_pool and list_sessions (filtered by desktop_pool_id) to verify the pool is safe to delete, then obtain explicit user approval."New value: +"Only used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client. Before deleting, call get_desktop_pool and list_sessions (filtered by desktop_pool_id) so you can tell the user what will be affected."
    • Changeddelete_rdsh_farm1 field changed
      • changedInput schema / properties / confirm / description
        Previous value: -"Must be explicitly True to proceed. Before setting this, call get_rdsh_farm and list_sessions to verify the farm has no active sessions, then obtain explicit user approval."New value: +"Only used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client. Before deleting, call get_rdsh_farm and list_sessions so you can tell the user what will be affected."
    • Changeddesktop_pool_action1 field changed
      • addedInput schema / properties / confirm
        Added value: +{
        +  "default": false,
        +  "description": "Only used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.",
        +  "type": "boolean"
        +}
    • Changeddisconnect_sessions1 field changed
      • addedInput schema / properties / confirm
        Added value: +{
        +  "default": false,
        +  "description": "Only used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.",
        +  "type": "boolean"
        +}
    • Changedend_remote_application1 field changed
      • addedInput schema / properties / confirm
        Added value: +{
        +  "default": false,
        +  "description": "Only used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.",
        +  "type": "boolean"
        +}
    • Changedhorizon_logout7 fields changed
      • addedInput schema / properties / refresh_token / anyOf
        Added value: +[
        +  {
        +    "format": "password",
        +    "type": "string",
        +    "writeOnly": true
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / refresh_token / default
        Added value: +null
      • changedInput schema / properties / refresh_token / description
        Previous value: -"Refresh token to invalidate"New value: +"Refresh token to invalidate. Omit to use the one the server stored at login."
      • removedInput schema / properties / refresh_token / format
        Removed value: -"password"
      • removedInput schema / properties / refresh_token / type
        Removed value: -"string"
      • removedInput schema / properties / refresh_token / writeOnly
        Removed value: -true
      • removedInput schema / required
        Removed value: -[
        -  "refresh_token"
        -]
    • Changedhorizon_refresh_token7 fields changed
      • addedInput schema / properties / refresh_token / anyOf
        Added value: +[
        +  {
        +    "format": "password",
        +    "type": "string",
        +    "writeOnly": true
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / refresh_token / default
        Added value: +null
      • changedInput schema / properties / refresh_token / description
        Previous value: -"Refresh token obtained from horizon_login"New value: +"Refresh token to use. Omit to use the one the server stored at login (normally what you want)."
      • removedInput schema / properties / refresh_token / format
        Removed value: -"password"
      • removedInput schema / properties / refresh_token / type
        Removed value: -"string"
      • removedInput schema / properties / refresh_token / writeOnly
        Removed value: -true
      • removedInput schema / required
        Removed value: -[
        -  "refresh_token"
        -]
    • Changedlist_application_pools5 fields changed
      • addedInput schema / properties / fetch_all
        Added value: +{
        +  "default": false,
        +  "description": "Fetch successive pages automatically (up to 10 pages / 5000 items). Prefer a filter when you only need a subset.",
        +  "type": "boolean"
        +}
      • addedOutput schema / additionalProperties
        Added value: +true
      • removedOutput schema / properties
        Removed value: -{
        -  "result": {
        -    "items": {},
        -    "type": "array"
        -  }
        -}
      • removedOutput schema / required
        Removed value: -[
        -  "result"
        -]
      • removedOutput schema / x-fastmcp-wrap-result
        Removed value: -true
    • Changedlist_audit_events5 fields changed
      • addedInput schema / properties / fetch_all
        Added value: +{
        +  "default": false,
        +  "description": "Fetch successive pages automatically (up to 10 pages / 5000 items). Prefer a filter when you only need a subset.",
        +  "type": "boolean"
        +}
      • addedOutput schema / additionalProperties
        Added value: +true
      • removedOutput schema / properties
        Removed value: -{
        -  "result": {
        -    "items": {},
        -    "type": "array"
        -  }
        -}
      • removedOutput schema / required
        Removed value: -[
        -  "result"
        -]
      • removedOutput schema / x-fastmcp-wrap-result
        Removed value: -true
    • Changedlist_desktop_pools5 fields changed
      • addedInput schema / properties / fetch_all
        Added value: +{
        +  "default": false,
        +  "description": "Fetch successive pages automatically (up to 10 pages / 5000 items). Prefer a filter when you only need a subset.",
        +  "type": "boolean"
        +}
      • addedOutput schema / additionalProperties
        Added value: +true
      • removedOutput schema / properties
        Removed value: -{
        -  "result": {
        -    "items": {},
        -    "type": "array"
        -  }
        -}
      • removedOutput schema / required
        Removed value: -[
        -  "result"
        -]
      • removedOutput schema / x-fastmcp-wrap-result
        Removed value: -true
    • Changedlist_image_management1 field changed
      • addedInput schema / properties / stream_id
        Added value: +{
        +  "default": "",
        +  "description": "Image stream ID — required for versions and tags. Obtain from resource='streams'.",
        +  "type": "string"
        +}
    • Changedlist_machines5 fields changed
      • addedInput schema / properties / fetch_all
        Added value: +{
        +  "default": false,
        +  "description": "Fetch successive pages automatically (up to 10 pages / 5000 items). Prefer a filter when you only need a subset.",
        +  "type": "boolean"
        +}
      • addedOutput schema / additionalProperties
        Added value: +true
      • removedOutput schema / properties
        Removed value: -{
        -  "result": {
        -    "items": {},
        -    "type": "array"
        -  }
        -}
      • removedOutput schema / required
        Removed value: -[
        -  "result"
        -]
      • removedOutput schema / x-fastmcp-wrap-result
        Removed value: -true
    • Changedlist_network_interface_cards3 fields changed
      • changedInput schema / properties / base_snapshot_id / description
        Previous value: -"Base snapshot ID — obtain from list_base_vm_snapshots (optional)"New value: +"Base snapshot ID — obtain from list_base_vm_snapshots (optional, with base_vm_id)"
      • changedInput schema / properties / base_vm_id / description
        Previous value: -"Base VM ID — obtain from list_base_vms (optional)"New value: +"Base VM ID — obtain from list_base_vms. Either this or vm_template_id is required."
      • changedInput schema / properties / vm_template_id / description
        Previous value: -"VM template ID — obtain from list_vm_templates (optional)"New value: +"VM template ID — obtain from list_vm_templates. Either this or base_vm_id is required."
    • Changedlist_rdsh_farms5 fields changed
      • addedInput schema / properties / fetch_all
        Added value: +{
        +  "default": false,
        +  "description": "Fetch successive pages automatically (up to 10 pages / 5000 items). Prefer a filter when you only need a subset.",
        +  "type": "boolean"
        +}
      • addedOutput schema / additionalProperties
        Added value: +true
      • removedOutput schema / properties
        Removed value: -{
        -  "result": {
        -    "items": {},
        -    "type": "array"
        -  }
        -}
      • removedOutput schema / required
        Removed value: -[
        -  "result"
        -]
      • removedOutput schema / x-fastmcp-wrap-result
        Removed value: -true
    • Changedlist_sessions5 fields changed
      • addedInput schema / properties / fetch_all
        Added value: +{
        +  "default": false,
        +  "description": "Fetch successive pages automatically (up to 10 pages / 5000 items). Prefer a filter when you only need a subset.",
        +  "type": "boolean"
        +}
      • addedOutput schema / additionalProperties
        Added value: +true
      • removedOutput schema / properties
        Removed value: -{
        -  "result": {
        -    "items": {},
        -    "type": "array"
        -  }
        -}
      • removedOutput schema / required
        Removed value: -[
        -  "result"
        -]
      • removedOutput schema / x-fastmcp-wrap-result
        Removed value: -true
    • Changedlogoff_sessions1 field changed
      • addedInput schema / properties / confirm
        Added value: +{
        +  "default": false,
        +  "description": "Only used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.",
        +  "type": "boolean"
        +}
    • Changedmachine_action1 field changed
      • addedInput schema / properties / confirm
        Added value: +{
        +  "default": false,
        +  "description": "Only used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.",
        +  "type": "boolean"
        +}
    • Changedrdsh_farm_action1 field changed
      • addedInput schema / properties / confirm
        Added value: +{
        +  "default": false,
        +  "description": "Only used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.",
        +  "type": "boolean"
        +}
    • Changedreset_or_restart_sessions1 field changed
      • addedInput schema / properties / confirm
        Added value: +{
        +  "default": false,
        +  "description": "Only used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.",
        +  "type": "boolean"
        +}
    • Changedsearch_ad_users_or_groups5 fields changed
      • addedInput schema / properties / fetch_all
        Added value: +{
        +  "default": false,
        +  "description": "Fetch successive pages automatically (up to 10 pages / 5000 items). Prefer a filter when you only need a subset.",
        +  "type": "boolean"
        +}
      • addedOutput schema / additionalProperties
        Added value: +true
      • removedOutput schema / properties
        Removed value: -{
        -  "result": {
        -    "items": {},
        -    "type": "array"
        -  }
        -}
      • removedOutput schema / required
        Removed value: -[
        -  "result"
        -]
      • removedOutput schema / x-fastmcp-wrap-result
        Removed value: -true
    • Changedset_pool_entitlements1 field changed
      • addedInput schema / properties / confirm
        Added value: +{
        +  "default": false,
        +  "description": "Only used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.",
        +  "type": "boolean"
        +}
    • Changedupdate_desktop_pool1 field changed
      • changedInput schema / properties / spec / description
        Previous value: -"Updated pool specification. Retrieve the current config with get_desktop_pool, modify the relevant fields, and pass the result here. Omit read-only fields such as id, type, and source."New value: +"Updated pool specification. Retrieve the current config with get_desktop_pool, strip the read-only/immutable fields listed below, modify what you intend to change, and pass the rest through unchanged — verified live against a real server to require no guessing. Fields to remove from get_desktop_pool's response before sending (present there but rejected or meaningless here): id, name, type, source, naming_method, vcenter_id, vcenter_name, farm_id, user_assignment, created_at, updated_at, delete_in_progress, and the num_machines/num_sessions/num_application_sessions/user_group_count/application_count counters. Everything else from get_desktop_pool — including display_assigned_machine_name, display_machine_alias, access_group_id, enable_provisioning, stop_provisioning_on_error, transparent_page_sharing_scope, session_type, and pattern_naming_settings, none of which earlier versions of get_desktop_pool used to return — can be passed straight through."
    • Changedupdate_global_policies1 field changed
      • addedInput schema / properties / confirm
        Added value: +{
        +  "default": false,
        +  "description": "Only used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.",
        +  "type": "boolean"
        +}
    • Changedupdate_settings1 field changed
      • addedInput schema / properties / confirm
        Added value: +{
        +  "default": false,
        +  "description": "Only used when the server runs with HORIZON_CONFIRMATION=flag (clients without elicitation). Otherwise the user is asked to confirm directly in the client.",
        +  "type": "boolean"
        +}
  2. 72 tool updatesv0.1.0
    • First observedassign_machine_users
    • First observedcreate_application_pool
    • First observedcreate_desktop_pool
    • First observedcreate_rdsh_farm
    • First observeddelete_application_pool
    • First observeddelete_desktop_pool
    • First observeddelete_rdsh_farm
    • First observeddesktop_pool_action
    • First observeddiagnose_session
    • First observeddisconnect_sessions
    • First observedend_remote_application
    • First observedget_ad_user_or_group
    • First observedget_api_coverage
    • First observedget_application_pool
    • First observedget_connection_server
    • First observedget_connection_server_health
    • First observedget_desktop_pool
    • First observedget_domain_netbios_map
    • First observedget_environment_properties
    • First observedget_event_database
    • First observedget_global_policies
    • First observedget_infrastructure_health
    • First observedget_machine
    • First observedget_metrics
    • First observedget_pool_entitlement
    • First observedget_rdsh_farm
    • First observedget_remote_assistance_ticket
    • First observedget_session
    • First observedget_settings
    • First observedhorizon_login
    • First observedhorizon_logout
    • First observedhorizon_refresh_token
    • First observedlist_ad_containers
    • First observedlist_ad_domains
    • First observedlist_application_pools
    • First observedlist_audit_events
    • First observedlist_base_vm_snapshots
    • First observedlist_base_vms
    • First observedlist_connection_servers
    • First observedlist_customization_specifications
    • First observedlist_datacenters
    • First observedlist_datastore_clusters
    • First observedlist_datastores
    • First observedlist_desktop_pools
    • First observedlist_gateways
    • First observedlist_hosts_or_clusters
    • First observedlist_ic_domain_accounts
    • First observedlist_image_management
    • First observedlist_licenses
    • First observedlist_machines
    • First observedlist_network_interface_cards
    • First observedlist_network_labels
    • First observedlist_pool_entitlements
    • First observedlist_rdsh_farms
    • First observedlist_resource_pools
    • First observedlist_sessions
    • First observedlist_virtual_centers
    • First observedlist_vm_folders
    • First observedlist_vm_templates
    • First observedlogoff_sessions
    • First observedmachine_action
    • First observedrdsh_farm_action
    • First observedreset_or_restart_sessions
    • First observedsearch_ad_users_or_groups
    • First observedsend_message_to_sessions
    • First observedset_pool_entitlements
    • First observedtrigger_connection_server_backup
    • First observedupdate_application_pool
    • First observedupdate_desktop_pool
    • First observedupdate_global_policies
    • First observedupdate_rdsh_farm
    • First observedupdate_settings

TDQS

A3.5/5.0

Scored across 72 tools

Disambiguation4/5

Tools are largely separated by resource and action (create/get/update/delete_desktop_pool, list_sessions/get_session, etc.), and the *_action tools are clearly documented as bulk lifecycle toggles. There is mild overlap in the settings surface (get_settings vs get_global_policies vs get_environment_properties, and their update counterparts), but descriptions clarify boundaries.

Naming Consistency4/5

Names follow a predictable snake_case verb_noun convention (list_, get_, create_, update_, delete_) almost throughout, including consistent horizon_* auth tools. Minor deviations are the noun_action tools (machine_action, desktop_pool_action, rdsh_farm_action) and slightly irregular list_hosts_or_clusters, but these are still readable and systematic.

Tool Count2/5

At 72 tools this is a very heavy surface, well beyond the 3-15 sweet spot, and an agent must sift through many near-sibling calls. The domain (pools, farms, machines, sessions, entitlements, AD, vCenter inventory, settings, monitoring) is genuinely broad so most tools earn their place, but the sheer count risks selection errors.

Completeness4/5

Core lifecycles are well covered: full CRUD for desktop pools, RDS farms, and application pools, plus machine/session actions, entitlements, AD search, vCenter inventory helpers, and health/metrics rollups. Gaps are mostly read-only areas (e.g. connection servers, licenses, gateways lack update/management ops), which an agent can work around.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables secure management of VMware vCenter 8.0+ environments through controlled operations including VM lifecycle management, snapshots, and resource discovery with built-in RBAC authorization, audit logging, and rate limiting.
    6
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables management of VMware vCenter and ESXi environments, including VM operations, resource management, and automation with Ollama AI and n8n workflows.
    4
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables interaction with VMware vCenter 8.0 REST API via a reverse proxy, providing read-only and write tools with dry-run protection and automatic session management.
    -