UniFi Network MCP Server
This MCP server provides 76 tools to read and manage a UniFi Network console via the Integration API.
Monitor and manage sites, devices (APs, switches, gateways), and clients – list, get, adopt, restart, power-cycle, and remove devices; list and get connected clients; authorize/unauthorize guests.
Configure networks, WiFi, and switching – create/update/delete networks and WiFi SSIDs, inspect switch stacks, LAGs, and MC-LAG domains.
Manage firewall, ACLs, and DNS – list/get/create/update/delete firewall zones and policies, ACL rules, DNS policies, and traffic matching lists; reorder and partially update rules.
Handle hotspot vouchers – create, list, get, delete, and bulk-delete vouchers.
Access VPN and WAN info – list VPN tunnels, VPN servers, WAN interfaces, and RADIUS profiles.
Retrieve historical data – client history and session records via controller APIs.
Get reference data – device tags, DPI categories/applications, and countries for geo-based rules.
Safety features – read-only mode by default, dry-run support for all write tools, destructive tool confirmations, and structured output for automation.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@UniFi Network MCP Serverlist all adopted devices at the default site"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
UniFi Network MCP Server
An MCP (Model Context Protocol) server that exposes the UniFi Network Integration API as tools for Claude and other MCP clients: sites, devices, clients, networks, WiFi, firewalls, ACLs, switching, DNS policies, hotspot vouchers, VPNs, and more.
Prerequisites
Node.js in the range
engines.nodeinpackage.jsonallowsA UniFi Network console with the Integration API enabled
An API key generated from your UniFi Network console (see Choosing an API key)
Related MCP server: UniFi Network MCP Server
Setup
Quick start (Claude Code)
Add to Claude Code with a single command — no clone or build needed:
claude mcp add-json unifi-network '{"command":"npx","args":["-y","@owine/unifi-network-mcp@latest"],"env":{"UNIFI_NETWORK_HOST":"192.168.1.1","UNIFI_NETWORK_API_KEY":"your-api-key"}}' -s userUse -s user for global availability across all projects, or -s project for the current project only.
@latest runs the newest release every time the server starts, including a new major version. To take fixes but choose when to make breaking upgrades, pin the major version instead (for example @owine/unifi-network-mcp@3).
Claude Desktop
Add the server to claude_desktop_config.json (Settings → Developer → Edit Config), then restart Claude Desktop:
{
"mcpServers": {
"unifi-network": {
"command": "npx",
"args": ["-y", "@owine/unifi-network-mcp@latest"],
"env": {
"UNIFI_NETWORK_HOST": "192.168.1.1",
"UNIFI_NETWORK_API_KEY": "your-api-key"
}
}
}
}Manual configuration (Claude Code)
Alternatively, add the same "unifi-network" entry to your ~/.claude.json under the top-level "mcpServers" key.
From source
If you prefer to build locally, this project uses pnpm via Corepack — use pnpm install, not npm install, which ignores pnpm-lock.yaml and resolves different dependency versions:
git clone https://github.com/owine/unifi-network-mcp.git
cd unifi-network-mcp
corepack enable
pnpm install
pnpm run buildThen add to Claude Code:
claude mcp add-json unifi-network '{"command":"node","args":["/path/to/unifi-network-mcp/dist/index.js"],"env":{"UNIFI_NETWORK_HOST":"192.168.1.1","UNIFI_NETWORK_API_KEY":"your-api-key"}}' -s userEnvironment Variables
Variable | Required | Default | Description |
| Yes | — | IP or hostname of your UniFi Network console, without |
| Yes | — | API key from Network integration settings |
| No | — | Absolute path to a PEM file with the console's certificate, to verify a self-signed console without turning verification off (see below) |
| No |
| Set to |
| No |
| Set to |
| No | — | Cloud Connector console ID; used only when |
UniFi consoles ship with a self-signed certificate, so against a local console the first call usually fails with a certificate error. The safe fix is to trust that one certificate: save it and point UNIFI_NETWORK_CA_CERT at the file.
openssl s_client -connect 192.168.1.1:443 </dev/null 2>/dev/null | openssl x509 > ~/.config/unifi-console.pemSet UNIFI_NETWORK_CA_CERT to the file's absolute path (for example /home/you/.config/unifi-console.pem); MCP hosts do not expand ~ in env. The server then accepts that exact certificate even though it is issued to a name like unifi.local rather than the IP you connect to; any other certificate must chain to the file and match the hostname. Check the fingerprint (openssl x509 -in ~/.config/unifi-console.pem -noout -fingerprint -sha256) against the console's if the network between you is not trusted. If the console later generates a new certificate, save it again.
Setting UNIFI_NETWORK_VERIFY_SSL=false instead turns off certificate checks for this server's connections to the console: anyone who can intercept that traffic can then read the API key. Only do this on a network you trust.
Choosing an API key
The key carries the rights of the admin who created it, and this server is driven by a model that reads data other people control (client hostnames, device names). Create the key as a dedicated admin with the least role that covers your use: for the default read-only mode, a View Only admin, so nothing can be changed even if a tool were misused. Use a full-access admin only when you set UNIFI_NETWORK_READ_ONLY=false.
Cloud Connector
To use a Site Manager API key with a console, set UNIFI_NETWORK_HOST=api.ui.com and UNIFI_NETWORK_CONSOLE_ID to its console ID. The existing UNIFI_NETWORK_API_KEY supplies the key. This works for current Integration API tools and the controller history routes when permitted by the console/key. Cloud Connector requires eligible console ownership/access and firmware 5.0.3 or later. TLS verification stays on: the server refuses to start with UNIFI_NETWORK_VERIFY_SSL=false and api.ui.com.
References: official Cloud Connector API and the Art-of-WiFi controller client, whose session queries use epoch seconds.
Upgrading from 2.x
3.0 tightens several defaults. Most setups need no change; check these:
Cloud Connector with
UNIFI_NETWORK_VERIFY_SSL=false: the server now refuses to start withUNIFI_NETWORK_HOST=api.ui.comand verification off. UnsetUNIFI_NETWORK_VERIFY_SSL.Writes that open access need
confirm: true: creating or switching a firewall policy or ACL rule to ALLOW, disabling a blocking policy or rule, creating an open SSID or changing an SSID's security type, and creating a large batch of vouchers. Without it the tool returns an error naming the change, and the agent can ask you before re-invoking.IDs must be IDs: ID inputs accept only letters, digits,
-and_(pass the IDs that list and get tools return).Smaller default results:
unifi_list_client_sessionsandunifi_list_vouchersreturn fewer rows by default, andunifi_list_client_historynow returns at mostlimitclients, most recently seen first, withtotalCountandtruncated; passlimitfor more. Rows from both history tools carry only the fields their tool descriptions list.Compact text output: tool results are compact JSON rather than indented;
structuredContentis unchanged.
One rule is relaxed: a dryRun: true preview of a destructive tool no longer needs confirm.
Safety Features
This server provides layered safety controls for responsible operation:
Tool annotations — Every tool declares
readOnlyHint,destructiveHintandopenWorldHint, and every write toolidempotentHint, so MCP clients (like Claude Code) can make informed confirmation decisionsServer instructions — On connect the server gives the MCP host a short usage guide for the model (get a
siteIdfirst, page withoffset/limit, preview writes withdryRun, ask before passingconfirm), matched to read-only or read-write modeRead-only mode — Enabled by default. Only read operations (list, get) are registered. Set
UNIFI_NETWORK_READ_ONLY=falseto enable write/mutating toolsDestructive tool warnings — Tools that delete or irreversibly modify resources have descriptions prefixed with
DESTRUCTIVE:to clearly signal riskConfirmation parameter — Every tool marked
DESTRUCTIVE:(includingunifi_remove_deviceandunifi_bulk_delete_vouchers) requires an explicitconfirm: trueparameter for the call to succeed. AdryRun: truepreview does not need it, since it changes nothingConfirmation for changes that open access — Some routine write tools ask for
confirm: trueonly when a particular change lets traffic or guests in: a firewall policy or ACL rule that ALLOWs traffic (created, or switched to ALLOW), disabling a policy or rule that blocks, creating an open SSID or changing an SSID's security type, and creating a large batch of vouchers (unifi_create_voucher'sconfirmparameter states the threshold). Without it the call returns an error naming the change; a dry run never needs itDry-run support — Every write tool accepts an optional
dryRun: trueparameter that returns a preview of the HTTP request (method, path, body) without making any changesSafe partial updates — The UniFi PUT endpoints for WiFi broadcasts, networks, firewall policies, ACL rules and DNS policies replace the whole resource, and some fields reset when omitted (a missing
dhcpGuardingdisables DHCP guarding). Their update tools read the current resource, keep every documented body field, and overlay only the top-level fields you pass, so omitted fields keep their current values. A field you pass replaces the current one whole — nested objects such asipv4Configuration,securityConfigurationor a policy'ssourceare not deep-merged, so start from what the get tool returns. Passnullto clear an optional field. Parallel updates to one resource run one at a time. The dry-run preview shows the merged body (the read still happens)Secret redaction — WiFi passphrases (including per-VLAN PPSK keys) are returned as
[REDACTED]unless the caller passesincludeSecrets: truetounifi_list_wifi/unifi_get_wifi. Write-tool echoes and dry-run previews are always redacted, and an update that echoes back[REDACTED]keeps the stored passphrase
Structured Output
Every read tool, and every write tool whose API response returns the affected resource, declares an MCP outputSchema and returns structuredContent alongside the usual text content. Clients that understand structured output get typed, machine-readable results instead of parsing JSON out of a text blob. A dryRun: true call returns its preview, {"dryRun": true, "wouldExecute": {"method", "path", "body"}}, the same way. Other write tools (deletes, device and guest actions, reorders) return the API response as text only.
The schemas live in src/utils/output-schemas.ts. They deliberately use a loose strategy: every non-key field is optional and objects accept fields the schema does not list, so firmware- and hardware-specific fields flow through unchanged rather than being stripped or triggering a validation error. This keeps the contract stable across console versions and hardware models.
Tools
System
Tool | Description |
| Get UniFi Network application info — returns |
Sites
Tool | Description |
| List all sites available to the API key |
Devices
Tool | Description |
| List all adopted devices at a site |
| Get a specific device by ID |
| Get latest statistics for a device |
| List devices pending adoption (global) |
| Adopt a pending device |
| DESTRUCTIVE: Remove (unadopt) a device — may factory reset |
| Restart a device |
| Power cycle a specific port (PoE restart) |
Clients
Tool | Description |
| List all connected clients (wired, wireless, VPN) at a site |
| Get a specific client by ID |
| Authorize a guest client on a hotspot network |
| Unauthorize a guest client |
Client history
Tool | Description |
| Historical/offline client inventory and first/last seen times |
| Retained connection sessions, duration, byte counters and roaming records |
Networks
Tool | Description |
| List all networks at a site |
| Get a specific network by ID |
| Get references to a network (WiFi, firewall zones, etc.) |
| Create a new network (UNMANAGED, GATEWAY or SWITCH body) |
| Update an existing network — partial changes are merged into the full PUT body |
| DESTRUCTIVE: Delete a network — disconnects all clients |
WiFi
Tool | Description |
| List all WiFi broadcasts (SSIDs) at a site (passphrases redacted by default) |
| Get a specific WiFi network by ID (passphrases redacted unless |
| Create a new WiFi network (SSID) |
| Update an existing WiFi network — partial changes are merged into the full PUT body |
| DESTRUCTIVE: Delete a WiFi network — disconnects all clients |
Hotspot Vouchers
Tool | Description |
| List all hotspot vouchers at a site |
| Get a specific hotspot voucher by ID |
| Create hotspot vouchers |
| DESTRUCTIVE: Delete a hotspot voucher |
| DESTRUCTIVE: Bulk delete vouchers matching a filter |
Firewall Zones & Policies
Tool | Description |
| List all firewall zones at a site |
| Get a specific firewall zone by ID |
| Create a new custom firewall zone |
| Replace a firewall zone's name and network list (send every network ID to keep) |
| DESTRUCTIVE: Delete a custom firewall zone |
| List all firewall policies at a site |
| Get a specific firewall policy by ID |
| Create a new firewall policy |
| Update a firewall policy — partial changes are merged into the full PUT body |
| Partially update a firewall policy (toggle logging or Insights flow reporting) |
| DESTRUCTIVE: Delete a firewall policy |
| Get user-defined firewall policy ordering for a zone pair |
| Reorder user-defined firewall policies for a zone pair |
ACL Rules
Tool | Description |
| List all ACL rules at a site |
| Get a specific ACL rule by ID |
| Get user-defined ACL rule ordering |
| Create a new ACL rule |
| Update an ACL rule — partial changes are merged into the full PUT body |
| DESTRUCTIVE: Delete an ACL rule |
| Reorder user-defined ACL rules |
Switching
Tool | Description |
| List all Switch Stacks at a site |
| Get details of a specific Switch Stack |
| List all MC-LAG (Multi-Chassis LAG) Domains at a site |
| Get details of a specific MC-LAG Domain |
| List all LAGs (Link Aggregation Groups) at a site |
| Get details of a specific LAG |
DNS Policies
Tool | Description |
| List all DNS policies at a site |
| Get a specific DNS policy by ID |
| Create a DNS policy of any type (A, AAAA, CNAME, MX, TXT, SRV, FORWARD_DOMAIN) |
| Update a DNS policy — partial changes are merged into the full PUT body |
| DESTRUCTIVE: Delete a DNS policy |
Traffic Matching
Tool | Description |
| List all traffic matching lists (port groups, IP groups) |
| Get a specific traffic matching list by ID |
| Create a new traffic matching list |
| Replace a traffic matching list (send the full items array) |
| DESTRUCTIVE: Delete a traffic matching list |
Supporting
Tool | Description |
| List all WAN interfaces at a site |
| List all site-to-site VPN tunnels at a site |
| List all VPN servers at a site |
| List all RADIUS profiles at a site |
| List all device tags at a site |
| List all DPI categories for traffic identification |
| List all DPI applications for traffic identification |
| List all countries/regions for geo-based rules |
Retained client connections
The Integration API only lists connected clients. The two history tools use the controller APIs instead: GET /proxy/network/v2/api/site/{siteReference}/clients/history and POST /proxy/network/api/s/{siteReference}/stat/session. The POST is a statistics query and does not change the network. Both tools remain available in read-only mode.
Use internalReference from unifi_list_sites (often default), not its UUID. Session queries require start and end in Unix seconds, with a maximum 31-day window. The controller ignores _start/offset on this endpoint. A full result sets mayBeTruncated=true; split the time window or filter by MAC and query again. Overlap split boundaries and deduplicate session IDs. A result below the requested limit means the query was not capped, not that all dates were retained.
{"siteReference":"default","start":1789272000,"end":1789876800}unifi_list_client_history lists offline clients only, most recently seen first, up to limit, with totalCount. truncated: true means less recently seen clients were left out; raise limit (narrowing withinHours drops those same clients).
Rows keep the controller's field names (assoc_time, duration, rx_bytes, tx_bytes, roaming_sessions, …) but carry only the fields each tool's description lists. RX/TX are the controller's counters, not relabeled client download/upload. Inventory is separate from session history. Retention varies; a non-truncated result does not prove all requested dates were retained, and ongoing sessions may not be present. Neither association nor traffic counters establish end-to-end Internet success.
These controller routes are not part of the published Integration API contract. Their availability and API-key permissions vary by controller version. Unsupported, unauthorized, HTML login, legacy meta.rc error and malformed responses fail explicitly instead of becoming an empty history. History requests are time-limited, reject redirects, and refuse oversized responses. No browser cookies are required where API-key access is supported.
Troubleshooting
Configuration errors go to the MCP host's server log and the server exits. Tool errors reach the agent as results starting with Error:.
Message | Cause and fix |
|
|
| The path does not exist for the server. Use an absolute path; |
| The file has no |
| Unset |
| The console ID only applies with |
| The console's certificate did not verify. Save it to |
| Wrong or unreachable host. |
| The key is wrong or revoked, or its admin lacks the rights (a View Only key cannot write). |
| A wrong |
| The console is slow. For a write, check whether it was applied before retrying. |
| Expected: the change needs |
| The agent passed a name or malformed ID. |
No write tools listed | Read-only is the default. Set |
| This console or key cannot use the history routes (see Retained client connections). It is not an empty history. |
| History tools take |
Development
pnpm install # Install dependencies
pnpm run build # Compile TypeScript
pnpm start # Run the server
pnpm run typecheck # Type-check src/ and tests
pnpm run lint # ESLint
pnpm run lint:fix # ESLint with auto-fix
pnpm test # Run all tests (vitest)
pnpm run test:watch # Run tests in watch mode
pnpm run test:coverage # Run tests with coverage
pnpm run test:package # Build, pack and smoke-test the published packageCommit conventions
This project uses conventional commits and release-please for automated releases:
feat: ...— new feature (minor version bump)fix: ...— bug fix (patch version bump)deps: ...— dependency update (patch version bump)feat!: ...orBREAKING CHANGE:footer — breaking change (major version bump)chore:,docs:,ci:, etc. — no version bump
On push to main, release-please opens a Release PR that bumps the version and updates CHANGELOG.md. Merging that PR publishes to npm automatically.
To override the version number, add Release-As: x.y.z in the commit body:
git commit --allow-empty -m "chore: release x.y.z" -m "Release-As: x.y.z"License
MIT — see LICENSE.
Available Tools
43 toolsunifi_get_acl_ruleGet ACL ruleBRead-only
Get a specific ACL rule by ID (full match criteria and action).
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID | |
| aclRuleId | Yes | ACL rule ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| name | No | |
| type | No | |
| index | No | |
| action | No | |
| enabled | No | |
| metadata | No | |
| description | No | |
| sourceFilter | No | |
| protocolFilter | No | |
| destinationFilter | No | |
| enforcingDeviceFilter | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is fully covered without the description. The parenthetical 'full match criteria and action' adds a small hint about the richness of the returned entity, but with an output schema present this is largely redundant context rather than new behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence that is front-loaded with the verb and resource; every clause earns its place. It is arguably under-specified rather than over-long, so not a full 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 full schema coverage, complete annotations, and an output schema that carries the return shape, the description covers the essentials. Only the absence of sibling routing (vs. unifi_list_acl_rules / unifi_get_acl_rule_ordering) leaves a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters (siteId, aclRuleId) are documented in the schema, so the baseline is 3. The description confirms the ID is the lookup key but adds no format, pattern, or scoping detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Get) and resource (a specific ACL rule) with the lookup key (by ID), which distinguishes it from unifi_list_acl_rules. It does not explicitly name the sibling it is not, so the differentiation is implicit rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisite statement, and no mention of the alternative (unifi_list_acl_rules) for discovering an ID. The 'by ID' phrasing only weakly implies you must already have the identifier.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_get_acl_rule_orderingGet ACL rule orderingBRead-only
Get the evaluation order of user-defined ACL rules. Returns: orderedAclRuleIds[] — rules are evaluated in list order.
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| orderedAclRuleIds | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this as a safe read operation (readOnlyHint, non-destructive, non-openWorld). The description adds useful domain semantics — that rules are evaluated in list order — but says nothing about permissions, aliasing with unifi_get_firewall_policy_ordering, or any other behavioral trait.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with purpose and then the return semantics. Zero filler; every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read-only getter with an output schema, the description is largely sufficient. Restating the return field borders on redundant given the output schema, but the ordering semantics are a genuine addition.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single parameter (siteId) whose schema description coverage is 100%, so the schema already documents it fully. The description adds no parameter-level meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get the evaluation order of user-defined ACL rules'), which is clearly distinct from unifi_list_acl_rules and unifi_get_acl_rule. It doesn't explicitly name those siblings, so an agent must infer the distinction from the name alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
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 alternatives such as unifi_list_acl_rules or unifi_get_acl_rule. The intended use (determining rule precedence) is only implied by the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_get_clientGet clientARead-only
Get a specific connected client by ID. Returns same shape as unifi_list_clients entries.
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID | |
| clientId | Yes | Client ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| name | No | |
| type | No | |
| access | No | |
| ipAddress | No | |
| macAddress | No | |
| connectedAt | No | |
| uplinkDeviceId | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is covered. The only added behavior is that the result matches unifi_list_clients entry shape, which is largely restated by the output schema. No auth, error, or not-found behavior is disclosed, so a 3 is appropriate given the annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the core action and followed by the one useful contract detail. No filler or repetition of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 re-explained, and the two required params are fully documented. Annotations cover the read-only nature. The definition is nearly complete for a simple getter, with only the not-found/permission behavior left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for both parameters, so siteId and clientId are already documented by the schema. The description's 'by ID' adds no format, constraint, or scope detail beyond what the schema supplies, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get a specific connected client') and pins the access key ('by ID'), which separates it from the list-style siblings. It also names unifi_list_clients to anchor the return shape. It stops short of a crisp sibling-vs-sibling routing statement, so 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: 'specific ... by ID' versus the list tool makes the single-record lookup case inferable, but there is no explicit 'use this when you already have a clientId' or a 'for all clients use unifi_list_clients' exclusion. Adequate but leaves the agent to infer the choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_get_deviceGet deviceARead-only
Get full configuration for a device. Returns (in addition to list fields): adoptedAt, provisionedAt, configurationId, uplink.deviceId (absent on the ISP modem), features (object keyed by capability: switching {lags[]} / accessPoint {}), interfaces.ports[] for switches, gateways and modems ({idx, state, connector, maxSpeedMbps, speedMbps (may be omitted on DOWN ports), poe:{standard, type, enabled, state} on PoE ports only}), interfaces.radios[] for APs ({wlanStandard, frequencyGHz, channelWidthMHz, channel}). Some devices (e.g. 5G modems) return empty features/interfaces objects. NOTE: in the LIST endpoint, features/interfaces are capability-tag string arrays instead. Use for: switch port layout/PoE state, AP radio config, uplink topology. For live throughput/CPU/memory, use unifi_get_device_statistics.
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID | |
| deviceId | Yes | Device ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| name | No | |
| model | No | |
| state | No | |
| uplink | No | |
| features | No | |
| adoptedAt | No | |
| ipAddress | No | |
| supported | No | |
| interfaces | No | |
| macAddress | No | |
| provisionedAt | No | |
| configurationId | No | |
| firmwareVersion | No | |
| firmwareUpdatable | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, non-destructive, closed-world semantics, and the description adds genuine behavioral caveats: uplink.deviceId is absent on the ISP modem, speedMbps may be omitted on DOWN ports, and some devices (5G modems) return empty features/interfaces. Much of the remaining text describes return content that the output schema already covers, so it lands just 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and usage routing are correctly front-loaded, but the middle is a dense single block of nested parenthetical field enumerations that is hard to parse and largely duplicates the declared output schema. It is information-rich yet not efficiently structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 re-explained, and the description still covers purpose, usage routing, sibling alternative, and cross-endpoint caveats. Nothing an agent needs to select or invoke this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only two parameters, both required and at 100% schema description coverage ("Site ID", "Device ID"), so the baseline is 3. The description adds no format, ID-source, or lookup guidance beyond what the schema states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Get full configuration for a device") and immediately distinguishes the detail endpoint from the list endpoint's capability-tag arrays. An agent can tell it apart from unifi_list_devices and unifi_get_device_statistics 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly enumerates use cases ("switch port layout/PoE state, AP radio config, uplink topology") and names the alternative for the excluded case ("For live throughput/CPU/memory, use unifi_get_device_statistics"). This is a textbook when-to-use / when-not-to-use split.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_get_device_statisticsGet device statisticsARead-only
Get latest live statistics for a device. Returns: uptimeSec, lastHeartbeatAt, nextHeartbeatAt, loadAverage1/5/15Min, cpuUtilizationPct, memoryUtilizationPct, uplink (txRateBps, rxRateBps; absent on e.g. the ISP modem), interfaces.radios[] for APs ({frequencyGHz, txRetriesPct}; interfaces is {} for non-AP devices). NOTE: verified against 11.0.83 — the Integration API does NOT expose per-switch-port byte/error/PoE-power counters here; port-level live stats are unavailable. Use for: device health and AP radio metrics. For config (channel, power, port assignment), use unifi_get_device.
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID | |
| deviceId | Yes | Device ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| uplink | No | |
| uptimeSec | No | |
| interfaces | No | |
| lastHeartbeatAt | No | |
| loadAverage1Min | No | |
| loadAverage5Min | No | |
| nextHeartbeatAt | No | |
| loadAverage15Min | No | |
| cpuUtilizationPct | No | |
| memoryUtilizationPct | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/openWorld=false/destructive=false, so safety is covered; the description nonetheless adds real behavioral value by flagging version-verified limitations ('does NOT expose per-switch-port byte/error/PoE-power counters') and conditional field absence (uplink missing on the ISP modem, interfaces empty for non-APs). Some of the 'Returns:' enumeration overlaps the output schema, which slightly dilutes the addition.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose, then use cases, then the alternative — a good ordering. The long 'Returns:' field enumeration is denser than needed given an output schema exists, but it is not padded or vague.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-param read tool with annotations and an output schema, the description covers purpose, routing to the sibling, conditional field behavior, and version-specific data gaps. An agent has everything needed to call and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for both parameters (siteId, deviceId), so the schema already carries the semantics; the description adds no format, constraint, or lookup guidance beyond it. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get latest live statistics for a device') and explicitly contrasts itself with the sibling unifi_get_device by scope (live stats vs. config). An agent can route between 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit use cases ('device health and AP radio metrics') and an explicit exclusion with the named alternative ('For config (channel, power, port assignment), use unifi_get_device'). Nothing 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.
unifi_get_dns_policyGet DNS policyCRead-only
Get a specific DNS policy by ID (same fields as the list entry).
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID | |
| dnsPolicyId | Yes | DNS policy ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| port | No | |
| text | No | |
| type | No | |
| domain | No | |
| weight | No | |
| enabled | No | |
| service | No | |
| metadata | No | |
| priority | No | |
| protocol | No | |
| ipAddress | No | |
| ttlSeconds | No | |
| ipv4Address | No | |
| ipv6Address | No | |
| serverDomain | No | |
| targetDomain | No | |
| mailServerDomain | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is fully covered. The description adds only that fields match the list entry, which is a minor return-shape note already implied by the existing output schema; no auth, error, or rate-limit context is provided.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with the key action front-loaded and no filler. The parenthetical about list-entry fields is the only marginally wasteful element given an output schema exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter read tool with a full output schema and complete annotations, the minimum viable information is present. It stops short of stating the relationship to the list tool or any failure conditions, leaving clear but minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 siteId and dnsPolicyId. The description's 'by ID' hints at the dnsPolicyId parameter but adds no syntactic or format detail beyond the schema; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: retrieving one DNS policy by ID. The name plus description clearly distinguish it from the sibling unifi_list_dns_policies. The trailing parenthetical adds little but doesn't obscure the purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to use this versus unifi_list_dns_policies or any other sibling, and no prerequisites mentioned (e.g., needing a siteId and an ID obtained from the list call). Usage is only inferable from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_get_firewall_policyGet firewall policyBRead-only
Get a firewall policy by ID with full match criteria and action. Returns the same fields as a unifi_list_firewall_policies entry, including loggingEnabled and reportFlowEnabled.
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID | |
| firewallPolicyId | Yes | Firewall policy ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| name | No | |
| index | No | |
| action | No | |
| source | No | |
| enabled | No | |
| metadata | No | |
| schedule | No | |
| description | No | |
| destination | No | |
| ipsecFilter | No | |
| loggingEnabled | No | |
| ipProtocolScope | No | |
| reportFlowEnabled | No | |
| connectionStateFilter | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is covered by structured data. The description adds meaningful context by specifying that the return matches a list-policies entry and naming fields like loggingEnabled and reportFlowEnabled, but since an output schema exists this is largely confirmatory rather than new behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero waste; the core action is front-loaded and the return-shape note follows. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter read with complete annotations and an output schema, the description is nearly sufficient. The only gap is the absence of routing guidance relative to the list sibling, which is minor given the tool's simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for both parameters (siteId and firewallPolicyId), so the schema already carries the meaning. The description adds nothing about parameter format or constraints beyond what the schema provides, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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 ('Get a firewall policy by ID') and scopes it further with 'full match criteria and action'. It also anchors the return shape to a named sibling (unifi_list_firewall_policies), letting an agent distinguish the single-item getter from the lister.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
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. The phrase 'by ID' implies a single-item lookup, but the description never tells the agent to use unifi_list_firewall_policies first to obtain the ID, nor when to prefer one over the other.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_get_firewall_policy_orderingGet firewall policy orderingARead-only
Get the evaluation order of user-defined firewall policies for a specific (source zone, destination zone) pair. Returns: orderedFirewallPolicyIds.beforeSystemDefined[] and orderedFirewallPolicyIds.afterSystemDefined[] arrays of policy IDs. System-defined rules sit between these two arrays.
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID | |
| sourceFirewallZoneId | Yes | Source firewall zone ID | |
| destinationFirewallZoneId | Yes | Destination firewall zone ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| orderedFirewallPolicyIds | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, destructiveHint=false and closed-world, so the safety profile is covered. The description adds the semantic that system-defined rules sit between the two returned arrays, which is useful context, but it discloses nothing about auth needs, rate limits, or edge cases.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, purpose front-loaded, then return structure. No filler and every sentence carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the return-format sentence is somewhat redundant, but annotations and schema together mean the agent has what it needs to call this correctly. Only the when-to-use routing against siblings is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three IDs are documented in the schema; the description only reinforces that the zone parameters form a pair. Baseline 3 is appropriate when the schema does the heavy lifting, and no extra format or constraint detail is added.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (get) and resource (firewall policy ordering) and narrows the scope to a (source zone, destination zone) pair. An agent can distinguish it from siblings like unifi_list_firewall_policies and unifi_get_acl_rule_ordering without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when this is useful (to learn evaluation order for a zone pair) but never states when to use it versus alternatives like unifi_list_firewall_policies or how it relates to a sibling ordering endpoint. 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.
unifi_get_firewall_zoneGet firewall zoneARead-only
Get a firewall zone by ID (same fields as the list entry).
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID | |
| firewallZoneId | Yes | Firewall zone ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| name | No | |
| metadata | No | |
| networkIds | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and a closed-world scope, so the safety profile is fully covered. The description's only added behavioral note is that the returned fields match the list entry, which is mild value and partly redundant given 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with the operation front-loaded and the parenthetical qualification trailing it. Nothing is wasted, though the extreme brevity leaves little room for routing or caveats.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only single-resource getter with full schema coverage, an output schema, and annotations covering safety, the description supplies what an agent needs to invoke it. A note about behavior when the ID is not found would make it complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with both required params documented, so the baseline is 3. The description only reiterates that lookup is by ID, adding no format, constraint, or error-handling detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get a firewall zone by ID') and clarifies scope with '(same fields as the list entry)'. It implicitly separates itself from unifi_list_firewall_zones by its by-ID retrieval, though it never names the sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'by ID' phrasing implies you call this when you already have a zone ID rather than enumerating, but there is no explicit when-to-use statement, no mention of when to prefer unifi_list_firewall_zones, and no note on what happens if the ID is unknown.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_get_infoGet infoARead-only
Get UniFi Network application info. Returns: applicationVersion only — the Integration API returns no isUniFiOSConsole or other field here. Use for: checking the Network version when a tool's description notes version-specific behaviour.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| applicationVersion | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=true, destructiveHint=false, openWorldHint=false), so the bar is low. The description adds genuine behavioral context by disclosing that the Integration API returns no isUniFiOSConsole or other field — a real caveat that prevents an agent from assuming richer output. It doesn't discuss auth or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste, front-loaded with the action and the return payload before the usage note. Nothing redundant and nothing padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-param, read-only app-info tool with an output schema and full annotation coverage, the description supplies what is needed: what it returns, what it does not return, and when to reach for it. The 'Use for' clause is slightly narrow and referential, but nothing an agent needs in order 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.
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. The description correctly avoids inventing parameter guidance and its note that only applicationVersion is returned prevents mistaking this for a parameterized query.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get UniFi Network application info') and then names the exact payload ('applicationVersion only'), which cleanly separates it from every sibling that lists or retrieves site/device/client entities. An agent can identify it 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly gives a use case: 'checking the Network version when a tool's description notes version-specific behaviour.' This is clear context with a triggering condition. It stops short of a 5 because it names no alternatives or when-not-to-use condition, though no sibling meaningfully overlaps.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_get_lagGet LAGARead-only
Get full details of a LAG including its type (LOCAL/SWITCH_STACK/MULTI_CHASSIS) and member ports.
| Name | Required | Description | Default |
|---|---|---|---|
| lagId | Yes | LAG ID | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| type | No | |
| members | No | |
| metadata | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered without the description's help. The description adds only the enum values and member ports, which is output content already carried by the existing output schema, so it contributes almost nothing behavioral beyond 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence that states the operation first and the returned detail second, with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter read-by-ID tool with full annotations and an output schema, the description covers what the caller needs; the only gap is the absence of any note distinguishing a LAG from an MC-LAG domain or pointing at unifi_list_lags for ID discovery.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for both parameters (lagId and siteId), so the schema already documents them fully. The description adds no format, sourcing, or lookup guidance for the IDs, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Get) and resource (LAG) plus the scope of the response (type LOCAL/SWITCH_STACK/MULTI_CHASSIS and member ports), so an agent knows exactly what comes back. It does not, however, differentiate itself from the closely related unifi_list_lags or unifi_get_mc_lag_domain siblings, which an agent could plausibly confuse with this tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The single-resource-by-ID shape and the required lagId/siteId imply the standard drill-down pattern after unifi_list_lags, but the description never states when to use this versus list or mc-lag-domain tools, and gives no prerequisites or exclusions. Usage is inferable rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_get_mc_lag_domainGet MC-LAG domainBRead-only
Get full details of an MC-LAG Domain (peer switches and member LAGs).
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID | |
| mcLagDomainId | Yes | MC-LAG Domain ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| lags | No | |
| name | No | |
| peers | No | |
| metadata | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so the safety profile needs no restating. The description adds genuine scope context by naming what the 'full details' comprise (peer switches, member LAGs), but says nothing about errors when an ID is not found or any size/rate considerations. Adding the return-content scope earns it above baseline without reaching rich behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler. The resource is named first and the clarifying parenthetical is placed where it helps most.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 100% schema coverage documents both IDs. The only real gap is the absence of when-to-use guidance relative to the list/get siblings, which for a small read tool is a minor omission.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Both parameters are fully documented in the schema (100% coverage) with type, pattern and description, so the schema does the heavy lifting. The description adds no syntax, format or sourcing guidance for siteId or mcLagDomainId beyond what the schema already provides; baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb ('Get') plus resource ('MC-LAG Domain') and clarifies the payload contents (peer switches and member LAGs). It is clearly distinguishable from unifi_list_mc_lag_domains and unifi_get_lag, though it never explicitly names those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to use this tool versus unifi_list_mc_lag_domains or unifi_get_lag, and no prerequisite guidance (e.g., that a domain ID must first come from the list tool). Usage is only implied by the word 'Get'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_get_networkGet networkARead-only
Get a network/VLAN by ID. Returns the list fields PLUS (live-verified) isolationEnabled, internetAccessEnabled, mdnsForwardingEnabled, cellularBackupEnabled, a full ipv4Configuration object (autoScaleEnabled, hostIpAddress, prefixLength, dhcpConfiguration with mode/ipAddressRange/leaseTimeSeconds/domainName/pingConflictDetectionEnabled/ntpServerIpAddresses — which may contain empty-string entries), and an ipv6Configuration object when IPv6 is configured (interfaceType, clientAddressAssignment, routerAdvertisement, hostIpAddress, prefixLength). NOTE: subnet/DHCP detail appears here at get-by-id but NOT in unifi_list_networks (sparse list view).
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID | |
| networkId | Yes | Network ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| name | No | |
| vlanId | No | |
| zoneId | No | |
| default | No | |
| enabled | No | |
| metadata | No | |
| management | No | |
| dhcpGuarding | No | |
| isolationEnabled | No | |
| ipv4Configuration | No | |
| ipv6Configuration | No | |
| cellularBackupEnabled | No | |
| internetAccessEnabled | No | |
| mdnsForwardingEnabled | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare a safe read (readOnlyHint=true, destructiveHint=false), and the description adds real behavioral context: 'live-verified' field reliability, the empty-string caveat in ntpServerIpAddresses, and the conditional presence of ipv6Configuration. It does not disclose auth needs or rate limits, keeping it below 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is correctly front-loaded in the first four words, but the rest is a long comma-chained enumeration of return fields that the output schema already covers. It is information-dense rather than padded with filler, yet the field lists strain readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, enumerating return fields is largely redundant, so the description's real contribution is the list-vs-get sparseness distinction and the empty-string caveat, both genuinely useful. For a 2-param read tool with full annotations and an output schema, nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (siteId, networkId) are already documented in the schema. The description adds only 'by ID', which maps to networkId but contributes no new syntax or format meaning beyond the existing pattern constraint.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get a network/VLAN by ID') and explicitly names the sibling it differs from (unifi_list_networks), so an agent can distinguish it 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The NOTE establishes a clear selection rule: this tool carries subnet/DHCP detail that the sparse list view lacks. It effectively tells the agent when to prefer this over unifi_list_networks, though it stops short of an explicit 'use this when you need full detail' phrasing or any prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_get_network_referencesGet network referencesARead-only
Get all objects that reference this network. Returns: { referenceResources: [{ resourceType (e.g. WIFI), referenceCount, references: [{ referenceId }] }] }. Use before deleting a network to find dependencies that need to be re-pointed or removed. NOTE: on 11.0.83 the controller returns HTTP 500 (api.unexpected-error) for many networks — observed on the default network and on networks used by PPSK keys. On a 500, fall back to unifi_list_wifi + unifi_get_wifi (network.networkId and securityConfiguration.presharedKeys[].network.networkId) and unifi_list_firewall_zones (networkIds).
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID | |
| networkId | Yes | Network ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| referenceResources | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint/destructiveHint=false, but the description adds substantial unstated behavior: the precise return structure and a documented controller bug (HTTP 500 api.unexpected-error on 11.0.83) with a working fallback procedure. That is exactly the kind of environment-specific behavior an agent 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded and every sentence carries weight (purpose, return shape, usage, failure fallback). It is slightly long, and since an output schema exists, enumerating the return shape in the description is mildly redundant, keeping it just under a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema and safety annotations already present, the description still covers everything else an agent needs: dependency-finding intent and a fully specified recovery path for the known 500 error. Nothing required 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both required params (siteId, networkId) are fully documented in the schema with patterns. The description adds no syntax or semantic detail for the parameters, 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.
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 (objects that reference this network) and immediately clarifies the returned relationship shape. It is clearly distinguishable from siblings like unifi_get_network or unifi_list_networks, which return the network itself rather than its dependents.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit trigger ("Use before deleting a network to find dependencies that need to be re-pointed or removed") and, on failure, names concrete alternatives (unifi_list_wifi + unifi_get_wifi, unifi_list_firewall_zones) with the exact field paths to inspect. This is model when-to-use/fallback guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_get_switch_stackGet switch stackARead-only
Get full details of a Switch Stack including all units and stacking topology. Returns the same fields as the list response but for a single stack: id, deviceId, name, units[] (named members before 10.6.106), lags[], metadata.origin.
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID | |
| switchStackId | Yes | Switch Stack ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| lags | No | |
| name | No | |
| units | No | |
| members | No | |
| deviceId | No | |
| metadata | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, openWorldHint=false, so the safety profile is covered. The description adds genuine value beyond that: the exact returned fields, plus the version caveat that `units` was named `members` before 10.6.106, which an agent would otherwise misread as a different field.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the purpose and then the return contract. The field enumeration is dense but earns its place because of the `members`/`units` version caveat; without that caveat it would be redundant with the output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-required-param read-only detail endpoint with 100% schema coverage and an output schema, nothing essential is missing. The description even goes beyond the minimum by flagging the historical field-name change, so an agent parsing results across controller versions is not surprised.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both required params (siteId, switchStackId) are documented in the schema with patterns, so the schema does the heavy lifting. The description adds nothing about parameter syntax or sourcing, which is the expected baseline when coverage is complete.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get full details of a Switch Stack') plus scope ('including all units and stacking topology'), which cleanly separates it from unifi_list_switch_stacks and the get_lag / get_mc_lag_domain siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The mention that it 'Returns the same fields as the list response but for a single stack' implies the list-vs-get relationship, but there is no explicit when-to-use guidance, no prerequisite (e.g. siteId/switchStackId must come from a listing call), and no stated exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_get_traffic_matching_listGet traffic matching listARead-only
Get a specific traffic matching list by ID (full items array).
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID | |
| trafficMatchingListId | Yes | Traffic matching list ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| name | No | |
| type | No | |
| items | No | |
| metadata | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The parenthetical '(full items array)' adds useful context about response shape distinguish it from the list endpoint's summaries, but no other behavioral traits are disclosed; 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with no filler, and the retrieval key is front-loaded. Efficient and appropriately sized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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, annotations cover safety, and both required parameters are documented. The definition is nearly complete, only lacking explicit routing guidance versus the list sibling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% - both siteId and trafficMatchingListId are documented in the schema with patterns. The description only repeats that retrieval is by ID and adds no format or constraint detail beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Get'), resource ('traffic matching list'), and retrieval key ('by ID'), which cleanly separates it from unifi_list_traffic_matching_lists. It does not explicitly name that sibling, so differentiation is implicit rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'by ID' - fetch one list when you have its identifier versus enumerating via the list sibling. No explicit when-to-use or when-not-to-use guidance is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_get_voucherGet voucherARead-only
Get a specific hotspot voucher by ID (same fields as the list entry).
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID | |
| voucherId | Yes | Voucher ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| code | No | |
| name | No | |
| expired | No | |
| createdAt | No | |
| expiresAt | No | |
| activatedAt | No | |
| rxRateLimitKbps | No | |
| txRateLimitKbps | No | |
| timeLimitMinutes | No | |
| authorizedGuestCount | No | |
| authorizedGuestLimit | No | |
| dataUsageLimitMBytes | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds that the response has the same fields as the list entry, which is modest but useful behavioral context; it does not mention permissions, rate limits, or error behavior, so a 3 is appropriate given the annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single, front-loaded sentence with no wasted words. The key identifying information (specific voucher by ID) comes first.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, annotations cover the safety profile, and both required parameters are fully documented in the schema. For a simple get-by-ID tool, the description is nearly complete; only explicit usage guidance relative to the list sibling is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with 'Site ID' and 'Voucher ID' documented in the schema itself. The description implies lookup by ID but adds no syntax, format, or constraints beyond what the schema already 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.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (Get), resource (hotspot voucher), and scope (a specific voucher identified by ID). This clearly distinguishes it from the sibling unifi_list_vouchers, which lists rather than retrieves a single record.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use guidance, prerequisites, or alternative recommendations are given. The clause 'same fields as the list entry' hints at redundancy with unifi_list_vouchers but does not tell the agent when to prefer this tool over the list tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_get_wifiGet WiFiARead-only
Get full configuration for a WiFi broadcast (SSID). Returns the list fields plus the booleans (hideName, clientIsolationEnabled, uapsdEnabled, multicastToUnicastConversionEnabled, bandSteeringEnabled, arpProxyEnabled, bssTransitionEnabled, advertiseDeviceName, channel2gLockedTo6, dtimPeriod2gLockedTo3), the full securityConfiguration (type, pmfMode, fastRoamingEnabled, saeConfiguration, presharedKeys[] on PPSK SSIDs, …), and optional configs when configured (omitted otherwise): clientFilteringPolicy, blackoutScheduleConfiguration, hotspotConfiguration, mdnsProxyConfiguration, handoffSuggestionsConfiguration, dtimPeriodByFrequencyGHzOverride, broadcastingDeviceFilter, mloEnabled. Passphrases (securityConfiguration.passphrase, presharedKeys[].passphrase) are returned as "[REDACTED]" unless includeSecrets is true.
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | Site ID | |
| includeSecrets | No | Return WiFi passphrases in plaintext instead of "[REDACTED]" (default: false). Only set this when the user explicitly needs the key. | |
| wifiBroadcastId | Yes | WiFi Broadcast ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| name | No | |
| type | No | |
| enabled | No | |
| network | No | |
| hideName | No | |
| metadata | No | |
| mloEnabled | No | |
| bandSteeringEnabled | No | |
| securityConfiguration | No | |
| broadcastingDeviceFilter | No | |
| broadcastingFrequenciesGHz | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/destructiveHint=false annotations, it discloses meaningful behavior: which optional config blocks are omitted when unconfigured, and that passphrases come back as '[REDACTED]' unless includeSecrets is true. That redaction detail is a genuine security-behavior disclosure an agent needs. It stops short of describing error or auth behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first clause, which is good. However, the remainder is a single run-on sentence enumerating a long list of field names that largely duplicates what the output schema already provides, so much of the text does not earn its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 detailed, and annotations already cover the read-only safety profile. What the description must supply — the conditional redaction and the omission of unconfigured optional blocks — is present, leaving only sibling routing and error context unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so siteId, wifiBroadcastId and includeSecrets are all documented in the schema itself. The description restates the includeSecrets redaction semantics but adds no new syntax, format, or defaulting detail beyond that. Baseline 3 applies when the schema carries the parameter burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Get full configuration for a WiFi broadcast (SSID)'. An agent can immediately tell this retrieves a single SSID's config, distinct from the sibling unifi_list_wifi. It does not, however, explicitly name the list sibling to route between them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied (a point-lookup for a specific broadcast), and the description notes the includeSecrets condition for returning plaintext passphrases. But it never states when to use this versus unifi_list_wifi, nor any prerequisites such as needing the broadcast ID from a prior list call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_acl_rulesList ACL rulesARead-only
List ACL rules (switch/AP-level access control lists, distinct from zone-based firewall policies) at a site. Returns: id, type (IPV4/MAC), name, enabled, action (ALLOW/BLOCK), description, protocolFilter, sourceFilter/destinationFilter matchers, enforcingDeviceFilter (which devices apply the rule), index (evaluation order — read-only; change it with unifi_reorder_acl_rules), metadata.origin. ACLs apply earlier in the path than firewall policies.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=true, destructiveHint=false), so the bar is lower, yet the description still adds real behavior: index is read-only evaluation order and must be changed via unifi_reorder_acl_rules, plus the domain note that ACLs apply earlier in the path than firewall policies. It doesn't mention pagination limits or filter syntax, which is a minor remaining gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose and sibling distinction, then the field list. The enumerated 'Returns:' fields partly duplicate the output schema that already exists, making some of the text redundant, but overall it is dense and free of filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a list tool with a read-only annotation set and an output schema, the description covers identity, scope, ordering semantics, and the reorder path. The only shortfall is that the return-field enumeration overlaps the output schema rather than adding new information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (siteId, limit, offset, filter all documented in-schema), so the schema carries parameter meaning. The description only implies site scoping with 'at a site' and adds nothing about limit/offset/filter semantics, which is the expected baseline 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.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource ('List ACL rules') and immediately scopes it: 'switch/AP-level access control lists, distinct from zone-based firewall policies'. An agent can separate this from unifi_list_firewall_policies 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'distinct from zone-based firewall policies' clause effectively routes the agent to the firewall-policy siblings when that is what's wanted, and the index note explicitly points to unifi_reorder_acl_rules for changing order. It stops short of stating prerequisites or when-not-to-use conditions, so it is clear context without full exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_client_historyList client historyARead-only
List historical/offline client inventory using the controller v2 API. Returns OFFLINE clients only — currently connected clients are excluded, so merge with unifi_list_clients for a full inventory. Includes names, MACs, first_seen and last_seen epoch seconds when available. This is inventory, not session history; use unifi_list_client_sessions for past connections. Requires controller history API-key support; errors never mean zero activity. Retention depends on the controller. Returns the most recently seen clients first, up to limit, with totalCount; truncated: true means less recently seen clients were left out, so raise limit (narrowing withinHours drops those same clients). Rows carry only mac, hostname, display_name, first_seen, last_seen, is_wired, status.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum clients, most recently seen first | |
| withinHours | No | Lookback in hours, up to one year; does not extend controller retention | |
| siteReference | Yes | Site internalReference from unifi_list_sites (often default), not the Integration API UUID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | Yes | |
| limit | Yes | |
| coverage | Yes | |
| truncated | Yes | |
| totalCount | Yes | |
| withinHours | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover the safety profile (readOnlyHint, destructiveHint, openWorldHint), and the description goes well beyond them: API-key dependency, error semantics, controller-dependent retention, result ordering, totalCount and truncated behavior, and the limit-vs-withinHours trade-off. These are exactly the traits an agent needs and none are in 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: purpose, expclusions, and sibling routing come first, then operational caveats. The final sentence enumerating row fields ('mac, hostname, display_name...') partially duplicates the output schema, which is minor waste, but the rest of the text is high-value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a filtered list tool with an output schema already present, the description covers everything else an agent needs: scope, exclusions, ordering, truncation, error interpretation, retention limits, and API-key prerequisites. Nothing consequential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 genuinely useful semantics the schema lacks: result ordering is 'most recently seen first up to limit', and narrowing withinHours drops the same clients excluded by truncation. That interaction between limit/truncated/withinHours is real added value over the per-parameter docs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('List historical/offline client inventory') and immediately scopes it: 'Returns OFFLINE clients only — currently connected clients are excluded.' It names the two siblings that could be confused with it, unifi_list_clients and unifi_list_client_sessions, so an agent can route correctly 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use and when-not-to-use guidance: merge with unifi_list_clients for a full inventory, and use unifi_list_client_sessions for past connections rather than this tool. It also states the precondition ('requires controller history API-key support') and the failure interpretation ('errors never mean zero activity').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_clientsList clientsARead-only
List currently connected clients at a site. Returns per client: id, name, type (WIRED/WIRELESS/VPN/TELEPORT), macAddress, ipAddress (may be absent), connectedAt, uplinkDeviceId (the switch/AP they're attached to), access.type. NOTE: verified against 11.0.83 (WIRED/WIRELESS; VPN/TELEPORT not live-verified) — the Integration API client schema is minimal and identical across those types; it does NOT expose signal strength, channel, or per-port binding. Use for: who's online right now. Disconnected/historical clients are NOT in the Integration API; use unifi_list_client_history and unifi_list_client_sessions for controller-retained records.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression. Filterable: id, type, macAddress, ipAddress, connectedAt (timestamp), access.type, access.authorized (boolean). NOT filterable: name, uplinkDeviceId. Example: type.eq('WIRELESS') | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, non-destructive, closed-world), but the description adds substantial context: version-verification status, which client types are live-verified vs not, and what the API schema deliberately omits (signal strength, channel, per-port binding). This is rich disclosure 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core purpose and return fields, then packs caveats and routing into the tail. Dense but every clause carries information; only the field enumeration is arguably slightly over-detailed given an output schema exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 full schema coverage, an output schema, and safety annotations, the description covers scope, alternatives, verification caveats, and API limitations. Nothing an agent needs 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so limit/offset/filter/siteId are already fully documented in the schema, including filterable fields. The description adds no parameter syntax or format detail 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.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with explicit scope ('List currently connected clients at a site'), and enumerates the returned fields. It clearly distinguishes itself from unifi_list_client_history and unifi_list_client_sessions by emphasizing 'currently connected' vs historical records.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use for: who's online right now' and states that disconnected/historical clients are NOT available here, naming the two sibling tools to use instead. The when-to-use and when-not-to-use conditions are fully specified.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_client_sessionsList client sessionsARead-only
Read retained past client connections, including disconnected clients, from the controller stat/session query endpoint. POST here only reads statistics. Rows carry only _id, mac, hostname, is_wired, assoc_time (epoch seconds), duration (seconds), rx_bytes/tx_bytes (controller perspective) and roaming_sessions when available. Use an explicit UTC epoch-second window (max 31 days). If mayBeTruncated is true, split the time window (overlap boundaries and deduplicate IDs) or filter by MAC. The controller ignores offset pagination. Records reflect controller retention and may omit ongoing sessions. Wi-Fi association/bytes do not establish end-to-end Internet success.
| Name | Required | Description | Default |
|---|---|---|---|
| end | Yes | End Unix epoch seconds; after start and at most 31 days later | |
| mac | No | Optional client MAC address | |
| limit | No | Maximum records; a full result requires a narrower window or MAC filter | |
| start | Yes | Start Unix epoch seconds, not milliseconds | |
| siteReference | Yes | Site internalReference from unifi_list_sites (often default), not the Integration API UUID |
Output Schema
| Name | Required | Description |
|---|---|---|
| end | Yes | |
| data | Yes | |
| count | Yes | |
| limit | Yes | |
| start | Yes | |
| coverage | Yes | |
| mayBeTruncated | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and destructiveHint=false, and the description adds real value on top: it explains that a POST here only reads statistics (pre-empting the false impression that POST implies mutation), that results are bounded by controller retention and may omit ongoing sessions, that mayBeTruncated signals truncation, and that Wi-Fi association/bytes do not prove end-to-end Internet success. These are substantive behavioral caveats 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then constraints, then failure-mode handling, then caveats; no filler sentences. It is dense and slightly long, with some row-field enumeration that overlaps the output schema, but each clause carries actionable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a filtered read tool with 100% schema coverage, an output schema, and explicit read-only annotations, the definition covers everything an agent needs: window construction, retention limits, truncation handling, pagination behavior, and interpretation caveats for the byte/association fields.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 start, end, mac, limit, and siteReference, and the description adds little beyond restating the UTC epoch-second window and 31-day cap. Marginal added meaning (MAC filtering as a truncation workaround) keeps it at the baseline rather than below it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Read retained past client connections... from the controller stat/session query endpoint') and clarifies that disconnected clients are included, which is more than the name conveys. However it never distinguishes itself from the very similar sibling unifi_list_client_history, so an agent must guess which session/history 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete operational guidance: use an explicit UTC epoch-second window with a 31-day maximum, and if mayBeTruncated is true, split the window (overlapping boundaries and deduplicating IDs) or filter by MAC. It also warns that offset pagination is ignored. It stops short of naming when to prefer this over unifi_list_client_history or unifi_list_clients.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_countriesList countriesARead-only
List countries/regions (global) for geo-IP firewall rules. Returns: code (ISO alpha-2, e.g. 'US'), name. Use the code when building firewall policies that match by source/destination country.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression (e.g., name.like('United*')) | |
| offset | No | Number of records to skip |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a safe read (readOnlyHint=true, destructiveHint=false, openWorldHint=false), lowering the bar. The description adds that this is a global reference list (not tenant/site scoped) and enumerates the returned fields, which is useful behavioral context beyond the safety profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the purpose and scoping, followed by the practical usage tip. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 re-explained, and annotations cover the safety profile. For a simple global reference-list tool, the description supplies everything needed to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so limit, filter, and offset are already documented in the schema with examples. The description adds no parameter-level meaning, making the baseline 3 the correct score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) plus resource (countries/regions) and scope qualifier (global, for geo-IP firewall rules), which cleanly separates it from site-scoped list siblings like unifi_list_firewall_zones or unifi_list_networks. An agent can tell what it returns (code/name) 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the agent to use the returned code when building firewall policies matching by source/destination country, which gives clear context for when the tool applies. It stops short of naming alternatives or exclusions, but for a static reference-list lookup the intended usage is fully conveyed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_devicesList devicesARead-only
List all adopted devices (gateways, switches, APs) at a site. Returns: id, name, model, macAddress, ipAddress, state (ONLINE/OFFLINE/etc), supported, firmwareVersion, firmwareUpdatable, features[] (capability tags, e.g. ['switching'] or ['accessPoint']), interfaces[] (e.g. ['ports'] or ['radios']). NOTE: features/interfaces are string arrays here; unifi_get_device expands them into objects. Use for: device inventory; pair with unifi_get_device for full config (port table, radios) and unifi_get_device_statistics for live metrics.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression. Filterable: name (supports like), model, state, macAddress, ipAddress, firmwareVersion, supported, firmwareUpdatable, features/interfaces (sets: contains/containsAny/containsAll). like is rejected on model. Example: features.contains('accessPoint') | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, openWorldHint=false, so the safety profile is covered. The description adds genuinely useful non-obvious behavior: that features/interfaces are returned as string arrays here while unifi_get_device expands them into objects, which prevents misinterpretation 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then return fields, then the array caveat, then usage routing. It is dense but every sentence serves a purpose; the enumerated return-field list is slightly redundant given an output schema exists, which keeps it short of a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 explain return values, yet it still flags the array-vs-object distinction that the schema alone wouldn't convey. Usage, scope, and sibling routing are all covered for a simple filtered-list tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters (including the filter grammar and limit/offset) are already documented in the schema. The description adds no parameter-level detail beyond that, which is the correct baseline 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.
Does the description clearly state what the tool does and how it differs from similar tools?
Starts with a specific verb+resource ('List all adopted devices (gateways, switches, APs) at a site'), which is more precise than the sibling unifi_list_pending_devices by scoping to adopted devices, and clearly distinct from unifi_get_device. An agent can identify this as the inventory-list tool 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit routing: 'Use for: device inventory; pair with unifi_get_device for full config (port table, radios) and unifi_get_device_statistics for live metrics.' It names both alternatives and the condition that selects each, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_device_tagsList device tagsARead-only
List device tags at a site. Tags group APs/switches for selective WiFi broadcast (via broadcastingDeviceFilter on a WiFi network). Returns: id, name, deviceIds[], metadata.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds genuine behavioral context beyond that: it explains the semantic role of tags and how they connect to WiFi broadcast filtering. It stops short of mentioning pagination behavior, but that is a minor gap against annotated read-only safety.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short clauses, front-loaded with the core purpose and then the domain context and return shape. Every sentence carries information; no padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a full input schema and an existing output schema, the description need not explain returns, though it lists them redundantly. Combined with the annotations, an agent has enough to call it correctly; only the absence of explicit sibling routing keeps it short of full marks.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters (siteId, limit, offset, filter) are documented in the schema itself. The description adds no syntax or format detail 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.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List device tags at a site') and adds real domain meaning by explaining what tags are (grouping APs/switches for selective WiFi broadcast). However it does not explicitly differentiate itself from the surrounding list_*/get_* siblings, so an agent must infer the distinction from naming conventions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description contextualizes tags via broadcastingDeviceFilter on a WiFi network, which implicitly signals why an agent would look them up. But there is no explicit when-to-use, when-not-to-use, or named alternative, 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.
unifi_list_dns_policiesList DNS policiesBRead-only
List DNS policies (local DNS records and forward rules served by the gateway) at a site. Returns: id, type (A_RECORD, AAAA_RECORD, CNAME_RECORD, MX_RECORD, TXT_RECORD, SRV_RECORD, FORWARD_DOMAIN), enabled, domain, metadata.origin, plus type-specific fields: A ipv4Address+ttlSeconds; AAAA ipv6Address+ttlSeconds; CNAME targetDomain+ttlSeconds; MX mailServerDomain+priority; TXT text; SRV serverDomain/service/protocol/port/priority/weight; FORWARD_DOMAIN ipAddress (per 11.0.83 response samples).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression, e.g. type.eq('A_RECORD') | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered without the description. The description adds the full field shape and the type enum values returned, which is useful behavioral context, but it says nothing about pagination behavior, default page size, or filter syntax beyond echoing the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and scope are front-loaded in the first clause before the field inventory. The long return-field enumeration is dense but each item earns its place by mapping record types to their fields; it is verbose but not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A read-only list tool with an output schema, complete parameter descriptions and full annotations needs little more than a clear purpose statement, which this supplies. Its only real omission is routing guidance to unifi_get_dns_policy and any note on paging through large result sets.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so limit, offset, filter and siteId are already documented in the schema, and the description adds no parameter meaning on top of that. Baseline 3 is appropriate when structured fields carry the parameter burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb+resource ('List DNS policies') and adds a clarifying gloss that these are local DNS records and forward rules served by the gateway. It never names its sibling unifi_get_dns_policy or states it returns a collection rather than one policy, so differentiation is left to the name alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisite (e.g. a valid siteId), and no mention of the alternative unifi_get_dns_policy for fetching a single rule. An agent must infer that this is the enumeration tool from the name only.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_dpi_applicationsList DPI applicationsARead-only
List individual DPI applications (global) — specific apps/services like 'Netflix', 'Zoom', 'Steam'. Returns: id (numeric), name. More granular than unifi_list_dpi_categories.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression, e.g. name.like('Net*') or id.eq(3). NOTE: totalCount ignores the filter here — page by count | |
| offset | No | Number of records to skip |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is covered. The description adds the '(global)' scope and the id/name return shape, but says nothing about pagination behavior or the filter-totalCount caveat that lives only in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences plus a return fragment, with the scope and sibling differentiation front-loaded. Every clause carries information and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 spelled out, and annotations carry the safety profile; the description still names the id/name fields for quick orientation. Complete enough for a zero-required-param list tool, though the filter/pagination interplay could have been surfaced here.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and all three parameters (limit, filter, offset) are documented in the schema, including the important note that totalCount ignores the filter. 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.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (list DPI applications) and pins down the scope as global with concrete examples ('Netflix', 'Zoom', 'Steam'). It explicitly contrasts itself with the sibling unifi_list_dpi_categories, so the agent can pick correctly 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'More granular than unifi_list_dpi_categories' gives a clear comparative cue about when to prefer this tool over its sibling. It stops short of explicit when-not-to-use conditions, but the granularity framing is enough for correct routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_dpi_categoriesList DPI categoriesARead-only
List DPI categories (global, not site-scoped) — high-level traffic groupings like 'Streaming', 'Social Networks', 'Gaming'. Returns: id (numeric), name. Use the category id when building firewall policies that match by category.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression, e.g. name.like('Stream*') or id.eq(3). NOTE: totalCount ignores the filter here — page by count | |
| offset | No | Number of records to skip |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, openWorldHint=false, so safety is covered. The description adds genuinely useful context beyond that: the global (non-site-scoped) nature of the resource and the returned id/name shape. It does not mention pagination behavior, though the schema does.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with zero filler, front-loading the resource identity and scope before the return shape and usage hint. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 the safety profile, the description only needs to add scope and usage context, which it does. Nothing an agent needs 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with limit, filter, and offset fully documented including the totalCount/ filter caveat. The description adds no parameter-level meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List DPI categories'), defines what DPI categories are with concrete examples ('Streaming', 'Social Networks', 'Gaming'), and distinguishes scope from siblings by noting it is 'global, not site-scoped'. An agent can tell it apart from unifi_list_dpi_applications 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear downstream use case: 'Use the category id when building firewall policies that match by category.' This tells the agent why it would call this tool. It does not, however, explicitly contrast with the closely related sibling unifi_list_dpi_applications, leaving the category-vs-application choice to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_firewall_policiesList firewall policiesARead-only
List firewall policies (zone-based rules) at a site. Returns: id, name, enabled, action (object with type field), source/destination (zone reference + trafficFilter), ipProtocolScope, connectionStateFilter, ipsecFilter, schedule, loggingEnabled, reportFlowEnabled (Insights Flows reporting; false on the predefined Allow Return Traffic and Block policies), index, description, metadata (origin SYSTEM_DEFINED/USER_DEFINED/DERIVED, configurable on system policies). action is {type: ALLOW|BLOCK, allowReturnTraffic on ALLOW}. The protocol lives in ipProtocolScope.protocolFilter (NAMED_PROTOCOL or PRESET); ports and addresses live in source/destination.trafficFilter, which is omitted when a side matches the whole zone. Unset optional fields (ipsecFilter, schedule, connectionStateFilter) are omitted, not null. Evaluation order within a zone pair comes from unifi_get_firewall_policy_ordering.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression, e.g. metadata.origin.eq('USER_DEFINED') or name.eq('Allow Return Traffic'). Boolean fields (enabled, loggingEnabled, reportFlowEnabled) are not filterable | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations already covering read-only safety, the description adds substantial behavioral context: return field structure, action shape, where protocol and ports live, that trafficFilter is omitted for whole-zone matches, that unset optional fields are omitted rather than null, and that reportFlowEnabled is false on predefined policies.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the purpose and then spends most of its length on return-shape details. It is dense but mostly earns its place by clarifying nested and omission semantics, though some of that may duplicate the output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a list tool with full schema coverage, annotations, and an output schema, the definition is largely complete. The main gap is explicit usage guidance relative to unifi_get_firewall_policy and pagination behavior, though those are partly covered by the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the four parameters are already documented in the schema. The description does not add parameter-level meaning beyond what the schema provides, which is the baseline-3 case when structured data does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb, resource, and scope: 'List firewall policies (zone-based rules) at a site.' It also distinguishes itself from the ordering sibling by noting that evaluation order comes from unifi_get_firewall_policy_ordering, so an agent can route between list, get, and ordering tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage through 'List firewall policies ... at a site,' but never explicitly says when to use this versus unifi_get_firewall_policy or unifi_get_firewall_policy_ordering. It references the ordering tool only for a related concern, not as a direct usage alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_firewall_zonesList firewall zonesARead-only
List firewall zones (groupings of networks for zone-based firewalling) at a site. Returns: id, name, networkIds[], metadata.origin (indicates system-defined vs user-defined). Use for: zone inventory; pair with unifi_list_firewall_policies to see rules between zones.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression, e.g. name.eq('Internal'). NOTE: totalCount ignores the filter on this endpoint (observed 11.0.83) — page by count | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, covering the safety profile. The description adds which fields are returned and the meaning of metadata.origin (system vs user-defined), but says nothing about permissions, pagination limits, or the filter/count quirk noted in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Compact and front-loaded, using a clear 'Returns:' / 'Use for:' structure. Every clause earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists, the return-value detail is optional but reinforces completeness, and the pairing hint aids correct usage. It remains slightly thin on operational constraints, but adequate 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.
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 siteId, limit, offset, and the filter/count caveat. The description adds no parameter-level meaning 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.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and resource (firewall zones) and defines the concept inline as 'groupings of networks for zone-based firewalling at a site.' This cleanly separates it from the singular sibling unifi_get_firewall_zone and from unifi_list_firewall_policies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage context: 'Use for: zone inventory' and names the complementary sibling to pair with (unifi_list_firewall_policies). No when-not guidance or prerequisites are given, but the routing context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_lagsList LAGsARead-only
List LAGs (Link Aggregation Groups — bonded switch ports) at a site. Returns: id, type (LOCAL/SWITCH_STACK/MULTI_CHASSIS), members[] ({deviceId, portIdxs[]}), switchStackId (SWITCH_STACK) or mcLagDomainId (MULTI_CHASSIS), metadata.origin.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression, e.g. type.eq('LOCAL'), members.deviceId.contains('<deviceId>'), switchStackId.isNull() | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds domain context on LAG types (LOCAL/SWITCH_STACK/MULTI_CHASSIS) and their associated identifiers, which is helpful, but it discloses nothing about pagination behavior or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the purpose and acronym expansion. The return-field enumeration is largely wasted effort given that an output schema exists, which is the only real structural inefficiency.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 full schema coverage and a dedicated output schema, the definition is essentially complete. The main shortfall is the absence of guidance on when to prefer this over unifi_get_lag or when to use filter versus limit/offset paging.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so limit, offset, filter, and siteId are all documented in the schema, including a concrete filter expression example. The description adds no parameter-level detail beyond that, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List LAGs') and disambiguates the acronym ('Link Aggregation Groups — bonded switch ports'), plus scopes it to a site. An agent can distinguish this from unifi_get_lag and unifi_list_switch_stacks immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The site scoping implies a siteId is required and the plural 'List' implies a collection read, but there is no explicit when-to-use guidance, no mention of the unifi_get_lag alternative for a single LAG, and no stated prerequisites. Usage is inferable but not spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_mc_lag_domainsList MC-LAG domainsARead-only
List MC-LAG (Multi-Chassis Link Aggregation) Domains — pairs of switches presenting as one for LAG redundancy. Returns: id, name, peers[] (per the older 10.4.57 spec: {deviceId, linkPortIdxs[], role TOP|BOTTOM}; not live-verified), lags[] (LAGs spanning the domain), metadata.origin.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression, e.g. peers.deviceId.contains('<deviceId>') | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true and destructiveHint=false, so safety is covered. The description goes beyond that by disclosing the response shape and, more valuably, flagging a reliability caveat ('per the older 10.4.57 spec... not live-verified') that no structured field conveys.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the verb and resource, then the concept, then the return detail in one dense sentence. It is efficient overall, though the parenthetical is heavy and the enumerated return fields partly duplicate the output schema that already exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 spelled out, and annotations cover the safety profile, so the description's remaining burden is light. It meets that burden and adds a useful spec-version caveat, missing only usage routing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so siteId, limit, filter, and offset are fully documented in the schema. The description adds no syntax, format, or default information beyond it, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List MC-LAG Domains') and then defines the concept — 'pairs of switches presenting as one for LAG redundancy' — which distinguishes it from the adjacent unifi_list_lags and unifi_get_mc_lag_domain siblings. An agent can tell what this returns without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use, when-not-to-use, or alternative routing guidance. Nothing tells the agent to prefer unifi_get_mc_lag_domain for a single domain or unifi_list_lags for individual LAGs, leaving selection to inference from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_networksList networksARead-only
List all networks (VLANs/LAN segments) at a site. Returns: id, name, management (UNMANAGED/GATEWAY/SWITCH), enabled, vlanId, default (true for the default network), zoneId (the firewall zone the network sits in), dhcpGuarding (only present when enabled), metadata.origin (+ metadata.configurable on the system-defined default network). NOTE: the list view is sparse — for subnet/DHCP/NTP detail (ipv4Configuration/ipv6Configuration), call unifi_get_network on a specific id. Use for: VLAN inventory; pair with unifi_get_network_references to find what consumes a network.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression, e.g. vlanId.eq(20) | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds genuine behavioral context beyond that: the list view is explicitly 'sparse', dhcpGuarding is 'only present when enabled', and metadata.configurable appears only on the system-defined default network. It does not mention pagination behavior (limit/offset interplay), which keeps it from 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and scoping, then enumerates the return fields in a compact clause-run. It is information-dense rather than padded, though the long comma-separated field list and the trailing NOTE make it slightly dense to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Even though an output schema exists, the description usefully documents the actual returned fields and their conditional presence, and it routes the agent to unifi_get_network for detail the list omits. For a 4-parameter read tool with no destructive behavior, nothing an agent needs 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — limit, filter, offset and siteId are all documented in the schema itself, including the API default of 25 and a filter expression example. The description adds no parameter detail, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List all networks (VLANs/LAN segments) at a site') and immediately distinguishes itself from the sibling unifi_get_network by scoping itself to the sparse list view. An agent can tell what this returns and how it differs from the get-by-id tool 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing: 'for subnet/DHCP/NTP detail ... call unifi_get_network on a specific id' names the alternative and the condition that selects it, and 'pair with unifi_get_network_references to find what consumes a network' gives a second concrete use. The 'Use for: VLAN inventory' clause adds a positive trigger.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_pending_devicesList pending devicesARead-only
List devices pending adoption across all sites (global endpoint, not site-scoped). Returns: basic device info per pending device (macAddress, model, ipAddress, firmwareVersion, etc. — exact per-row schema is not rendered in the 11.0.83 docs). Use for: discovering new devices on the network before calling unifi_adopt_device.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression, e.g. model.eq('U7 Pro') | |
| offset | No | Number of records to skip |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, so safety is covered. The description adds real value beyond them by disclosing the global (non-site-scoped) endpoint behavior and by flagging that the exact per-row schema is undocumented in the 11.0.83 docs — an honest uncertainty disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose, then returns, then usage in a tight structure with no filler sentences. The doc-version parenthetical is slightly noisy but earns its place as a transparency caveat rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so explaining return values is optional, yet the description still summarizes the key fields and notes the schema-uncertainty. Combined with annotations covering safety, an agent has enough to call it correctly; only explicit pagination/filter behavior notes are absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (limit, filter, offset all documented with examples and defaults), so the baseline is 3. The description adds no parameter-level detail beyond the schema, which is acceptable given the schema does the work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and resource (devices pending adoption), and adds the crucial scope qualifier 'across all sites (global endpoint, not site-scoped)'. This distinguishes it from siblings like unifi_list_devices and site-scoped list tools without needing to open the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides an explicit workflow trigger: 'Use for: discovering new devices on the network before calling unifi_adopt_device', naming the follow-up tool. It lacks an explicit when-not/exclusion clause, but the adoption-discovery context is clear enough for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_radius_profilesList RADIUS profilesARead-only
List RADIUS profiles (auth/accounting server configurations referenced by WiFi WPA-Enterprise, switch 802.1X port auth, VPN). Returns: id, name, metadata (origin, configurable).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression, e.g. name.eq('Default') | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds domain context but no additional behavioral traits such as pagination, rate limits, or permission requirements; the listed return fields are already provided by the output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two tight sentences with the core purpose front-loaded and no redundant phrasing. Every clause earns its place by naming the tool's function and domain context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a full input schema, an output schema, and annotations covering the safety profile, the description needs only to clarify the resource's purpose. It does so adequately, leaving no critical gap for an agent to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters are fully documented in the schema. The description adds no parameter-level meaning, which is the baseline expectation 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.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('List RADIUS profiles') and clarifies what RADIUS profiles are with concrete examples (WiFi WPA-Enterprise, switch 802.1X port auth, VPN). It does not explicitly contrast with any sibling tool, so it falls short of the 5 bar for sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when the tool is useful by explaining what RADIUS profiles are referenced by, but it never states when to choose this tool over alternatives or any prerequisites. Usage is left to inference from the domain context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_sitesList sitesARead-only
List all sites the API key has access to. Returns: id (the siteId every other tool requires), internalReference, name. Use for: first call in any workflow — almost every other tool needs a siteId.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression. Filterable: id, internalReference, name — eq/ne/in/notIn only (like is rejected). Example: name.eq('Default') | |
| offset | No | Number of records to skip |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, openWorldHint=false, so the safety profile is covered. The description adds real value beyond that: it scopes results to what the API key can access and flags that the returned id is the siteId required by other tools, which is genuine cross-tool behavioral context. It does not discuss pagination defaults, but the schema does.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, with the purpose and the return contract front-loaded before the usage directive. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-required-param list tool with an output schema, annotations, and a fully documented input schema, the description supplies the one thing structured fields cannot: that this is the entry point that yields the siteId for the rest of the toolset. 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and all three params (limit, filter, offset) are fully documented in the schema, including filter operators and examples. The description adds nothing about parameters, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('List all sites') plus the access scope ('the API key has access to') and enumerates the return fields. It is unambiguously distinguishable from the many sibling list_* tools, which target devices, clients, networks, and so on.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use for: first call in any workflow' and gives the reason — 'almost every other tool needs a siteId'. That is a concrete when-to-use condition with the dependency explained, leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_switch_stacksList switch stacksARead-only
List Switch Stacks (multiple physical switches managed as one logical unit) at a site. Returns: id, deviceId (the stack's primary device), name, units[] (the stacked switches — named members on consoles older than 10.6.106), lags[] (LAGs spanning the stack), metadata.origin. Per-unit schema is not rendered in the 11.0.83 docs — call unifi_get_switch_stack to inspect. Use for: identifying stacked switches; individual member configs/stats still come from unifi_get_device.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression, e.g. name.like('Core*') or metadata.origin.eq('USER_DEFINED'). Device filters (members.deviceId, units.deviceId) are rejected on 11.0.83 | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover the safety profile (readOnly, non-destructive). The description adds substantive behavior the annotations cannot: version-specific return naming (units[] vs `members` on consoles older than 10.6.106), a documentation gap in 11.0.83 for the per-unit schema, and a filter restriction (device filters rejected on 11.0.83).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then returns, then usage — good ordering with no filler sentences. It is dense with parenthetical asides (concept definition, version caveat, doc gap), which slightly slows scanning but each aside carries real information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 adds the version-drift caveat that the output schema cannot express. Together with the sibling routing and filter restriction, nothing an agent needs to invoke this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so limit/offset/filter/siteId meaning is already fully documented in the schema. The description adds essentially nothing about parameter syntax or semantics beyond what the schema states (the device-filter rejection note is duplicated in the schema's filter description). Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('List Switch Stacks') and immediately defines the domain concept (multiple physical switches managed as one logical unit) scoped to a site. It also distinguishes itself from siblings unifi_get_switch_stack and unifi_get_device, so an agent can select it 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use for: identifying stacked switches' plus an exclusion — member configs/stats come from unifi_get_device, and per-unit schema requires unifi_get_switch_stack. This names the alternatives and the conditions that select them.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_traffic_matching_listsList traffic matching listsARead-only
List traffic matching lists at a site — named collections of ports or IPs reused in firewall/ACL rules. Returns: id, type (PORTS/IPV4_ADDRESSES/IPV6_ADDRESSES), name, items[] (tagged objects such as {type:'PORT_NUMBER', value:22} or {type:'SUBNET', value:''}). Use for: finding the matching-list ID to reference from a firewall policy.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression. Only id and name are filterable (type is rejected with HTTP 400). Example: name.like('Web*'). NOTE: totalCount ignores the filter here — page by count | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, covering the safety profile. The description adds the type enum values (PORTS/IPV4_ADDRESSES/IPV6_ADDRESSES) and item shapes, which is useful, but much of that is duplicated by the existing output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then returns, then the use-case. Three compact clauses with no filler. The 'Returns:' enumeration is somewhat redundant given an output schema is present, slightly costing conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 full output schema and complete annotation coverage, the description provides enough to select and call it correctly. Nothing critical is missing, though it could have pointed at the sibling get tool for single-item retrieval.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 siteId, limit, offset, and filter (including the filter caveat). The description adds no parameter-level detail, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (list traffic matching lists) and then defines the resource domain-specifically ('named collections of ports or IPs reused in firewall/ACL rules'). This clearly distinguishes it from the singular sibling unifi_get_traffic_matching_list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use for: finding the matching-list ID to reference from a firewall policy' gives a concrete selection context tied to a workflow. It lacks an explicit when-not-to-use or a named alternative, but the intent is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_vouchersList vouchersARead-only
List hotspot/guest-portal vouchers at a site. Returns: id, code, name, createdAt, activatedAt (when first guest used it), expiresAt, timeLimitMinutes, dataUsageLimitMBytes, rxRateLimitKbps, txRateLimitKbps, authorizedGuestLimit, authorizedGuestCount, expired. Use filter like 'expired.eq(true)' to bulk-find stale vouchers.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return | |
| filter | No | Filter expression (e.g., 'expired.eq(true)') | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=false, destructiveHint=false, so the safety profile is covered. The description adds genuinely new context by enumerating the returned fields and clarifying field meaning (activatedAt = when first guest used it, expired flag), aiding interpretation 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the verb and resource, then the return list, then the filter tip. Slightly long on the return-field enumeration, but each item is information-bearing and the structure is easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 needn't detail return values, yet it does, so nothing is missing. Combined with full schema coverage and annotations, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the filter parameter's own schema description already contains the 'expired.eq(true)' example. The description only restates the filter's purpose (bulk-find stale vouchers) and adds nothing about limit/offset pagination, so baseline 3 is correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) with a clearly scoped resource (hotspot/guest-portal vouchers at a site). This distinguishes it from the sibling unifi_get_voucher, which fetches a single voucher, without needing to open either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a concrete usage directive: use filter 'expired.eq(true)' to bulk-find stale vouchers, which tells the agent a real task this tool handles. It stops short of naming alternatives or stating when-not to use it, so not a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_vpn_serversList VPN serversARead-only
List VPN servers (roaming/client-access VPNs) at a site. Returns: id, type (L2TP, OPENVPN, PPTP, UID, WIREGUARD), name, enabled, metadata.origin.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression, e.g. type.eq('WIREGUARD') | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds the returned fields and the type enumeration, but no auth, pagination, or filtering behavior beyond that; an output schema exists, so the return list is largely redundant.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two efficient sentences, purpose front-loaded ahead of the return details. No wasted text, though the return enumeration borders on redundant given the output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 full schema coverage, an output schema, and safety annotations, the definition is nearly complete. It could mention the filter capability (type.eq) and pagination, but those live in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so limit, filter, offset, and siteId are already documented in the schema (including the filter example and API default). The description adds nothing beyond 'at a site', so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List VPN servers') with a scoping clarifier ('roaming/client-access VPNs) at a site'). The parenthetical helps distinguish it from the adjacent unifi_list_vpn_tunnels sibling, though it does not name that sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'at a site' phrasing implies the required context, but there is no explicit when-to-use/when-not guidance and no routing to unifi_list_vpn_tunnels versus this tool. 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.
unifi_list_vpn_tunnelsList VPN tunnelsARead-only
List site-to-site VPN tunnels (IPsec, WireGuard, OpenVPN site-to-site) at a site. Returns: tunnel definitions per row (per-row schema not rendered in 11.0.83 docs and no tunnels to sample live; the older 10.4.57 spec lists id, type (IPSEC/OPENVPN/WIREGUARD), name, metadata.origin/source — call to inspect). For roaming client VPN servers, see unifi_list_vpn_servers.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression, e.g. metadata.source.isNull() | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds real behavioral context beyond that: the supported tunnel types, a caveat that the per-row schema is not rendered in 11.0.83 docs, and a note that there were no live tunnels to sample, advising the caller to inspect at runtime. It stops short of detailing pagination or filtering behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose before the return-value detail and the sibling pointer. The parenthetical version/schema caveat is dense and slightly over-long, but each clause carries information the agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 full schema coverage and an output schema, the description covers purpose, scope, return shape, and the sibling alternative. The runtime caveat about the undocumented per-row schema compensates for the uncertain return format, leaving little an agent needs that is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so siteId, limit, filter, and offset are already fully documented in the schema. The description adds no parameter-level meaning (e.g. how filter expressions apply to tunnels), so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and resource (site-to-site VPN tunnels) with the site scope, and explicitly distinguishes the tool from its sibling unifi_list_vpn_servers by noting the latter is for roaming client VPN servers. An agent can select this 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent: 'For roaming client VPN servers, see unifi_list_vpn_servers,' naming the alternative and the condition that selects it. The site-to-site framing also implicitly scopes when this tool applies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_wansList WANsARead-only
List WAN interface definitions at a site. Returns: id, name only (verified against 11.0.83 — the Integration API exposes no live link status or throughput rates here). Use for: WAN inventory, multi-WAN topology.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly=true, destructive=false, closed-world, so safety is covered. The description adds a real capability boundary beyond the schema: the API exposes only id and name, and there is no live link status or throughput, verified against a specific version — useful expectation-setting.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three compact clauses in one line: what it does, what it returns with its limitation, and when to use it. Front-loaded and free of filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return fields need not be re-explained, yet the description adds valuable caveats anyway. The only minor gap is that pagination through limit/offset is never acknowledged despite those parameters existing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with limit, offset, and siteId all documented (including the API default of 25). The description adds nothing about pagination or the siteId requirement, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List WAN interface definitions') scoped to a site, which no sibling covers. An agent can distinguish it from unifi_list_devices, unifi_list_networks, etc. without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear usage context ('Use for: WAN inventory, multi-WAN topology'), which orients the agent toward the right scenarios. It stops short of naming exclusions or alternatives (e.g., where to get link status instead), so it is context without routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unifi_list_wifiList WiFiARead-only
List all WiFi broadcasts (SSIDs) at a site. Returns (sparse list view, live-verified on 11.0.83): id, name (SSID), type (STANDARD/IOT_OPTIMIZED), enabled, metadata.origin, network reference (absent on PPSK SSIDs), securityConfiguration.type, broadcastingFrequenciesGHz, hotspotConfiguration (empty object when set). Booleans such as hideName/bandSteeringEnabled/clientIsolationEnabled, the full security configuration and optional configs are only returned by unifi_get_wifi. Passphrases (securityConfiguration.passphrase, presharedKeys[].passphrase) are returned as "[REDACTED]" unless includeSecrets is true. Use for: SSID inventory. For per-AP radio state (channel, txPower), use unifi_get_device on the AP.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of records to return (API default: 25) | |
| filter | No | Filter expression, e.g. enabled.eq(true) | |
| offset | No | Number of records to skip | |
| siteId | Yes | Site ID | |
| includeSecrets | No | Return WiFi passphrases in plaintext instead of "[REDACTED]" (default: false). Only set this when the user explicitly needs the key. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| count | No | |
| limit | No | |
| offset | No | |
| totalCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, non-destructive, closed-world), and the description adds substantial context beyond them: the sparse vs. full field set, version-verified behavior (11.0.83), fields absent on PPSK SSIDs, empty-object semantics for hotspotConfiguration, and passphrase redaction defaulting to "[REDACTED]" unless includeSecrets is true.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: purpose and alternative routing come first, then the field/redaction caveats. The return-field enumeration is lengthy and partly redundant given an output schema exists, but it carries conditional-presence and redaction information that earns most of its space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a filtered list tool with full schema coverage, annotations, and an output schema, the description covers everything an agent needs: what it returns, the sparse-vs-full distinction, secret handling, and where to go for adjacent data.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so limit/offset/filter/siteId are already documented and the baseline is 3. The description adds genuine meaning for includeSecrets by explaining the redaction default and cautioning to set it only when the user explicitly needs the key — behavior not stated in the schema's own description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'List all WiFi broadcasts (SSIDs) at a site.' It immediately distinguishes itself from unifi_get_wifi (the full/detailed view) and unifi_get_device (per-AP radio state), so an agent can route correctly without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use for: SSID inventory' plus named alternatives for adjacent needs: unifi_get_wifi for full config, unifi_get_device on the AP for channel/txPower. This is real when-to-use/when-to-use-something-else routing, not implied guidance.
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.
43 tool updates
v2.15.0- Changed
unifi_get_acl_rule8 fields changed- added
Input schema / properties / aclRuleId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - changed
Output schema / properties / description / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Output schema / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / protocolFilter / anyOfAdded value: +[ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } +] - removed
Output schema / properties / protocolFilter / itemsRemoved value: -{ - "type": "string" -} - removed
Output schema / properties / protocolFilter / typeRemoved value: -"array"
- Changed
unifi_get_acl_rule_ordering2 fields changed- added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_get_client3 fields changed- added
Input schema / properties / clientId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_get_device3 fields changed- added
Input schema / properties / deviceId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_get_device_statistics3 fields changed- added
Input schema / properties / deviceId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_get_dns_policy15 fields changed- added
Input schema / properties / dnsPolicyId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / ipAddressAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / ipv6AddressAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / mailServerDomainAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / portAdded value: +{ + "type": [ + "number", + "null" + ] +} - added
Output schema / properties / priorityAdded value: +{ + "type": [ + "number", + "null" + ] +} - added
Output schema / properties / protocolAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / serverDomainAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / serviceAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / targetDomainAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / textAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / weightAdded value: +{ + "type": [ + "number", + "null" + ] +}
- Changed
unifi_get_firewall_policy5 fields changed- added
Input schema / properties / firewallPolicyId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / reportFlowEnabledAdded value: +{ + "type": "boolean" +}
- Changed
unifi_get_firewall_policy_ordering4 fields changed- added
Input schema / properties / destinationFirewallZoneId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / sourceFirewallZoneId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_get_firewall_zone4 fields changed- added
Input schema / properties / firewallZoneId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
- Changed
unifi_get_info1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_get_lag4 fields changed- added
Input schema / properties / lagId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
- Changed
unifi_get_mc_lag_domain4 fields changed- added
Input schema / properties / mcLagDomainId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
- Changed
unifi_get_network4 fields changed- added
Input schema / properties / networkId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
- Changed
unifi_get_network_references3 fields changed- added
Input schema / properties / networkId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_get_switch_stack4 fields changed- added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / switchStackId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
- Changed
unifi_get_traffic_matching_list4 fields changed- added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / trafficMatchingListId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
- Changed
unifi_get_voucher3 fields changed- added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / voucherId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_get_wifi5 fields changed- added
Input schema / properties / includeSecretsAdded value: +{ + "description": "Return WiFi passphrases in plaintext instead of \"[REDACTED]\" (default: false). Only set this when the user explicitly needs the key.", + "type": "boolean" +} - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - added
Input schema / properties / wifiBroadcastId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
- Changed
unifi_list_acl_rules9 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - changed
Output schema / properties / data / items / properties / description / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Output schema / properties / data / items / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / data / items / properties / protocolFilter / anyOfAdded value: +[ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } +] - removed
Output schema / properties / data / items / properties / protocolFilter / itemsRemoved value: -{ - "type": "string" -} - removed
Output schema / properties / data / items / properties / protocolFilter / typeRemoved value: -"array"
- Changed
unifi_list_client_history6 fields changed- added
Input schema / properties / limitAdded value: +{ + "default": 100, + "description": "Maximum clients, most recently seen first", + "maximum": 500, + "minimum": 1, + "type": "integer" +} - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / limitAdded value: +{ + "type": "number" +} - added
Output schema / properties / totalCountAdded value: +{ + "type": "number" +} - added
Output schema / properties / truncatedAdded value: +{ + "type": "boolean" +} - changed
Output schema / requiredPrevious value: -[ - "data", - "count", - "withinHours", - "coverage" -]New value: +[ + "data", + "count", + "totalCount", + "limit", + "truncated", + "withinHours", + "coverage" +]
- Changed
unifi_list_client_sessions2 fields changed- changed
Input schema / properties / limit / defaultPrevious value: -1000New value: +100 - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_list_clients5 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression. Filterable: id, type, macAddress, ipAddress, connectedAt (timestamp), access.type, access.authorized (boolean). NOT filterable: name, uplinkDeviceId. Example: type.eq('WIRELESS')" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_list_countries3 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_list_device_tags4 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_list_devices5 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression. Filterable: name (supports like), model, state, macAddress, ipAddress, firmwareVersion, supported, firmwareUpdatable, features/interfaces (sets: contains/containsAny/containsAll). like is rejected on model. Example: features.contains('accessPoint')" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_list_dns_policies17 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression, e.g. type.eq('A_RECORD')" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / data / items / properties / ipAddressAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / data / items / properties / ipv6AddressAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / data / items / properties / mailServerDomainAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / data / items / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / data / items / properties / portAdded value: +{ + "type": [ + "number", + "null" + ] +} - added
Output schema / properties / data / items / properties / priorityAdded value: +{ + "type": [ + "number", + "null" + ] +} - added
Output schema / properties / data / items / properties / protocolAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / data / items / properties / serverDomainAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / data / items / properties / serviceAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / data / items / properties / targetDomainAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / data / items / properties / textAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / data / items / properties / weightAdded value: +{ + "type": [ + "number", + "null" + ] +}
- Changed
unifi_list_dpi_applications4 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression, e.g. name.like('Net*') or id.eq(3). NOTE: totalCount ignores the filter here — page by count" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_list_dpi_categories4 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression, e.g. name.like('Stream*') or id.eq(3). NOTE: totalCount ignores the filter here — page by count" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_list_firewall_policies7 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression, e.g. metadata.origin.eq('USER_DEFINED') or name.eq('Allow Return Traffic'). Boolean fields (enabled, loggingEnabled, reportFlowEnabled) are not filterable" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / data / items / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / data / items / properties / reportFlowEnabledAdded value: +{ + "type": "boolean" +}
- Changed
unifi_list_firewall_zones6 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression, e.g. name.eq('Internal'). NOTE: totalCount ignores the filter on this endpoint (observed 11.0.83) — page by count" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / data / items / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
- Changed
unifi_list_lags6 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression, e.g. type.eq('LOCAL'), members.deviceId.contains('<deviceId>'), switchStackId.isNull()" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / data / items / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
- Changed
unifi_list_mc_lag_domains6 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression, e.g. peers.deviceId.contains('<deviceId>')" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / data / items / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
- Changed
unifi_list_networks6 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression, e.g. vlanId.eq(20)" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / data / items / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
- Changed
unifi_list_pending_devices4 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression, e.g. model.eq('U7 Pro')" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_list_radius_profiles6 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression, e.g. name.eq('Default')" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / data / items / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
- Changed
unifi_list_sites4 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression (e.g., name.like('office*'))"New value: +"Filter expression. Filterable: id, internalReference, name — eq/ne/in/notIn only (like is rejected). Example: name.eq('Default')" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_list_switch_stacks6 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression, e.g. name.like('Core*') or metadata.origin.eq('USER_DEFINED'). Device filters (members.deviceId, units.deviceId) are rejected on 11.0.83" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / data / items / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
- Changed
unifi_list_traffic_matching_lists6 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression. Only id and name are filterable (type is rejected with HTTP 400). Example: name.like('Web*'). NOTE: totalCount ignores the filter here — page by count" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / data / items / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
- Changed
unifi_list_vouchers5 fields changed- changed
Input schema / properties / limit / defaultPrevious value: -100New value: +25 - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 100, max: 1000)"New value: +"Number of records to return" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_list_vpn_servers6 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression, e.g. type.eq('WIREGUARD')" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / data / items / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
- Changed
unifi_list_vpn_tunnels5 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression, e.g. metadata.source.isNull()" - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_list_wans4 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
unifi_list_wifi7 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression"New value: +"Filter expression, e.g. enabled.eq(true)" - added
Input schema / properties / includeSecretsAdded value: +{ + "description": "Return WiFi passphrases in plaintext instead of \"[REDACTED]\" (default: false). Only set this when the user explicitly needs the key.", + "type": "boolean" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of records to return (default: 25, max: 200)"New value: +"Number of records to return (API default: 25)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of records to skip (default: 0)"New value: +"Number of records to skip" - added
Input schema / properties / siteId / patternAdded value: +"^[A-Za-z0-9_-]{1,64}$" - changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / data / items / properties / metadata / properties / configurableAdded value: +{ + "type": "boolean" +}
2 tool updates
v2.14.0- Added
unifi_list_client_history - Added
unifi_list_client_sessions
26 tool updates
v2.13.0- Changed
unifi_get_acl_rule1 field changed- added
Output schema / properties / indexAdded value: +{ + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +}
- Changed
unifi_get_network1 field changed- added
Output schema / properties / ipv6ConfigurationAdded value: +{}
- Changed
unifi_get_switch_stack2 fields changed- added
Output schema / properties / deviceIdAdded value: +{ + "type": "string" +} - added
Output schema / properties / unitsAdded value: +{ + "items": {}, + "type": "array" +}
- Changed
unifi_list_acl_rules2 fields changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0 - added
Output schema / properties / data / items / properties / indexAdded value: +{ + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +}
- Changed
unifi_list_clients1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_countries2 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression (e.g., 'name.like(United*)')"New value: +"Filter expression (e.g., name.like('United*'))" - changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_device_tags1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_devices1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_dns_policies1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_dpi_applications1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_dpi_categories1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_firewall_policies1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_firewall_zones1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_lags1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_mc_lag_domains1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_networks2 fields changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0 - added
Output schema / properties / data / items / properties / ipv6ConfigurationAdded value: +{}
- Changed
unifi_list_pending_devices1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_radius_profiles1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_sites2 fields changed- changed
Input schema / properties / filter / descriptionPrevious value: -"Filter expression (e.g., 'name.like(office*)')"New value: +"Filter expression (e.g., name.like('office*'))" - changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_switch_stacks3 fields changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0 - added
Output schema / properties / data / items / properties / deviceIdAdded value: +{ + "type": "string" +} - added
Output schema / properties / data / items / properties / unitsAdded value: +{ + "items": {}, + "type": "array" +}
- Changed
unifi_list_traffic_matching_lists1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_vouchers1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_vpn_servers1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_vpn_tunnels1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_wans1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
- Changed
unifi_list_wifi1 field changed- changed
Input schema / properties / limit / minimumPrevious value: -1New value: +0
9 tool updates
v2.10.0- Added
unifi_get_acl_rule - Added
unifi_get_acl_rule_ordering - Added
unifi_get_device_statistics - Added
unifi_get_info - Added
unifi_get_network - Added
unifi_list_acl_rules - Added
unifi_list_pending_devices - Added
unifi_list_vouchers - Added
unifi_list_wifi
9 tool updates
v2.9.0- Removed
unifi_get_acl_rule - Removed
unifi_get_acl_rule_ordering - Removed
unifi_get_device_statistics - Removed
unifi_get_info - Removed
unifi_get_network - Removed
unifi_list_acl_rules - Removed
unifi_list_pending_devices - Removed
unifi_list_vouchers - Removed
unifi_list_wifi
41 tool updates
v2.8.0- First observed
unifi_get_acl_rule - First observed
unifi_get_acl_rule_ordering - First observed
unifi_get_client - First observed
unifi_get_device - First observed
unifi_get_device_statistics - First observed
unifi_get_dns_policy - First observed
unifi_get_firewall_policy - First observed
unifi_get_firewall_policy_ordering - First observed
unifi_get_firewall_zone - First observed
unifi_get_info - First observed
unifi_get_lag - First observed
unifi_get_mc_lag_domain - First observed
unifi_get_network - First observed
unifi_get_network_references - First observed
unifi_get_switch_stack - First observed
unifi_get_traffic_matching_list - First observed
unifi_get_voucher - First observed
unifi_get_wifi - First observed
unifi_list_acl_rules - First observed
unifi_list_clients - First observed
unifi_list_countries - First observed
unifi_list_device_tags - First observed
unifi_list_devices - First observed
unifi_list_dns_policies - First observed
unifi_list_dpi_applications - First observed
unifi_list_dpi_categories - First observed
unifi_list_firewall_policies - First observed
unifi_list_firewall_zones - First observed
unifi_list_lags - First observed
unifi_list_mc_lag_domains - First observed
unifi_list_networks - First observed
unifi_list_pending_devices - First observed
unifi_list_radius_profiles - First observed
unifi_list_sites - First observed
unifi_list_switch_stacks - First observed
unifi_list_traffic_matching_lists - First observed
unifi_list_vouchers - First observed
unifi_list_vpn_servers - First observed
unifi_list_vpn_tunnels - First observed
unifi_list_wans - First observed
unifi_list_wifi
TDQS
Scored across 43 tools
Tools are mostly distinct by resource and action (list vs get vs statistics), and descriptions explicitly clarify when to use similar tools like unifi_list_clients vs unifi_list_client_history vs unifi_list_client_sessions. However, the many list/get pairs and multiple client-history tools create some potential for confusion, though descriptions mitigate it.
All tool names follow a strict unifi_ prefix with a verb_noun pattern in snake_case (e.g., unifi_list_devices, unifi_get_device, unifi_list_firewall_policies). The convention is applied uniformly across all 43 tools with no deviations.
At 43 tools, the set is well above the 25-tool threshold for being too many. Much of the volume comes from near-duplicate list/get pairs for every resource, and the server covers only read operations, so the large surface increases selection burden without proportional value.
The server provides broad read/inventory coverage, but it lacks all write, update, delete, and action operations (e.g., creating firewall rules, updating WiFi, adopting devices, reordering ACLs). Descriptions even reference missing tools like unifi_adopt_device and unifi_reorder_acl_rules, leaving significant gaps for a network management toolset.
Maintenance
Related MCP Connectors
Manage Koru Shield DNS filtering: profiles, rules, categories, schedules, and logs.
Manage Accelo companies, contacts, jobs, tasks, tickets and time.
Manage Invoice Ninja clients, invoices, quotes, expenses, tasks and projects.
Manage repositories, users, releases, and automate GitHub workflows
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables AI assistants to interact with Ubiquiti UniFi network infrastructure for monitoring devices, managing clients, and performing configuration tasks like blocking/unblocking devices and viewing network health.101GPL 3.0
- AlicenseBqualityDmaintenanceEnables AI assistants to manage UniFi network infrastructure through 50+ tools covering devices, clients, networks, WiFi, firewall rules, and guest access using the official UniFi Network API.5234 npm5MIT
- AlicenseNot gradedqualityAmaintenanceEnables management of a local UniFi controller, including devices, clients, network configuration, and monitoring through a single action tool.13MIT
- -licenseNot gradedqualityNot gradedmaintenanceTurns your UniFi Network Controller into programmable tools for querying and modifying network settings via MCP.-