UniFi Protect MCP
Click on "Install 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 Protect MCPshow me a snapshot from the driveway camera"
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 Protect MCP Server
An MCP (Model Context Protocol) server that exposes UniFi Protect's Integration REST API as tools for Claude Code and other MCP clients. Aligned with UniFi Protect API 7.1.83 — 73 tools covering cameras, lights, sensors, chimes, viewers, sirens, fobs, relays, speakers, bridges, link stations, alarm hubs, arm profiles, live views, files, users, NVR status, and WebSocket subscriptions.
Prerequisites
Node.js 22.x (22.13 or newer) or 24.x — see
enginesinpackage.jsonA UniFi Protect system with the Integration API enabled
An API key generated from your UniFi Protect console
Related MCP server: UniFi Internal API MCP Server
Setup
Quick start (npx)
Add to Claude Code with a single command — no clone or build needed:
claude mcp add-json unifi-protect '{"command":"npx","args":["-y","@owine/unifi-protect-mcp@latest"],"env":{"UNIFI_PROTECT_HOST":"192.168.1.1","UNIFI_PROTECT_API_KEY":"your-api-key","UNIFI_PROTECT_VERIFY_SSL":"false"}}' -s userUse -s user for global availability across all projects, or -s project for the current project only.
From source
If you prefer to build locally:
git clone https://github.com/owine/unifi-protect-mcp.git
cd unifi-protect-mcp
corepack enable # provides pnpm at the version pinned in package.json
pnpm install
pnpm run buildThis project uses pnpm — npm install ignores pnpm-lock.yaml and may resolve different dependency versions than CI.
Then add to Claude Code:
claude mcp add-json unifi-protect '{"command":"node","args":["/path/to/unifi-protect-mcp/dist/index.js"],"env":{"UNIFI_PROTECT_HOST":"192.168.1.1","UNIFI_PROTECT_API_KEY":"your-api-key","UNIFI_PROTECT_VERIFY_SSL":"false"}}' -s userEnvironment Variables
Variable | Required | Default | Description |
| Yes | — | IP or hostname of your UniFi Protect console |
| Yes | — | API key from Protect integration settings |
| No |
| Set to |
| No |
| Set to |
Manual Configuration
Alternatively, add to your ~/.claude.json under the top-level "mcpServers" key:
{
"mcpServers": {
"unifi-protect": {
"command": "npx",
"args": ["-y", "@owine/unifi-protect-mcp@latest"],
"env": {
"UNIFI_PROTECT_HOST": "192.168.1.1",
"UNIFI_PROTECT_API_KEY": "your-api-key",
"UNIFI_PROTECT_VERIFY_SSL": "false"
}
}
}
}Safety Features
This server provides layered safety controls for responsible operation:
Tool annotations — Every tool declares
readOnlyHintanddestructiveHintso MCP clients (like Claude Code) can make informed confirmation decisionsRead-only mode — Enabled by default. Only read operations (list, get, snapshot) are registered. Set
UNIFI_PROTECT_READ_ONLY=falseto enable write/mutating toolsConfirmation parameter — The most dangerous tools (
protect_disable_mic,protect_trigger_alarm_webhook) require an explicitconfirm: trueparameter that must be present for the call to succeedDry-run support — All write tools (except those with
confirm) accept an optionaldryRun: trueparameter that returns a preview of what would happen without making any changes
Tools (73 total)
System (2)
Tool | Description |
| Get system information and version details |
| List all NVR devices |
Subscriptions (2)
Tool | Description |
| Subscribe via WebSocket to device state updates |
| Subscribe via WebSocket to event notifications |
Cameras (12)
Tool | Description |
| List all cameras |
| Get camera details by ID |
| Update camera settings |
| Get a JPEG snapshot (returns image) |
| Create an RTSPS stream session |
| Get active RTSPS stream sessions |
| Stop and delete an active RTSPS stream |
| Create a talkback (two-way audio) session |
| IRREVERSIBLE: Permanently disable camera microphone |
| Start PTZ patrol at a given slot |
| Stop PTZ patrol |
| Move PTZ to a preset position |
Lights (3)
Tool | Description |
| List all lights |
| Get light details by ID |
| Update light settings |
Sensors (3)
Tool | Description |
| List all sensors |
| Get sensor details by ID |
| Update sensor settings |
Chimes (3)
Tool | Description |
| List all chimes |
| Get chime details by ID |
| Update chime settings |
Viewers (3)
Tool | Description |
| List all viewers |
| Get viewer details by ID |
| Update viewer settings |
Sirens (6)
Tool | Description |
| List all sirens |
| Get siren details by ID |
| Update siren settings (name, volume, LED) |
| Activate the siren alarm for a given duration (5/10/20/30s) |
| Stop an active siren |
| Test the siren sound for 5 seconds at a given volume |
Fobs (3)
Tool | Description |
| List all key fobs |
| Get fob details by ID |
| Update fob settings |
Relays (4)
Tool | Description |
| List all relays |
| Get relay details by ID |
| Update relay settings |
| Set/toggle a relay output channel, with optional pulse duration |
Speakers (4)
Tool | Description |
| List all speakers |
| Get speaker details by ID |
| Update speaker settings (volume, mic) |
| Test the speaker sound at a given volume |
Bridges (3)
Tool | Description |
| List all bridges |
| Get bridge details by ID |
| Update bridge settings |
Link Stations (3)
Tool | Description |
| List all link stations (non-alarm-hub gateways) |
| Get link station details by ID |
| Update link station settings |
Alarm Hubs (4)
Tool | Description |
| List all alarm hubs |
| Get alarm hub details by ID |
| Update alarm hub settings |
| Trigger an alarm hub output channel (sirens, lights, etc.) |
Arm Profiles (7) — local alarm manager
Tool | Description |
| List all arm profiles |
| Create a new arm profile |
| Set the active profile used when arming |
| Update an arm profile |
| DESTRUCTIVE: Delete an arm profile by ID |
| Arm the alarm using the current profile |
| Disarm the alarm |
Live Views (4)
Tool | Description |
| List all live views |
| Get live view details by ID |
| Create a new live view |
| Update a live view |
Alarm & Files (3)
Tool | Description |
| Trigger an alarm webhook (fires external alarm action) |
| List files by type |
| Upload a file (base64-encoded) |
Users (4)
Tool | Description |
| List Protect users (filtered by access permissions) |
| Get a Protect user by ID |
| List UniFi Identity (ULP) users with enrolled credentials |
| Get a UniFi Identity user by ID |
Development
The Node version used for development is pinned in .nvmrc. With fnm installed, fnm use reads it automatically on cd.
pnpm run build # Compile TypeScript
pnpm start # Run the server
pnpm run typecheck # Type-check without emitting
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 coverageGit hooks are managed by lefthook — pnpm exec lefthook install enables them. Pre-commit runs ESLint on staged files and a full typecheck, so fnm and pnpm both need to be on your PATH.
Commit conventions
This project uses conventional commits and release-please for automated releases:
feat: ...— new feature (minor version bump)fix: ...— bug fix (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.x.x in the commit body:
git commit --allow-empty -m "chore: release 2.0.0" -m "Release-As: 2.0.0"License
MIT
Available Tools
38 toolsprotect_get_alarm_hubARead-only
Get full details for a specific alarm hub by ID. Returns: id, modelKey ("linkstation"), name, mac, state, isAlarmHub, ledSettings (isEnabled), lastEvent, alarmHub (object) (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Alarm hub ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Device ID |
| mac | No | MAC address |
| name | No | Device name |
| state | No | CONNECTED | DISCONNECTED | ... |
| alarmHub | No | Alarm hub status (object: armed, battery, connector, cover, output, input, …) |
| modelKey | No | Resource kind |
| lastEvent | No | Last event timestamp in epoch ms (number) |
| isAlarmHub | No | Whether this device is an alarm hub (boolean) |
| ledSettings | No | LED settings (object: isEnabled) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. Description adds specific fields returned (id, modelKey, name, mac, state, etc.) and references documentation, providing valuable behavioral context beyond 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?
Two sentences: first states purpose, second lists returned fields. Front-loaded with no extraneous words. Very concise.
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 it has an output schema (not shown but indicated), the description is sufficiently complete for a simple tool with one parameter. Lists key return fields and references docs. Slight deduction for not fully detailing all fields but output schema covers 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% with a clear 'Alarm hub ID' description. Description mentions 'by ID' but does not add further constraints or format details. 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?
Description clearly states 'Get full details for a specific alarm hub by ID' which specifies the action (get) and resource (alarm hub details). It distinguishes from sibling tools like protect_list_alarm_hubs and other get_ 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?
Description implies usage context but does not explicitly state when to use this tool over alternatives, such as comparing to protect_list_alarm_hubs for listing all hubs. No exclusions or when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_bridgeARead-only
Get full details for a specific bridge by ID. Returns: id, modelKey, name, mac, state, platform, clients (array of MACs), maxClients (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Bridge ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Device ID |
| mac | No | MAC address |
| name | No | Device name |
| state | No | CONNECTED | DISCONNECTED | ... |
| clients | No | Connected client MACs (array of strings) |
| modelKey | No | Resource kind |
| platform | No | Hardware platform, e.g. "mt7621" |
| maxClients | No | Max client capacity (number) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint true and destructiveHint false. The description adds context about the return fields, but does not disclose any additional behavioral traits such as authentication requirements, rate limits, or error conditions.
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 concise (one sentence plus a list of return fields) and front-loaded with the core purpose. The list of returned fields is relevant and not redundant.
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 the low complexity (single required parameter, read-only, output schema present), the description is fairly complete. It specifies the purpose and the return fields, which is sufficient for a simple get-by-ID 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?
The schema description for the 'id' parameter already says 'Bridge ID'. The tool description does not add any further meaning or usage details for this parameter, so it adds no value 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?
The description clearly states the tool gets full details for a specific bridge by ID, listing the specific fields returned. This distinguishes it from other sibling get_* tools for different entities like cameras or sensors.
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 when you have a bridge ID and want details, but no explicit guidance on when to use this tool versus alternatives (e.g., other get_* tools for different devices) or any exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_cameraARead-only
Get details for a specific camera by ID. The Protect Integration API returns the SAME field set as protect_list_cameras entries (id, mac, name, modelKey, state, activePatrolSlot, hasPackageCamera, hdrType, isMicEnabled, micVolume, videoMode, featureFlags, lcdMessage, ledSettings, osdSettings, smartDetectSettings) — there is no extended/by-id-only payload (confirmed live on 7.1.83). Recording state, motion events, zones, and channel/RTSP config are NOT exposed by this API surface.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Camera ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Camera ID |
| mac | No | MAC address |
| name | No | Camera name |
| state | No | CONNECTED | DISCONNECTED | ... |
| hdrType | No | HDR mode, e.g. "auto" |
| modelKey | No | Always "camera" |
| micVolume | No | Microphone volume 0-100 (number) |
| videoMode | No | Video mode, e.g. "default" |
| lcdMessage | No | |
| ledSettings | No | |
| osdSettings | No | |
| featureFlags | No | |
| isMicEnabled | No | Microphone enabled (boolean) |
| activePatrolSlot | No | Active PTZ patrol slot, or null (number|null) |
| hasPackageCamera | No | Has a secondary package camera (boolean) |
| smartDetectSettings | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint annotation, description lists exact fields returned and explicitly states what is NOT exposed (recording state, motion events, etc.), providing valuable behavioral context.
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 well-structured sentences: first states purpose, second provides critical context and comparison. No extraneous 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?
Covers purpose, parameter, output fields, and limitations. With output schema present, description sufficiently completes the understanding for a simple get-by-id 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 has 100% coverage with parameter description 'Camera ID'. Description adds no additional meaning or format details beyond 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?
Clearly states verb 'Get' and resource 'camera by ID'. Distinguishes from sibling protect_list_cameras by noting the same field set, no extended payload.
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 compares with protect_list_cameras, indicating when to use this tool (single camera) vs listing all cameras. Also implicitly distinguishes from other get tools by resource name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_chimeARead-only
Get full details for a specific chime by ID. Returns: id, modelKey, name, mac, state, cameraIds (array of camera IDs), ringSettings (array of objects: cameraId, volume, ringtoneId, repeatTimes) — verified live 7.1.83.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Chime ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Device ID |
| mac | No | MAC address |
| name | No | Device name |
| state | No | CONNECTED | DISCONNECTED | ... |
| modelKey | No | Resource kind |
| cameraIds | No | Paired camera IDs (array of strings) |
| ringSettings | No | Per-camera ring config (array of objects: cameraId, volume, ringtoneId, repeatTimes) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the tool is clearly a safe read operation. The description adds the returned fields but no additional behavioral traits beyond that. It does not disclose any special behaviors like rate limits or side effects, but none are expected.
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 concise: one sentence stating the purpose followed by a bulleted list of returned fields. It is front-loaded with the action and resource, with no wasted words. Every part serves a purpose.
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 the tool's simplicity (one parameter, no nested objects in input) and the presence of an output schema (per context signals), the description is nearly complete. It lists the return fields, which is slightly redundant but helpful. It could mention pagination or error handling, but not necessary for a get-by-ID.
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% with a single parameter 'id' described as 'Chime ID.' The description does not add further meaning to the parameter beyond what the schema provides. The listed return fields are helpful but pertain to output, not parameter semantics. 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 clearly states 'Get full details for a specific chime by ID,' with a specific verb and resource. It distinguishes from sibling tools (e.g., protect_get_camera) by focusing on 'chime' and lists the returned fields, making the purpose unambiguous.
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 when a chime ID is available, but it does not provide explicit guidance on when to use this tool versus alternatives (e.g., when to call protect_list_chimes first or use other get tools). The context is clear but lacks exclusions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_fobARead-only
Get full details for a specific fob by ID. Returns: id, modelKey, name, mac, state, awayState, buttonLabels, featureFlags (buttons[]), wirelessConnectionState (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Fob ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Device ID |
| mac | No | MAC address |
| name | No | Device name |
| state | No | CONNECTED | DISCONNECTED | ... |
| modelKey | No | Resource kind |
| awayState | No | Away state, e.g. "ONLINE" |
| buttonLabels | No | Button label preset, e.g. "securityActions" |
| featureFlags | No | Feature flags (object: buttons[]) |
| wirelessConnectionState | No | Wireless link state (object) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare it read-only and non-destructive. Description adds the specific return fields, adding value beyond 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?
Single sentence stating purpose followed by a list of return fields. No wasted words, information is front-loaded.
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?
Adequate for a simple get-by-ID tool with output schema. Could mention error cases or how to obtain the ID, but not strictly necessary.
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 parameter description is minimal ('Fob ID'). Description does not add additional context about ID format or constraints 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?
Clearly states the action ('Get full details') and the resource ('a specific fob by ID'). Distinguishes from sibling list tool by specifying single entity retrieval.
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 guidance on when to use vs. alternatives like protect_list_fobs, but the context of requiring an ID implies it's for individual lookups.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_infoARead-only
Get UniFi Protect application information. Returns: applicationVersion (string).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| applicationVersion | No | Current Protect application version |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark it as read-only and non-destructive. The description adds that the output is a single string field, providing useful context beyond 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?
Extremely concise: two sentences, no wasted words. Every sentence adds 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?
Given no parameters and an output schema, the description is complete. It states what it returns, which aligns with the output 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?
No parameters exist, so baseline is 4. No addition needed or possible.
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?
Clearly states the tool retrieves UniFi Protect application information, and explicitly mentions the returned field (applicationVersion). This distinguishes it from sibling tools that get/list other entities.
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 guidance on when to use this tool vs alternatives, but the description is clear enough that it is for application-level info, which is unique among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_lightARead-only
Get full details for a specific light by ID. Returns: id, modelKey, name, mac, state, lightModeSettings (mode, enableAt), lightDeviceSettings (isIndicatorEnabled, pirDuration, pirSensitivity, ledLevel), isDark, isLightOn, isLightForceEnabled, lastMotion, isPirMotionDetected, camera (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Light ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Device ID |
| mac | No | MAC address |
| name | No | Device name |
| state | No | CONNECTED | DISCONNECTED | ... |
| camera | No | Paired camera ID |
| isDark | No | Whether it is currently dark out (boolean) |
| modelKey | No | Resource kind |
| isLightOn | No | Whether the light is currently on (boolean) |
| lastMotion | No | Last motion timestamp in epoch ms (number) |
| lightModeSettings | No | Activation settings (object: mode, enableAt) |
| isLightForceEnabled | No | Main LED force-enabled (boolean) |
| isPirMotionDetected | No | PIR motion currently detected (boolean) |
| lightDeviceSettings | No | Hardware settings (object: isIndicatorEnabled, pirDuration, pirSensitivity, ledLevel) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the agent knows it's a safe read. The description adds the returned fields (id, modelKey, name, etc.) and references documentation, providing context beyond 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?
The description is a single sentence followed by a list of return fields, which is concise and front-loaded with purpose. While the list is somewhat long, it provides useful detail for the agent without requiring inspection of 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 low-complexity tool with one parameter, safe annotations, and an output schema, the description is complete: it specifies the action, resource, and return fields. No additional information is needed.
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 input schema has one parameter (id) with description 'Light ID' and 100% coverage. The description does not add any additional meaning to the parameter 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?
The description clearly states it gets full details for a specific light by ID. The resource (light) and action (get) are unambiguous. Among sibling tools, this distinguishes itself from other get_device tools (e.g., get_camera, get_sensor) by focusing on lights.
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 when needing details of a specific light, but does not explicitly mention when to use this tool versus alternatives like protect_list_lights for listing all lights or other get tools for different devices. The guidance is implied but not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_link_stationARead-only
Get full details for a specific link station by ID. Returns: id, modelKey ("linkstation"), name, mac, state, isAlarmHub, ledSettings (isEnabled), lastEvent, alarmHub (object) (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Link station ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Device ID |
| mac | No | MAC address |
| name | No | Device name |
| state | No | CONNECTED | DISCONNECTED | ... |
| alarmHub | No | Alarm hub status (object: armed, battery, connector, cover, output, input, …) |
| modelKey | No | Resource kind |
| lastEvent | No | Last event timestamp in epoch ms (number) |
| isAlarmHub | No | Whether this device is an alarm hub (boolean) |
| ledSettings | No | LED settings (object: isEnabled) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide read-only and non-destructive hints. The description adds value by listing returned fields (id, modelKey, name, etc.), which helps the agent understand what data to expect.
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 clearly convey the tool's action and return fields. No wasted words; information is front-loaded with key behavior.
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?
The description is complete for a simple get-by-ID tool. It names return fields, and an output schema exists. No further context needed.
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 schema already covers the single 'id' parameter with 100% coverage. The description does not add additional meaning to the parameter beyond what the schema 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?
The description clearly states the tool gets full details for a specific link station by ID. It distinguishes from sibling 'protect_list_link_stations' which lists all stations.
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?
While the tool's purpose is clear, the description does not explicitly state when to use this tool versus alternatives like listing tools. However, the sibling list implies it's for individual station retrieval.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_liveviewARead-only
Get details for a specific live view by ID. Returns: id, modelKey, name, isDefault, isGlobal, layout, owner, slots (each slot: cameras string[], cycleMode, cycleInterval). The full slot list is needed when updating because PATCH replaces the slots array.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Liveview ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Liveview ID |
| name | No | Liveview name |
| owner | No | Owning user ID |
| slots | No | Camera slots |
| layout | No | Grid layout / slot count (number) |
| isGlobal | No | Whether shared across all users (boolean) |
| modelKey | No | Always "liveview" |
| isDefault | No | Whether this is the default liveview (boolean) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and destructiveHint=false. Description adds valuable context beyond annotations: specifies return fields and importantly notes that the full slot list is needed when updating because PATCH replaces the slots array – a behavioral trait for mutation workflows.
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 purpose. No wasted words. Efficiently conveys purpose, return structure, and a critical usage note.
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 output schema present, description provides sufficient information: return fields and the key behavioral note about slot replacement. Complete for a get-by-ID 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?
Only one parameter (id) with schema coverage 100%. Description restates 'by ID' but adds no further semantics or constraints beyond the schema's description 'Liveview ID'. 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?
Clearly states 'Get details for a specific live view by ID' – a specific verb+resource. Distinguishes from sibling tools like protect_list_liveviews (list all) and other get tools by targeting live views.
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?
Implicitly clear when to use: when you have an ID and need details. Does not explicitly mention alternatives or when-not, but the purpose is straightforward and context from sibling names (list vs get) aids differentiation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_relayARead-only
Get full details for a specific relay by ID. Returns: id, modelKey, name, mac, state, ledSettings (isEnabled), outputs (array), inputs (array), wirelessConnectionState (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Relay ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Device ID |
| mac | No | MAC address |
| name | No | Device name |
| state | No | CONNECTED | DISCONNECTED | ... |
| inputs | No | Input channels (array of objects) |
| outputs | No | Output channels (array of objects) |
| modelKey | No | Resource kind |
| ledSettings | No | LED settings (object: isEnabled) |
| wirelessConnectionState | No | Wireless link state (object) |
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 clear. The description adds some detail about returned fields but does not disclose additional behavioral traits beyond what annotations provide.
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 no wasted words. First sentence states purpose, second lists return fields. Front-loaded and efficient.
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?
The description is adequate for a simple get operation with one parameter. It lists return fields. However, it does not mention what happens if ID is invalid or how to know the required state (though annotations and output schema likely cover this).
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 one parameter 'id' with schema description 'Relay ID'. The description adds no extra meaning beyond the schema. With 100% schema coverage, baseline is 3.
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 clearly states 'Get full details for a specific relay by ID.' It uses a specific verb and resource, and lists the return fields, which distinguishes it from sibling tools like protect_list_relays.
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 ID'), but there is no explicit guidance on when to use this vs. alternatives like list_relays or other get tools. No exclusions or context given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_rtsp_streamsARead-only
Get active RTSPS stream sessions for a camera. Returns the per-quality stream URLs currently published (keys typically: high, medium, low, package). Empty/missing keys mean no session is currently active at that quality — use protect_create_rtsp_stream to start one.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Camera ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| low | No | RTSPS URL for the low-quality stream |
| high | No | RTSPS URL for the high-quality stream |
| medium | No | RTSPS URL for the medium-quality stream |
| package | No | RTSPS URL for the package-camera stream |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and destructiveHint=false. The description adds context about the meaning of empty/missing keys (no active session) and suggests a follow-up action, which is valuable beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise (two sentences), front-loaded with the primary purpose, and includes actionable information about return keys and alternative tool. No wasted words.
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 the tool's simplicity (one parameter, clear annotations, output schema present), the description adequately covers the behavior: what it returns, key meanings, and how to handle empty results. It is complete for an agent to use 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?
The input schema has 100% coverage for the single parameter 'id' with a description. The tool description does not add additional semantic meaning for that parameter beyond what the schema 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 clearly states the tool retrieves active RTSPS stream sessions for a camera and returns per-quality URLs. It distinguishes from the sibling tool protect_create_rtsp_stream by mentioning that empty keys indicate no active session.
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 provides guidance on when to use this tool and explicitly mentions an alternative (protect_create_rtsp_stream) for starting a session if none is active. However, it does not elaborate on when not to use it compared to other get tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_sensorARead-only
Get full details for a specific sensor by ID. Returns: id, modelKey, name, mac, state, mountType, batteryStatus (percentage, isLow), stats (light, humidity, temperature), lightSettings, humiditySettings, temperatureSettings, isOpened, openStatusChangedAt, isMotionDetected, motionDetectedAt, motionSettings, glassBreakSettings, scheduleMode, armProfileIds, hasCustomSensitivityWhenArmed, alarmTriggeredAt, alarmSettings, leakDetectedAt, externalLeakDetectedAt, leakSettings, tamperingDetectedAt, wirelessConnectionState (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Sensor ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Device ID |
| mac | No | MAC address |
| name | No | Device name |
| state | No | CONNECTED | DISCONNECTED | ... |
| stats | No | Environmental stats (object: light, humidity, temperature) |
| isOpened | No | Open/close contact state (boolean) |
| modelKey | No | Resource kind |
| mountType | No | Mount type, e.g. "door", "leak", "garage" |
| leakSettings | No | Leak detection settings (object) |
| scheduleMode | No | Schedule mode: "always" | "when_armed" |
| alarmSettings | No | Alarm settings (object: isEnabled) |
| armProfileIds | No | Arm profile IDs this sensor belongs to (array of strings) |
| batteryStatus | No | Battery status (object: percentage, isLow) |
| lightSettings | No | Light threshold settings (object) |
| leakDetectedAt | No | Last leak timestamp in epoch ms (number) |
| motionSettings | No | Motion detection settings (object) |
| alarmTriggeredAt | No | Last alarm timestamp in epoch ms (number) |
| humiditySettings | No | Humidity threshold settings (object) |
| isMotionDetected | No | Motion currently detected (boolean) |
| motionDetectedAt | No | Last motion timestamp in epoch ms (number) |
| glassBreakSettings | No | Glass-break detection settings (object) |
| openStatusChangedAt | No | Open-status change timestamp in epoch ms (number) |
| tamperingDetectedAt | No | Last tampering timestamp in epoch ms (number) |
| temperatureSettings | No | Temperature threshold settings (object) |
| externalLeakDetectedAt | No | Last external-leak timestamp in epoch ms (number) |
| wirelessConnectionState | No | Wireless link state (object: signalState, batteryStatus, bridge) |
| hasCustomSensitivityWhenArmed | No | Custom armed sensitivity enabled (boolean) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only and non-destructive behavior. The description adds value by enumerating the return fields, clarifying what data to expect. However, it does not discuss error handling 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?
The description is compact but front-loads the purpose. The long list of return fields reduces conciseness slightly but is necessary for completeness.
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 a single required parameter and the presence of an output schema, the description fully covers the tool's behavior by listing all return fields. No gaps remain for a simple get-by-ID operation.
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 input schema fully covers the single parameter 'id' with description 'Sensor ID'. The tool description does not add further meaning beyond the schema, meeting the baseline for 100% coverage.
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 clearly states the tool retrieves full details for a specific sensor by ID, with a precise verb ('Get') and resource ('sensor'). It distinguishes from sibling tools like protect_get_camera by focusing on sensors.
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 does not explicitly state when to use this tool versus alternatives, such as protect_list_sensors for listing. Usage is implied but lacks guidance on context or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_sirenARead-only
Get full details for a specific siren by ID. Returns: id, modelKey, name, mac, state, volume, ledSettings (isEnabled), sirenStatus (isActive, activatedAt, duration), connectionType, wirelessConnectionState (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Siren ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Device ID |
| mac | No | MAC address |
| name | No | Device name |
| state | No | CONNECTED | DISCONNECTED | ... |
| volume | No | Siren volume (number) |
| modelKey | No | Resource kind |
| ledSettings | No | LED settings (object: isEnabled) |
| sirenStatus | No | Current siren status (object: isActive, activatedAt, duration) |
| connectionType | No | Connection type, e.g. "lora" |
| wirelessConnectionState | No | Wireless link state (object) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Description lists returned fields, adding value beyond annotations. Annotations already indicate read-only safety, so description provides further behavioral detail.
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 concise sentences: one for purpose, one for return data. No fluff.
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 simple tool with one parameter and output schema (implicit from listed fields), description is 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?
Only one parameter 'id' with schema description; description does not add beyond 'by ID'. Schema coverage is 100%, 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?
Clearly states it gets full details for a specific siren by ID, distinguishing it from list tools and other get tools for different devices.
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?
Implicitly suggests use for single siren details; no explicit alternatives or when-not-to-use, but context from sibling tools makes it clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_snapshotARead-only
Get a JPEG snapshot from a camera. Returns a base64-encoded image/jpeg (rendered directly by MCP clients). Use highQuality=true for full-resolution capture; set channel=package to capture from the secondary package camera on doorbells with hasPackageCamera=true.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Camera ID | |
| channel | No | Camera channel to capture. Use "package" for cameras with hasPackageCamera=true (defaults to main) | |
| highQuality | No | If true, request a high-quality snapshot |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only and non-destructive behavior. The description adds value by specifying the return format (base64-encoded image/jpeg) and the conditional behavior for package camera capture, enhancing transparency beyond 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?
The description is concise, with two sentences that front-load the main purpose. Every sentence provides essential information, and there is no redundancy or 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 the simple nature of the tool and good annotations/schema, the description is complete enough. It covers the return type and parameter guidance. No output schema exists, but the description compensates by explaining the output format.
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% with parameter descriptions, but the description adds meaningful semantics: highQuality=true for full-resolution and channel=package for secondary camera usage. This provides context that the schema alone lacks.
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 clearly states the tool's function: 'Get a JPEG snapshot from a camera.' It specifies the verb and resource, and the mention of base64-encoded output distinguishes it from other protect_get_* siblings which retrieve different device data.
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 provides explicit guidelines for parameter usage: use highQuality=true for full-resolution and channel=package for secondary camera on doorbells with hasPackageCamera=true. This helps the agent decide when to use these parameters, though it does not explicitly state when not to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_speakerARead-only
Get full details for a specific speaker by ID. Returns: id, modelKey, name, mac, state, volume, micVolume, isMicEnabled, speakerState (status, mode), featureFlags (hasMic) (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Speaker ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Device ID |
| mac | No | MAC address |
| name | No | Device name |
| state | No | CONNECTED | DISCONNECTED | ... |
| volume | No | Speaker volume (number) |
| modelKey | No | Resource kind |
| micVolume | No | Microphone volume (number) |
| featureFlags | No | Feature flags (object: hasMic) |
| isMicEnabled | No | Microphone enabled (boolean) |
| speakerState | No | Speaker state (object: status, mode) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and destructiveHint=false. The description adds value by listing the specific fields returned (id, modelKey, etc.), providing context beyond the annotations. No contradiction.
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 a single sentence with the core purpose followed by a parenthetical list of returned fields. Every part is informative and no wasted words.
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 the low complexity (1 parameter, no enums), the description lists all returned fields, and the output schema exists. The description is complete enough for an agent to understand the tool's behavior.
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 describes the id parameter as 'Speaker ID' with 100% coverage. The description does not add extra meaning beyond the schema, so baseline score 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 clearly states 'Get full details for a specific speaker by ID,' using a specific verb and resource. It distinguishes from sibling list tools that return multiple items.
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 to use (when you have a speaker ID and need full details) but does not explicitly mention when not to use or mention alternatives like protect_list_speakers for multiple speakers.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_ulp_userARead-only
Get details for a specific UniFi Identity (ULP) user by ID. Returns: id, modelKey, firstName, lastName, fullName, status.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ULP user ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ULP user UUID |
| status | No | Account status, e.g. ACTIVE |
| fullName | No | Full name |
| lastName | No | Last name |
| modelKey | No | Always "ulpUser" |
| firstName | No | First name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, indicating safe read operation. The description adds value by listing the return fields, but does not disclose other behavioral aspects like error handling or pagination. Given annotations, this is adequate but not exceptional.
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 extremely concise: one sentence stating purpose followed by a clear list of return fields. No unnecessary words, and the key information is front-loaded.
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 the tool's simplicity (1 parameter), high schema coverage, annotations, and presence of an output schema, the description fully covers the necessary information. It states the purpose and what is returned, which is sufficient for an agent to invoke 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 coverage is 100%, so the schema already documents the single parameter 'id' as 'ULP user ID'. The description does not add additional meaning beyond what the schema provides, meeting the baseline.
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 clearly states the action ('Get details') and the specific resource ('UniFi Identity (ULP) user by ID'). It distinguishes itself from siblings like protect_get_user (different user type) and protect_list_ulp_users (lists all).
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 guidance is provided on when to use this tool versus alternatives such as protect_get_user or protect_list_ulp_users. The description implies usage when a specific ULP user ID is known, but lacks explicit context or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_userARead-only
Get details for a specific Protect user by ID. Returns the same fields as protect_list_users entries: id, modelKey, name, firstName, lastName, email, ucoreUserId.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | User ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | User ID |
| name | No | Display name |
| No | Email address | |
| lastName | No | Last name |
| modelKey | No | Always "user" |
| firstName | No | First name |
| ucoreUserId | No | UniFi Core user UUID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark it as read-only and non-destructive. The description adds value by specifying the exact returned fields (id, modelKey, name, etc.), which is beyond what annotations provide. No contradictions.
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 sentence that concisely states the purpose and return fields. Every word is necessary; no wasted text.
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 (though not shown), the description explicitly lists all fields, making it complete. The tool is simple (single parameter, no nested objects), and the description covers everything needed.
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% with a single 'id' parameter described as 'User ID'. The description does not add new meaning beyond the schema. 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?
Clearly states 'Get details for a specific Protect user by ID.' The verb 'Get' and resource 'Protect user' are specific. It distinguishes from sibling tools like 'protect_list_users' (list) and other 'get' tools for different entities.
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 guidance on when to use vs. alternatives, but the purpose is clear. Given the context of sibling tools (e.g., protect_list_users for listing), usage is implied, but not explicitly stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_get_viewerARead-only
Get full details for a specific viewer by ID. Returns: id, modelKey, name, mac, state, liveview, streamLimit (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Viewer ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Device ID |
| mac | No | MAC address |
| name | No | Device name |
| state | No | CONNECTED | DISCONNECTED | ... |
| liveview | No | Assigned live view ID, or null |
| modelKey | No | Resource kind |
| streamLimit | No | Max concurrent streams (number) |
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 clear. Description adds value by listing returned fields and mentioning version (7.1.83 docs), which aids understanding of 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?
Two sentences: first states purpose, second lists return fields and version. Every sentence provides essential information with no 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 simple get-by-ID tool with an output schema, the description adequately covers purpose, parameters, and return fields. Version info adds completeness. Lacks mention of error conditions or required permissions, but annotations cover safety.
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% with a single parameter 'id' described as 'Viewer ID'. The description adds no additional meaning beyond the schema, 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?
Description clearly states 'Get full details for a specific viewer by ID', specifying verb (get) and resource (viewer), which distinguishes it from sibling tools like protect_list_viewers that return summaries.
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 guidance on when to use vs alternatives like protect_list_viewers. The description implies usage when you have an ID, but lacks when-not or alternative suggestions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_alarm_hubsARead-only
List all alarm hubs managed by UniFi Protect. Returns array; each alarm hub includes: id, modelKey ("linkstation"), name, mac, state, isAlarmHub, ledSettings (isEnabled), lastEvent, alarmHub (object) (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and destructiveHint=false; the description adds behavioral context by detailing the return array contents and citing documentation.
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 sentences: the first states the action, the second details the return format. No unnecessary 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 simple list tool with no parameters and good annotations, the description fully covers what the tool does and what it returns, including specific 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?
No parameters exist, so schema coverage is 100%. The description adds meaning beyond the schema by explaining the tool's purpose and output structure.
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 clearly states 'List all alarm hubs managed by UniFi Protect,' using a specific verb and resource, and distinguishes from sibling tools like protect_get_alarm_hub.
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 use for listing all alarm hubs, but does not explicitly state when to use this tool versus alternatives (e.g., protect_get_alarm_hub for a single hub).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_arm_profilesARead-only
List all arm profiles (only available when using the local alarm manager — the standalone NVR alarm system, not Protect cloud alerts). Returns array; each profile (7.1.83 docs): id, name, automations[], creator, schedules[], recordEverything, activationDelay (0 | 60000 | 300000 | 600000), createdAt, updatedAt.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, indicating safe read. The description adds value by specifying the availability condition (local alarm manager) and the structure of the returned array, which goes beyond what annotations provide.
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 a single sentence that packs essential info, but the inclusion of '7.1.83 docs' adds slight noise. Otherwise, it is front-loaded with the purpose and condition, making it efficient.
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 the tool's simplicity (no parameters, read-only list), the description covers the necessary context: when to use, what it returns, and the field details. It lacks mention of empty result or error cases, but those are not critical for a basic list tool with good annotations.
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 are no parameters, and schema coverage is effectively 100% (empty schema). Baseline for 0 parameters is 4, and the description does not need to add parameter information. It focuses on the output, which 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 clearly states the verb 'List' and the resource 'arm profiles', and distinguishes from siblings by specifying it's only available with the local alarm manager, not Protect cloud alerts. This makes the tool's purpose unambiguous and distinct from other list 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 explicitly states when to use this tool (only when using the local alarm manager) and implicitly when not to use it (Protect cloud alerts). No alternative tool is mentioned, but the condition is clear enough to guide the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_bridgesARead-only
List all bridges managed by UniFi Protect. Returns array; each bridge includes: id, modelKey, name, mac, state, platform, clients (array of MACs), maxClients (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the agent knows it's a safe read operation. The description adds beyond annotations by detailing the return array structure (fields: id, modelKey, name, mac, etc.) and referencing documentation for maxClients.
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 sentences: the first states the purpose, the second provides return details. Every sentence adds value, with no wasted words. Front-loaded purpose ensures quick understanding.
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 list tool with no parameters and an output schema (implied by the description of return fields), the description is complete. It lists the expected fields and references documentation for further detail, covering the user's needs.
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 are no parameters, and schema coverage is 100%. The description adds no parameter info, which is appropriate. Baseline for 0 parameters is 4, indicating no need for additional semantic content.
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 clearly states the action ('List') and the resource ('all bridges managed by UniFi Protect'), providing a specific verb and resource. It distinguishes from sibling tools like 'protect_get_bridge' which retrieves a single bridge.
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 when you need all bridges, but it does not explicitly state when to use this tool versus alternatives (e.g., 'protect_get_bridge' for a specific bridge). No exclusions or context are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_camerasARead-only
List all cameras managed by UniFi Protect. Returns array; each camera includes (Integration API 7.1.83-verified fields): id, mac, name, modelKey, state (CONNECTED/DISCONNECTED), activePatrolSlot, hasPackageCamera, hdrType, isMicEnabled, micVolume, videoMode, featureFlags (hasHdr, hasMic, hasSpeaker, hasLedStatus, smartDetectTypes[], smartDetectAudioTypes[], videoModes[], supportFullHdSnapshot), lcdMessage (type, resetAt, text), ledSettings (isEnabled, floodLed, welcomeLed), osdSettings (isNameEnabled, isDateEnabled, isLogoEnabled, isDebugEnabled, overlayLocation), smartDetectSettings (objectTypes[], audioTypes[]). The Integration API does NOT expose recording state, motion timestamps, connection/last-seen, firmware, host, or per-channel stream config.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and destructiveHint=false. The description adds significant behavioral context by listing exactly which fields are returned and, importantly, what the API does NOT expose (recording state, motion timestamps, etc.), surpassing what annotations provide.
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 lists fields. While dense with information, it is not overly verbose. The field enumeration could be streamlined but remains clear and complete.
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 zero parameters, a rich output schema (described in text), and full annotation coverage, the description provides complete context. It tells the agent exactly what to expect and what not to expect, with no 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?
There are zero parameters, and schema coverage is 100%. The description does not need to explain parameters; baseline is 4. No contradiction or missing info, but the description adds no parameter-specific value.
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 clearly states 'List all cameras managed by UniFi Protect', identifying the specific verb (list) and resource (cameras). It distinguishes from sibling list tools for other entities like protect_list_alarm_hubs, protect_list_bridges, etc.
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 provides clear context for when to use this tool (when listing cameras), but lacks explicit when-not-to-use or alternative references. Given siblings are all similarly named list tools for different entities, usage is implied but not explicitly guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_chimesARead-only
List all chimes managed by UniFi Protect. Returns array; each chime includes: id, modelKey, name, mac, state, cameraIds (array of camera IDs), ringSettings (array of objects: cameraId, volume, ringtoneId, repeatTimes) — verified live 7.1.83.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds value by detailing the return structure (array with fields including nested ringSettings) and includes a verification note ('verified live 7.1.83'), which builds trust and informs the agent about the output format.
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 extremely concise: two sentences, each serving a clear purpose. The first states the core function, the second details the return structure. No redundant words.
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 the tool's simplicity (no parameters, uses output schema), the description fully explains what the output contains, including field names and nested arrays. It is sufficiently complete for an agent to understand the tool's behavior.
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 input schema has no parameters and coverage is 100%, so the description does not need to add parameter details. It provides no param info, but baseline 3 is appropriate as per guidelines.
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 clearly states 'List all chimes managed by UniFi Protect', which specifies the verb (list) and resource (chimes). The name 'protect_list_chimes' distinguishes it from sibling tools like 'protect_get_chime' which retrieves a single chime, and other list tools for different entities.
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 for listing all chimes but does not explicitly state when to use this tool versus alternatives like protect_get_chime. No when-not conditions or alternative references are provided, so it relies on the tool name and context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_filesARead-only
List files of a given type (only 'animations' is currently supported — clips uploadable to G4 Doorbell screens). Returns array; each record (7.1.83 docs): name (server-generated), type, originalName, path.
| Name | Required | Description | Default |
|---|---|---|---|
| fileType | Yes | File type to list (only 'animations' is currently supported) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the description's mention of listing files is consistent. It adds value by describing the return structure (array of records with fields: name, type, originalName, path) and the context of clips for G4 Doorbell screens, but does not cover potential behaviors like pagination or errors.
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 a single, information-dense sentence that covers the tool's function, supported type, output format, and documentation reference. No wasted words, and the key information is front-loaded.
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 the tool's simplicity (one required parameter, annotations present, output schema exists), the description is complete. It provides functional purpose, input constraint, output structure, and a documentation reference, leaving no obvious gaps for an agent.
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 schema already describes the 'fileType' parameter, but the description adds context about the only supported value ('animations') and its purpose (clips for G4 Doorbell screens), enhancing understanding 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?
The description clearly states the tool lists files of a given type, with specific mention of the only currently supported type ('animations'). It distinguishes itself from sibling list tools (e.g., list_cameras, list_users) by being the only one for files.
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 when listing animation files for G4 Doorbell screens, and explicitly notes the limitation to 'animations'. However, it does not provide explicit when-not-to-use or compare to alternatives, which is acceptable given the tool's unique purpose among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_fobsARead-only
List all fobs managed by UniFi Protect. Returns array; each fob includes: id, modelKey, name, mac, state, awayState, buttonLabels, featureFlags (buttons[]), wirelessConnectionState (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only and non-destructive behavior. The description adds details about return structure (array with specific fields) and references documentation, enhancing transparency beyond 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?
Two sentences, front-loaded with purpose, then return details. Every sentence is informative with no 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 parameterless list tool with output schema, the description adequately covers what the tool returns. Missing explicit mention of output schema details, but the listed fields are sufficient.
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 are no parameters (empty schema), so the description naturally cannot add parameter details. With 100% schema coverage, the baseline of 4 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 clearly states the action ('list') and resource ('fobs managed by UniFi Protect'). It distinguishes from siblings like protect_get_fob by specifying 'list all' vs. a single fob.
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 guidance on when to use this tool vs. alternatives. Given many list tools exist, a brief note on differentiating from other list operations would help, but the tool's simplicity makes it acceptable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_lightsARead-only
List all lights managed by UniFi Protect. Returns array; each light includes: id, modelKey, name, mac, state, lightModeSettings (mode, enableAt), lightDeviceSettings (isIndicatorEnabled, pirDuration, pirSensitivity, ledLevel), isDark, isLightOn, isLightForceEnabled, lastMotion, isPirMotionDetected, camera (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnly and non-destructive behavior. The description adds value by detailing the return structure (array of lights with specific fields) and version reference, going beyond 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?
The description is concise with a single sentence stating purpose followed by a structured list of fields. Every sentence serves a purpose and is front-loaded.
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 the tool's simplicity (no parameters, simple list), the description fully covers the operation: it lists all lights and enumerates return fields. Output schema is effectively described.
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?
No parameters exist (0 params), so baseline 4 applies. The description adds no parameter information but compensates by describing output fields.
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 explicitly states 'List all lights' with a specific verb and resource, distinguishing from sibling 'protect_get_light' for single light retrieval.
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 provides clear context that this tool lists all lights, implicitly suggesting use for bulk retrieval. However, it does not explicitly mention when not to use or name alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_link_stationsARead-only
List all link stations managed by UniFi Protect. Returns array; each link station includes: id, modelKey ("linkstation"), name, mac, state, isAlarmHub, ledSettings (isEnabled), lastEvent, alarmHub (object) (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, ensuring a safe read operation. Description adds value beyond annotations by detailing the array structure and specific fields (id, modelKey, name, mac, state, etc.). No contradictions.
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: first states purpose, second describes return schema. Every word earns its place; no redundancy. Front-loaded with the action.
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 parameterless list tool with annotations and output schema described, the description is complete. It covers the return structure and key fields, leaving no ambiguity about the tool's function or output.
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?
No parameters exist, so schema coverage is 100%. Baseline is 4 per guidelines. The description compensates by outlining the return fields, which is particularly helpful since there is no parameter to describe.
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?
Description starts with clear verb 'List' and resource 'all link stations', using domain qualifier 'UniFi Protect'. Sibling tools include protect_list_lights, protect_list_sensors, etc., so this tool is uniquely identified.
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 instruction on when to use this tool versus alternatives like protect_get_link_station or protect_list_alarm_hubs. The description implies it is for listing all link stations, but does not rule out other contexts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_liveviewsARead-only
List all live views (camera grid layouts shown on viewers / in the Protect UI). Returns array; each liveview includes (Integration API 7.1.83-verified): id, modelKey, name, isDefault, isGlobal, layout (number, slot count), owner (user ID), slots (array of {cameras: string[], cycleMode, cycleInterval}). NOTE: slots use a cameras string-array, not a single cameraId.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, indicating safe reading. The description adds value by detailing the return format (array with specific fields) and notes about slots using a cameras string-array, which provides behavioral context beyond what annotations convey.
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 a single, well-structured sentence that front-loads the purpose, then lists key details. Every sentence adds value, with no redundancy or wasted words.
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 the tool's simplicity (no params, good annotations, output schema exists), the description is complete. It explains what live views are, the output structure, and a notable nuance about slots. It covers everything an agent needs to invoke and understand the result.
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 are no parameters in the schema, so schema_description_coverage is 100% trivially. With 0 parameters, the baseline is 4. The description does not need to add parameter information; it correctly focuses on the output.
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 clearly states the verb 'List' and the resource 'live views', with an explanation of what live views are (camera grid layouts). It effectively distinguishes from sibling tools like protect_get_liveview (single) and protect_list_viewers (viewer hardware).
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 provides no guidance on when to use this tool versus alternatives, such as when to use protect_get_liveview for a specific live view. It implies listing all, but lacks explicit when-not or alternative suggestions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_nvrsARead-only
Get the NVR (Network Video Recorder) console info. NOTE: despite the name, the Protect Integration API's /nvrs endpoint returns a SINGLE NVR object, not an array. Returns: id, modelKey, name, doorbellSettings (defaultMessageText, defaultMessageResetTimeoutMs, customMessages[], customImages[]), armMode (status, armedAt, willBeArmedAt, breachDetectedAt, breachEventCount, breachTriggerEventId, breachEventId).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | NVR ID |
| name | No | NVR name |
| armMode | No | |
| modelKey | No | Always "nvr" |
| doorbellSettings | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true; the description adds value by revealing that the API returns a single object instead of an array and lists the returned fields, providing behavioral context 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?
Two sentences; the first states the purpose, the second clarifies the name discrepancy and lists outputs. No wasted words, front-loaded.
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 tool with no parameters and an output schema, the description is complete: it explains the non-intuitive behavior and the return fields. No gaps remain.
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?
With no parameters and 100% schema coverage, baseline is 4. The description adds no parameter info (none needed) but compensates by detailing the return structure, which is beneficial.
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 clearly states what the tool does ('Get the NVR console info') and explicitly corrects the misleading name by noting the endpoint returns a single NVR object, not an array. This distinguishes it from sibling list tools like protect_list_cameras.
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 to use (to get NVR info) and the note about single object prevents misuse. It does not explicitly state alternatives, but given that no other NVR tool exists among siblings, the guidance is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_relaysARead-only
List all relays managed by UniFi Protect. Returns array; each relay includes: id, modelKey, name, mac, state, ledSettings (isEnabled), outputs (array), inputs (array), wirelessConnectionState (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
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 known. The description adds value by detailing the return fields (id, modelKey, name, etc.), which goes beyond annotations. However, it does not mention any potential limits, pagination, or other behavioral details.
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 two-sentence description is extremely concise and front-loaded. It begins with the primary action and then lists return fields. Every sentence earns its place; there is no fluff 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 simple read-only list tool with no parameters and an existing output schema, the description is mostly complete. It names all relay fields. However, it could mention whether the list is exhaustive or if any pagination applies, though this is minor.
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 are no parameters, and schema coverage is trivially 100%. Per guidelines, 0 params gives a baseline of 4. The description does not need to add parameter info, and it correctly omits unnecessary detail.
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 clearly states 'List all relays' with a specific verb and resource. It distinguishes from sibling tools like protect_get_relay which likely gets a single relay. The exact resource and scope are unambiguous.
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 (to get all relays) but does not explicitly state when to use this tool versus alternatives like protect_get_relay. No when-not guidance or exclusion criteria are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_sensorsARead-only
List all sensors managed by UniFi Protect. Returns array; each sensor includes: id, modelKey, name, mac, state, mountType, batteryStatus (percentage, isLow), stats (light, humidity, temperature), lightSettings, humiditySettings, temperatureSettings, isOpened, openStatusChangedAt, isMotionDetected, motionDetectedAt, motionSettings, glassBreakSettings, scheduleMode, armProfileIds, hasCustomSensitivityWhenArmed, alarmTriggeredAt, alarmSettings, leakDetectedAt, externalLeakDetectedAt, leakSettings, tamperingDetectedAt, wirelessConnectionState (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true and destructiveHint=false, making the safety profile clear. The description adds value by detailing the return format (array with fields like id, modelKey, name, etc.), going beyond annotations. However, it does not mention potential limits or pagination, which are minor gaps.
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 a single sentence followed by a detailed list of return fields. It is front-loaded with the primary purpose. The list is structured but slightly verbose; however, every element is relevant.
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 no parameters and an existing output schema, the description provides a thorough breakdown of returned fields. It lacks details on ordering, filtering, or authentication requirements, but these are 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?
The tool has no parameters, with schema coverage at 100%. Following guidelines, a baseline of 4 is appropriate since the description adds no param-specific information but cannot improve on an empty 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?
The description clearly states 'List all sensors managed by UniFi Protect', using a specific verb and resource. It distinguishes itself from sibling tools like protect_get_sensor (single sensor) and other list tools for different entities.
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 for retrieving all sensors but lacks explicit guidance on when to use this tool versus alternatives (e.g., protect_get_sensor for a single sensor, or other list tools). No when-not or exclusion criteria are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_sirensARead-only
List all sirens managed by UniFi Protect. Returns array; each siren includes: id, modelKey, name, mac, state, volume, ledSettings (isEnabled), sirenStatus (isActive, activatedAt, duration), connectionType, wirelessConnectionState (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. Description adds return structure details (fields like id, name, state, volume, etc.) and references documentation, going beyond 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?
Single sentence plus a bullet list of fields. Every sentence earns its place; no fluff.
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?
Complete for a list tool with no parameters. Annotations and output fields fully cover behavior. Sibling context makes selection straightforward.
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?
No parameters exist, so baseline is 4. Description adds no parameter semantics but compensates by listing returned fields, which aids agent understanding of output.
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?
Explicitly states 'List all sirens managed by UniFi Protect.' Clearly identifies action (list) and resource (sirens). Distinguished from sibling tool protect_get_siren which retrieves a single siren.
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?
Implies usage for listing all sirens, but lacks explicit when-to-use or when-not-to-use guidance. No mention of alternatives like protect_get_siren for filtering singular results.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_speakersARead-only
List all speakers managed by UniFi Protect. Returns array; each speaker includes: id, modelKey, name, mac, state, volume, micVolume, isMicEnabled, speakerState (status, mode), featureFlags (hasMic) (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds behavioral context (returns array, lists specific fields like state, volume) but does not go beyond what annotations and output schema suggest.
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 very concise: two sentences with no wasted words. It front-loads the main action then details outputs.
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 zero parameters, rich annotations, and an output schema (though not shown, the description lists fields), the description is complete for a simple list operation.
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?
Input schema has zero parameters, so parameter semantics are irrelevant. Baseline of 4 applies as the description does not need to compensate.
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 it lists all speakers managed by UniFi Protect, with specific fields listed. It clearly distinguishes from sibling tools (e.g., protect_list_cameras) by indicating the resource type (speakers).
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 (when you need speakers list) but does not explicitly state when to use it over alternatives or when not to use it. No comparison with sibling tools provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_ulp_usersARead-only
List all UniFi Identity (ULP) users. Returns array; each ULP user includes (Integration API 7.1.83-verified): id, modelKey, firstName, lastName, fullName, status (e.g. ACTIVE). Enrolled-credential detail (NFC cards, fingerprints) is NOT exposed by this API surface.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and destructiveHint=false, but the description adds value by confirming the read nature and disclosing that enrolled-credential details are not exposed. This goes beyond what annotations provide. No other behavioral aspects (e.g., pagination) are mentioned, but given the tool's simplicity, this is sufficient.
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 sentences with no wasted words. The first sentence clearly states the purpose, and the second provides essential details. It is front-loaded and efficient.
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-parameter list tool with an output schema available, the description covers the core purpose, return structure, and known limitations. It implicitly assumes the agent can handle the output schema for format details. Could be slightly enhanced by mentioning ordering or default count, but current level is adequate.
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 are no parameters (schema coverage 100% by default), but the description compensates by explaining the output structure and limitations. It specifies the exact fields returned and explicitly states what is excluded. This fully informs an agent of the tool's capabilities.
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 explicitly states 'List all UniFi Identity (ULP) users' with a specific verb and resource. It further details what each user includes (id, modelKey, etc.) and what is NOT exposed, leaving no ambiguity about the tool's function. The distinct resource type 'ULP users' differentiates it from sibling 'list_users' 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 provides context about returned fields and explicitly excludes credential detail, helping agents set expectations. However, it does not mention when to use this tool versus alternatives like protect_get_ulp_user for a single user. No explicit usage conditions or exclusions are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_usersARead-only
List all Protect users (filtered by the API key's access permissions). Returns array; each user includes (Integration API 7.1.83-verified): id, modelKey, name, firstName, lastName, email, ucoreUserId. The Integration API does NOT expose roles, permissions, login history, groups, or notification settings.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and destructiveHint=false. The description adds substantial behavioral context: the return type (array), exact fields returned (id, modelKey, etc.), and explicitly states what is NOT exposed (roles, permissions, etc.). This goes beyond 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?
The description is two sentences with no fluff. The first sentence immediately states the tool's purpose and scope. Every sentence provides necessary 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?
Given the tool's simplicity (no parameters), and the presence of an output schema, the description fully covers purpose, behavior, and return fields. It explicitly lists included fields and notable exclusions, making 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?
There are zero parameters, so schema coverage is 100% by default. Baseline is 4. The description does not add parameter information because none are needed. No deduction necessary.
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 clearly states the tool lists all Protect users, filtered by API key permissions. The verb 'list' and resource 'users' are specific, and it distinguishes from siblings like protect_get_user (singular) and protect_list_ulp_users (different user type).
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 using this tool to get a list of users visible to the API key. It does not explicitly mention when not to use it or suggest alternatives, but the sibling context provides differentiation. A slight gap in explicit exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_list_viewersARead-only
List all viewers managed by UniFi Protect. Returns array; each viewer includes: id, modelKey, name, mac, state, liveview, streamLimit (7.1.83 docs).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Array of items returned by the list endpoint |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true and destructiveHint=false, so the description does not need to restate safety. It adds return format details (array, fields). But it lacks info on pagination, rate limits, or authorization needs.
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 a single concise sentence that front-loads the purpose and includes essential return info. No word is wasted.
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 0 parameters, high schema coverage, presence of output schema, and low complexity, the description provides sufficient context. It explains what the tool returns, which is all that's needed.
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 input schema has 0 parameters, so description cannot add parameter meaning. Schema coverage is 100%. Baseline for 0 params is 4.
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 clearly states the verb 'list' and the resource 'viewers' with the context 'managed by UniFi Protect'. It immediately distinguishes from sibling list tools like protect_list_cameras or protect_list_nvrs.
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: when you need to list viewers. However, it does not explicitly state when to use it vs. alternatives or provide any exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_subscribe_devicesARead-only
Connect to the device update WebSocket and collect messages for a specified duration (1-30s). Returns {messages, duration, error?}; each message has {type: 'add'|'update'|'remove', modelKey: 'camera'|'light'|'sensor'|..., id, payload: partial device fields that changed}. Use to detect state changes like isRecording flipping, battery drops, or new devices being adopted — fields delivered are only those that changed, not the full device object.
| Name | Required | Description | Default |
|---|---|---|---|
| duration | No | Seconds to listen (1-30, default 5) |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Connection error, if any |
| duration | No | Actual listen duration in seconds (number) |
| messages | No | Captured WebSocket messages (add/update/remove or event envelopes) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds details beyond annotations: WebSocket connection, duration collection, partial updates only (changed fields), and potential error. Annotations already indicate read-only and non-destructive, so description supplements well.
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 core action, then return structure, examples, and behavioral note. Every sentence adds value; no fluff.
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 the tool's complexity (WebSocket, time-bound subscription, partial updates), the description covers the return format, message structure, field change semantics, and usage context. Output schema exists but description still provides key behavioral info.
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?
Single parameter 'duration' with schema description already covering defaults and range. Description reiterates 'specified duration (1-30s)' but adds no new semantic value beyond 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?
Clearly describes connecting to a WebSocket to collect device update messages for a specified duration. Specifies return structure and message content, distinguishing from sibling 'get'/'list' tools and the broader 'protect_subscribe_events'.
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 specific use cases like detecting state changes (isRecording flipping, battery drops, new devices). Does not explicitly mention when not to use, but the examples give strong guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
protect_subscribe_eventsARead-only
Connect to the Protect event WebSocket and collect messages for a specified duration (1-30s). Returns {messages, duration, error?}; each event message includes: id, type ('motion' | 'ring' | 'smartDetectZone' | 'smartDetectLine' | 'sensorMotion' | 'sensorAlarm' | 'fingerprint' | 'nfcCard' | ...), start, end (null while ongoing), camera/sensor id, score, smartDetectTypes (['person','vehicle','animal','package','license_plate','face']), metadata (e.g. detected license plate text, NFC card id, fingerprint id, ULP user match).
| Name | Required | Description | Default |
|---|---|---|---|
| duration | No | Seconds to listen (1-30, default 5) |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Connection error, if any |
| duration | No | Actual listen duration in seconds (number) |
| messages | No | Captured WebSocket messages (add/update/remove or event envelopes) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint and destructiveHint false. Description adds return format, event types, and message structure, which is useful beyond annotations. No contradiction.
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 purpose, followed by return details. No wasted words.
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 single parameter and presence of output schema, description covers return structure and event types adequately. Lacks details on error conditions or connection behavior, but sufficient for simple subscription.
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?
Single parameter 'duration' is fully described in schema (default, min, max). Description does not add new semantic info beyond 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?
Description clearly states it connects to a WebSocket to collect event messages with a duration range. It distinguishes from list/get tools but does not explicitly contrast with sibling subscribe_devices.
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 or when-not-to-use guidance. Implies real-time event monitoring but lacks context on prerequisites or alternatives.
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. Dates show when Glama detected each change.
11 tool updates
v2.10.0- Added
protect_get_fob - Added
protect_get_info - Added
protect_get_link_station - Added
protect_get_rtsp_streams - Added
protect_list_arm_profiles - Added
protect_list_chimes - Added
protect_list_fobs - Added
protect_list_link_stations - Added
protect_list_nvrs - Added
protect_list_speakers - Added
protect_list_viewers
11 tool updates
v2.9.0- Removed
protect_get_fob - Removed
protect_get_info - Removed
protect_get_link_station - Removed
protect_get_rtsp_streams - Removed
protect_list_arm_profiles - Removed
protect_list_chimes - Removed
protect_list_fobs - Removed
protect_list_link_stations - Removed
protect_list_nvrs - Removed
protect_list_speakers - Removed
protect_list_viewers
28 tool updates
v2.7.5- Changed
protect_get_alarm_hub4 fields changed- added
Output schema / properties / alarmHubAdded value: +{ + "description": "Alarm hub status (object: armed, battery, connector, cover, output, input, …)" +} - added
Output schema / properties / isAlarmHubAdded value: +{ + "description": "Whether this device is an alarm hub (boolean)" +} - added
Output schema / properties / lastEventAdded value: +{ + "description": "Last event timestamp in epoch ms (number)" +} - added
Output schema / properties / ledSettingsAdded value: +{ + "description": "LED settings (object: isEnabled)" +}
- Changed
protect_get_bridge3 fields changed- added
Output schema / properties / clientsAdded value: +{ + "description": "Connected client MACs (array of strings)" +} - added
Output schema / properties / maxClientsAdded value: +{ + "description": "Max client capacity (number)" +} - added
Output schema / properties / platformAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Hardware platform, e.g. \"mt7621\"" +}
- Changed
protect_get_camera4 fields changed- added
Output schema / properties / lcdMessage / additionalPropertiesAdded value: +{} - removed
Output schema / properties / lcdMessage / descriptionRemoved value: -"Doorbell LCD message (object; often empty {})" - added
Output schema / properties / lcdMessage / propertiesAdded value: +{ + "resetAt": { + "description": "Auto-reset timestamp in epoch ms, or null (number|null)" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Message text shown on the doorbell LCD" + }, + "type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Message type, e.g. \"CUSTOM_MESSAGE\", \"LEAVE_PACKAGE_AT_DOOR\", \"DO_NOT_DISTURB\"" + } +} - added
Output schema / properties / lcdMessage / typeAdded value: +"object"
- Changed
protect_get_chime2 fields changed- added
Output schema / properties / cameraIdsAdded value: +{ + "description": "Paired camera IDs (array of strings)" +} - added
Output schema / properties / ringSettingsAdded value: +{ + "description": "Per-camera ring config (array of objects: cameraId, volume, ringtoneId, repeatTimes)" +}
- Changed
protect_get_fob4 fields changed- added
Output schema / properties / awayStateAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Away state, e.g. \"ONLINE\"" +} - added
Output schema / properties / buttonLabelsAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Button label preset, e.g. \"securityActions\"" +} - added
Output schema / properties / featureFlagsAdded value: +{ + "description": "Feature flags (object: buttons[])" +} - added
Output schema / properties / wirelessConnectionStateAdded value: +{ + "description": "Wireless link state (object)" +}
- Changed
protect_get_light8 fields changed- added
Output schema / properties / cameraAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Paired camera ID" +} - added
Output schema / properties / isDarkAdded value: +{ + "description": "Whether it is currently dark out (boolean)" +} - added
Output schema / properties / isLightForceEnabledAdded value: +{ + "description": "Main LED force-enabled (boolean)" +} - added
Output schema / properties / isLightOnAdded value: +{ + "description": "Whether the light is currently on (boolean)" +} - added
Output schema / properties / isPirMotionDetectedAdded value: +{ + "description": "PIR motion currently detected (boolean)" +} - added
Output schema / properties / lastMotionAdded value: +{ + "description": "Last motion timestamp in epoch ms (number)" +} - added
Output schema / properties / lightDeviceSettingsAdded value: +{ + "description": "Hardware settings (object: isIndicatorEnabled, pirDuration, pirSensitivity, ledLevel)" +} - added
Output schema / properties / lightModeSettingsAdded value: +{ + "description": "Activation settings (object: mode, enableAt)" +}
- Changed
protect_get_link_station4 fields changed- added
Output schema / properties / alarmHubAdded value: +{ + "description": "Alarm hub status (object: armed, battery, connector, cover, output, input, …)" +} - added
Output schema / properties / isAlarmHubAdded value: +{ + "description": "Whether this device is an alarm hub (boolean)" +} - added
Output schema / properties / lastEventAdded value: +{ + "description": "Last event timestamp in epoch ms (number)" +} - added
Output schema / properties / ledSettingsAdded value: +{ + "description": "LED settings (object: isEnabled)" +}
- Changed
protect_get_relay4 fields changed- added
Output schema / properties / inputsAdded value: +{ + "description": "Input channels (array of objects)" +} - added
Output schema / properties / ledSettingsAdded value: +{ + "description": "LED settings (object: isEnabled)" +} - added
Output schema / properties / outputsAdded value: +{ + "description": "Output channels (array of objects)" +} - added
Output schema / properties / wirelessConnectionStateAdded value: +{ + "description": "Wireless link state (object)" +}
- Changed
protect_get_sensor22 fields changed- added
Output schema / properties / alarmSettingsAdded value: +{ + "description": "Alarm settings (object: isEnabled)" +} - added
Output schema / properties / alarmTriggeredAtAdded value: +{ + "description": "Last alarm timestamp in epoch ms (number)" +} - added
Output schema / properties / armProfileIdsAdded value: +{ + "description": "Arm profile IDs this sensor belongs to (array of strings)" +} - added
Output schema / properties / batteryStatusAdded value: +{ + "description": "Battery status (object: percentage, isLow)" +} - added
Output schema / properties / externalLeakDetectedAtAdded value: +{ + "description": "Last external-leak timestamp in epoch ms (number)" +} - added
Output schema / properties / glassBreakSettingsAdded value: +{ + "description": "Glass-break detection settings (object)" +} - added
Output schema / properties / hasCustomSensitivityWhenArmedAdded value: +{ + "description": "Custom armed sensitivity enabled (boolean)" +} - added
Output schema / properties / humiditySettingsAdded value: +{ + "description": "Humidity threshold settings (object)" +} - added
Output schema / properties / isMotionDetectedAdded value: +{ + "description": "Motion currently detected (boolean)" +} - added
Output schema / properties / isOpenedAdded value: +{ + "description": "Open/close contact state (boolean)" +} - added
Output schema / properties / leakDetectedAtAdded value: +{ + "description": "Last leak timestamp in epoch ms (number)" +} - added
Output schema / properties / leakSettingsAdded value: +{ + "description": "Leak detection settings (object)" +} - added
Output schema / properties / lightSettingsAdded value: +{ + "description": "Light threshold settings (object)" +} - added
Output schema / properties / motionDetectedAtAdded value: +{ + "description": "Last motion timestamp in epoch ms (number)" +} - added
Output schema / properties / motionSettingsAdded value: +{ + "description": "Motion detection settings (object)" +} - added
Output schema / properties / mountTypeAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Mount type, e.g. \"door\", \"leak\", \"garage\"" +} - added
Output schema / properties / openStatusChangedAtAdded value: +{ + "description": "Open-status change timestamp in epoch ms (number)" +} - added
Output schema / properties / scheduleModeAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Schedule mode: \"always\" | \"when_armed\"" +} - added
Output schema / properties / statsAdded value: +{ + "description": "Environmental stats (object: light, humidity, temperature)" +} - added
Output schema / properties / tamperingDetectedAtAdded value: +{ + "description": "Last tampering timestamp in epoch ms (number)" +} - added
Output schema / properties / temperatureSettingsAdded value: +{ + "description": "Temperature threshold settings (object)" +} - added
Output schema / properties / wirelessConnectionStateAdded value: +{ + "description": "Wireless link state (object: signalState, batteryStatus, bridge)" +}
- Changed
protect_get_siren5 fields changed- added
Output schema / properties / connectionTypeAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Connection type, e.g. \"lora\"" +} - added
Output schema / properties / ledSettingsAdded value: +{ + "description": "LED settings (object: isEnabled)" +} - added
Output schema / properties / sirenStatusAdded value: +{ + "description": "Current siren status (object: isActive, activatedAt, duration)" +} - added
Output schema / properties / volumeAdded value: +{ + "description": "Siren volume (number)" +} - added
Output schema / properties / wirelessConnectionStateAdded value: +{ + "description": "Wireless link state (object)" +}
- Changed
protect_get_snapshot1 field changed- added
Input schema / properties / channelAdded value: +{ + "description": "Camera channel to capture. Use \"package\" for cameras with hasPackageCamera=true (defaults to main)", + "enum": [ + "main", + "package" + ], + "type": "string" +}
- Changed
protect_get_speaker5 fields changed- added
Output schema / properties / featureFlagsAdded value: +{ + "description": "Feature flags (object: hasMic)" +} - added
Output schema / properties / isMicEnabledAdded value: +{ + "description": "Microphone enabled (boolean)" +} - added
Output schema / properties / micVolumeAdded value: +{ + "description": "Microphone volume (number)" +} - added
Output schema / properties / speakerStateAdded value: +{ + "description": "Speaker state (object: status, mode)" +} - added
Output schema / properties / volumeAdded value: +{ + "description": "Speaker volume (number)" +}
- Changed
protect_get_viewer2 fields changed- added
Output schema / properties / liveviewAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Assigned live view ID, or null" +} - added
Output schema / properties / streamLimitAdded value: +{ + "description": "Max concurrent streams (number)" +}
- Changed
protect_list_alarm_hubs4 fields changed- added
Output schema / properties / result / items / properties / alarmHubAdded value: +{ + "description": "Alarm hub status (object: armed, battery, connector, cover, output, input, …)" +} - added
Output schema / properties / result / items / properties / isAlarmHubAdded value: +{ + "description": "Whether this device is an alarm hub (boolean)" +} - added
Output schema / properties / result / items / properties / lastEventAdded value: +{ + "description": "Last event timestamp in epoch ms (number)" +} - added
Output schema / properties / result / items / properties / ledSettingsAdded value: +{ + "description": "LED settings (object: isEnabled)" +}
- Changed
protect_list_arm_profiles8 fields changed- added
Output schema / properties / result / items / properties / activationDelayAdded value: +{ + "description": "Activation delay in ms: 0 | 60000 | 300000 | 600000 (number)" +} - added
Output schema / properties / result / items / properties / automationsAdded value: +{ + "description": "Associated automation IDs (array of strings)" +} - added
Output schema / properties / result / items / properties / createdAtAdded value: +{ + "description": "Creation timestamp in epoch ms (number)" +} - added
Output schema / properties / result / items / properties / creatorAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ID of the user who created the profile" +} - removed
Output schema / properties / result / items / properties / modelKeyRemoved value: -{ - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Resource kind" -} - added
Output schema / properties / result / items / properties / recordEverythingAdded value: +{ + "description": "Record everything while active (boolean)" +} - added
Output schema / properties / result / items / properties / schedulesAdded value: +{ + "description": "Arm schedules (array of objects)" +} - added
Output schema / properties / result / items / properties / updatedAtAdded value: +{ + "description": "Last update timestamp in epoch ms (number)" +}
- Changed
protect_list_bridges3 fields changed- added
Output schema / properties / result / items / properties / clientsAdded value: +{ + "description": "Connected client MACs (array of strings)" +} - added
Output schema / properties / result / items / properties / maxClientsAdded value: +{ + "description": "Max client capacity (number)" +} - added
Output schema / properties / result / items / properties / platformAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Hardware platform, e.g. \"mt7621\"" +}
- Changed
protect_list_cameras4 fields changed- added
Output schema / properties / result / items / properties / lcdMessage / additionalPropertiesAdded value: +{} - removed
Output schema / properties / result / items / properties / lcdMessage / descriptionRemoved value: -"Doorbell LCD message (object; often empty {})" - added
Output schema / properties / result / items / properties / lcdMessage / propertiesAdded value: +{ + "resetAt": { + "description": "Auto-reset timestamp in epoch ms, or null (number|null)" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Message text shown on the doorbell LCD" + }, + "type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Message type, e.g. \"CUSTOM_MESSAGE\", \"LEAVE_PACKAGE_AT_DOOR\", \"DO_NOT_DISTURB\"" + } +} - added
Output schema / properties / result / items / properties / lcdMessage / typeAdded value: +"object"
- Changed
protect_list_chimes2 fields changed- added
Output schema / properties / result / items / properties / cameraIdsAdded value: +{ + "description": "Paired camera IDs (array of strings)" +} - added
Output schema / properties / result / items / properties / ringSettingsAdded value: +{ + "description": "Per-camera ring config (array of objects: cameraId, volume, ringtoneId, repeatTimes)" +}
- Changed
protect_list_files6 fields changed- removed
Output schema / properties / result / items / properties / idRemoved value: -{ - "description": "File ID", - "type": "string" -} - removed
Output schema / properties / result / items / properties / modelKeyRemoved value: -{ - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Resource kind" -} - changed
Output schema / properties / result / items / properties / name / descriptionPrevious value: -"File name"New value: +"Stored file name (server-generated)" - added
Output schema / properties / result / items / properties / originalNameAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Original uploaded file name" +} - added
Output schema / properties / result / items / properties / pathAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Server-side storage path" +} - added
Output schema / properties / result / items / properties / typeAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Asset file type, e.g. \"animations\"" +}
- Changed
protect_list_fobs4 fields changed- added
Output schema / properties / result / items / properties / awayStateAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Away state, e.g. \"ONLINE\"" +} - added
Output schema / properties / result / items / properties / buttonLabelsAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Button label preset, e.g. \"securityActions\"" +} - added
Output schema / properties / result / items / properties / featureFlagsAdded value: +{ + "description": "Feature flags (object: buttons[])" +} - added
Output schema / properties / result / items / properties / wirelessConnectionStateAdded value: +{ + "description": "Wireless link state (object)" +}
- Changed
protect_list_lights8 fields changed- added
Output schema / properties / result / items / properties / cameraAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Paired camera ID" +} - added
Output schema / properties / result / items / properties / isDarkAdded value: +{ + "description": "Whether it is currently dark out (boolean)" +} - added
Output schema / properties / result / items / properties / isLightForceEnabledAdded value: +{ + "description": "Main LED force-enabled (boolean)" +} - added
Output schema / properties / result / items / properties / isLightOnAdded value: +{ + "description": "Whether the light is currently on (boolean)" +} - added
Output schema / properties / result / items / properties / isPirMotionDetectedAdded value: +{ + "description": "PIR motion currently detected (boolean)" +} - added
Output schema / properties / result / items / properties / lastMotionAdded value: +{ + "description": "Last motion timestamp in epoch ms (number)" +} - added
Output schema / properties / result / items / properties / lightDeviceSettingsAdded value: +{ + "description": "Hardware settings (object: isIndicatorEnabled, pirDuration, pirSensitivity, ledLevel)" +} - added
Output schema / properties / result / items / properties / lightModeSettingsAdded value: +{ + "description": "Activation settings (object: mode, enableAt)" +}
- Changed
protect_list_link_stations4 fields changed- added
Output schema / properties / result / items / properties / alarmHubAdded value: +{ + "description": "Alarm hub status (object: armed, battery, connector, cover, output, input, …)" +} - added
Output schema / properties / result / items / properties / isAlarmHubAdded value: +{ + "description": "Whether this device is an alarm hub (boolean)" +} - added
Output schema / properties / result / items / properties / lastEventAdded value: +{ + "description": "Last event timestamp in epoch ms (number)" +} - added
Output schema / properties / result / items / properties / ledSettingsAdded value: +{ + "description": "LED settings (object: isEnabled)" +}
- Changed
protect_list_nvrs2 fields changed- added
Output schema / properties / armMode / properties / armProfileIdAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Active arm profile ID (present when arming/armed)" +} - changed
Output schema / properties / armMode / properties / status / descriptionPrevious value: -"disabled | armed | ..."New value: +"disabled | arming | armed | ..."
- Changed
protect_list_relays4 fields changed- added
Output schema / properties / result / items / properties / inputsAdded value: +{ + "description": "Input channels (array of objects)" +} - added
Output schema / properties / result / items / properties / ledSettingsAdded value: +{ + "description": "LED settings (object: isEnabled)" +} - added
Output schema / properties / result / items / properties / outputsAdded value: +{ + "description": "Output channels (array of objects)" +} - added
Output schema / properties / result / items / properties / wirelessConnectionStateAdded value: +{ + "description": "Wireless link state (object)" +}
- Changed
protect_list_sensors22 fields changed- added
Output schema / properties / result / items / properties / alarmSettingsAdded value: +{ + "description": "Alarm settings (object: isEnabled)" +} - added
Output schema / properties / result / items / properties / alarmTriggeredAtAdded value: +{ + "description": "Last alarm timestamp in epoch ms (number)" +} - added
Output schema / properties / result / items / properties / armProfileIdsAdded value: +{ + "description": "Arm profile IDs this sensor belongs to (array of strings)" +} - added
Output schema / properties / result / items / properties / batteryStatusAdded value: +{ + "description": "Battery status (object: percentage, isLow)" +} - added
Output schema / properties / result / items / properties / externalLeakDetectedAtAdded value: +{ + "description": "Last external-leak timestamp in epoch ms (number)" +} - added
Output schema / properties / result / items / properties / glassBreakSettingsAdded value: +{ + "description": "Glass-break detection settings (object)" +} - added
Output schema / properties / result / items / properties / hasCustomSensitivityWhenArmedAdded value: +{ + "description": "Custom armed sensitivity enabled (boolean)" +} - added
Output schema / properties / result / items / properties / humiditySettingsAdded value: +{ + "description": "Humidity threshold settings (object)" +} - added
Output schema / properties / result / items / properties / isMotionDetectedAdded value: +{ + "description": "Motion currently detected (boolean)" +} - added
Output schema / properties / result / items / properties / isOpenedAdded value: +{ + "description": "Open/close contact state (boolean)" +} - added
Output schema / properties / result / items / properties / leakDetectedAtAdded value: +{ + "description": "Last leak timestamp in epoch ms (number)" +} - added
Output schema / properties / result / items / properties / leakSettingsAdded value: +{ + "description": "Leak detection settings (object)" +} - added
Output schema / properties / result / items / properties / lightSettingsAdded value: +{ + "description": "Light threshold settings (object)" +} - added
Output schema / properties / result / items / properties / motionDetectedAtAdded value: +{ + "description": "Last motion timestamp in epoch ms (number)" +} - added
Output schema / properties / result / items / properties / motionSettingsAdded value: +{ + "description": "Motion detection settings (object)" +} - added
Output schema / properties / result / items / properties / mountTypeAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Mount type, e.g. \"door\", \"leak\", \"garage\"" +} - added
Output schema / properties / result / items / properties / openStatusChangedAtAdded value: +{ + "description": "Open-status change timestamp in epoch ms (number)" +} - added
Output schema / properties / result / items / properties / scheduleModeAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Schedule mode: \"always\" | \"when_armed\"" +} - added
Output schema / properties / result / items / properties / statsAdded value: +{ + "description": "Environmental stats (object: light, humidity, temperature)" +} - added
Output schema / properties / result / items / properties / tamperingDetectedAtAdded value: +{ + "description": "Last tampering timestamp in epoch ms (number)" +} - added
Output schema / properties / result / items / properties / temperatureSettingsAdded value: +{ + "description": "Temperature threshold settings (object)" +} - added
Output schema / properties / result / items / properties / wirelessConnectionStateAdded value: +{ + "description": "Wireless link state (object: signalState, batteryStatus, bridge)" +}
- Changed
protect_list_sirens5 fields changed- added
Output schema / properties / result / items / properties / connectionTypeAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Connection type, e.g. \"lora\"" +} - added
Output schema / properties / result / items / properties / ledSettingsAdded value: +{ + "description": "LED settings (object: isEnabled)" +} - added
Output schema / properties / result / items / properties / sirenStatusAdded value: +{ + "description": "Current siren status (object: isActive, activatedAt, duration)" +} - added
Output schema / properties / result / items / properties / volumeAdded value: +{ + "description": "Siren volume (number)" +} - added
Output schema / properties / result / items / properties / wirelessConnectionStateAdded value: +{ + "description": "Wireless link state (object)" +}
- Changed
protect_list_speakers5 fields changed- added
Output schema / properties / result / items / properties / featureFlagsAdded value: +{ + "description": "Feature flags (object: hasMic)" +} - added
Output schema / properties / result / items / properties / isMicEnabledAdded value: +{ + "description": "Microphone enabled (boolean)" +} - added
Output schema / properties / result / items / properties / micVolumeAdded value: +{ + "description": "Microphone volume (number)" +} - added
Output schema / properties / result / items / properties / speakerStateAdded value: +{ + "description": "Speaker state (object: status, mode)" +} - added
Output schema / properties / result / items / properties / volumeAdded value: +{ + "description": "Speaker volume (number)" +}
- Changed
protect_list_viewers2 fields changed- added
Output schema / properties / result / items / properties / liveviewAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Assigned live view ID, or null" +} - added
Output schema / properties / result / items / properties / streamLimitAdded value: +{ + "description": "Max concurrent streams (number)" +}
38 tool updates
v2.7.4- First observed
protect_get_alarm_hub - First observed
protect_get_bridge - First observed
protect_get_camera - First observed
protect_get_chime - First observed
protect_get_fob - First observed
protect_get_info - First observed
protect_get_light - First observed
protect_get_link_station - First observed
protect_get_liveview - First observed
protect_get_relay - First observed
protect_get_rtsp_streams - First observed
protect_get_sensor - First observed
protect_get_siren - First observed
protect_get_snapshot - First observed
protect_get_speaker - First observed
protect_get_ulp_user - First observed
protect_get_user - First observed
protect_get_viewer - First observed
protect_list_alarm_hubs - First observed
protect_list_arm_profiles - First observed
protect_list_bridges - First observed
protect_list_cameras - First observed
protect_list_chimes - First observed
protect_list_files - First observed
protect_list_fobs - First observed
protect_list_lights - First observed
protect_list_link_stations - First observed
protect_list_liveviews - First observed
protect_list_nvrs - First observed
protect_list_relays - First observed
protect_list_sensors - First observed
protect_list_sirens - First observed
protect_list_speakers - First observed
protect_list_ulp_users - First observed
protect_list_users - First observed
protect_list_viewers - First observed
protect_subscribe_devices - First observed
protect_subscribe_events
TDQS
Most tools are clearly distinct with a consistent prefix and verb-noun pattern. However, protect_get_link_station and protect_get_alarm_hub both return objects with modelKey 'linkstation', causing potential confusion between link stations and alarm hubs. protect_list_nvrs is also misleading as it returns a single object.
All tools follow the 'protect_verb_noun' pattern with lowercase verbs (get, list, subscribe) and nouns. This is entirely consistent across all 38 tools, making it easy for agents to predict tool names.
With 38 tools, the count exceeds the recommended maximum of 25 for a well-scoped server. While the domain is broad, many tools are get/list pairs for different entity types, and the set could be streamlined. This feels heavy and may overwhelm agents.
The tool set is heavily read-only, with only get, list, and subscribe operations. There are no create, update, or delete tools for any entity, and a referenced protect_create_rtsp_stream tool is missing. This severely limits the ability to manage the Protect system, leaving significant gaps in the API surface.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
The OpenRouter for tools. One MCP connection gives any AI agent 254 hosted tools, pay per call.
AI-callable tools for API mocking, testing, monitoring, security, and automation.
Universal AI API Orchestrator — 1,554 tools, 96 services. One install.
Marketo MCP server for AI. 130 tools to operate Marketo from Claude, Cursor, or ChatGPT.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceExposes the UniFi Network Integration API as MCP tools, dynamically loaded from JSON manifests, with read-only mode by default.MIT
- AlicenseBqualityDmaintenanceProvides 170+ tools to manage UniFi networks via the internal controller API, enabling AI assistants to perform full network management including clients, devices, WLANs, firewall, and more.64MIT
- AlicenseBqualityAmaintenanceExposes the Firewalla MSP API as tools for Claude Code and other MCP clients, enabling natural-language management of Firewalla boxes, alarms, rules, devices, flows, target lists, and trends with full read/write capabilities.19MIT
- AlicenseNot gradedqualityCmaintenanceA safety-first MCP server for managing UniFi networks, exposing 17 tools for telemetry, diagnostics, and guarded mutations with dry-run previews and confirm requirements.14MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/owine/unifi-protect-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server