Port OS Smart Home
Server Details
Port OS Smart Home helps you connect your AI to your existing devices.
Works with philips, sonos, smartthings, tuya, nest, ring, alexa, etc.
Cloud hosted service. Connect your device to Port OS cloud, then connect Claude/ChatGPT/etc via Port OS.
For example:
turn off lights, control brightness, colors
check temperature, set thermostat
watch your cameras,
check your batteries, sensors
ping your phone, wallet trackers
lock door locks set pins
run your robo vacuums
- Status
- Healthy
- OAuth
- Works in Glama
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
TDQS
Scored across 10 tools
The tools are mostly distinct: control performs actions, endpoint_query/group_query discover and read, endpoint_manage/group_manage change metadata, and subscription tools are separate. The main ambiguity is endpoint_query vs endpoint_show, since both can provide device state, and control is a very broad catch-all action tool, though its role is still distinguishable.
Names are consistently snake_case and organized by resource prefix: endpoint_*, group_*, and subscription_*. The bare control tool and the compound subscription_label_edit are minor deviations from the dominant resource_action pattern but remain clear.
Ten tools is well within the 3–15 sweet spot for a broad smart-home hub, and each area—discovery, action dispatch, metadata management, and subscriptions—has a place. Four subscription tools are slightly heavy for an ancillary feature, but they remain justified by distinct lifecycle operations.
Endpoint/group discovery, metadata management, and generic command dispatch give broad lifecycle coverage for smart-home control. Subscription tools cover list, inspect, cancel, and label editing but not creation, which is a gap for setting up a new event monitor; otherwise there are no major dead ends.
Available Tools
10 toolscontrolADestructiveInspect
Control connected devices and services, retrieve results, and capture camera snapshots.
Discover the device with endpoint_query or the room with group_query. Copy its full id, message and optional routeId; use the documented payload for the declared message. Send a matching payload ({} for a command without fields). Preserve the account that returned the IDs and clarify ambiguous targets before writes.
Most controls return status accepted: dispatch succeeded, but the physical outcome is unconfirmed. For result-returning commands, such as search, library pages and get-snapshot, set waitForResult=true. A correlated result returns status responded; snapshots also return image pixels and timeOfSample. Outbound declarations include events, so they do not guarantee that every command responds. For playback, volume and power, omit waitForResult and verify fresh state using endpoint_query or group_query with declared expand capabilities and forceDeviceAttributeQuery=true.
Live music queue recipe for "set up a playlist and play it on my Sonos": build an active playback queue unless the customer also asks to save a reusable library playlist. This recipe is available to tools-only clients without resources/read or bundled skills.
Discover the Spotify library and the requested speaker or native group. On the library's declared media-search/search-media message, use payload {"query":"","type":"track"} and waitForResult=true. Copy playable canonical track IDs from the returned tracks; do not invent IDs or pass a search phrase to playback.
Select the target route declaring media-queue, preferring the native Sonos route when available. Check its supportedMediaResources and maxItemsPerPlay. Send one play-queue message with payload {"mediaIds":["",""]} and the copied routeId. This starts a new ordered selection. play-queue has no queueVersion field; requiresQueueVersion applies only to add-to-queue. Do not emulate a queue with repeated single-track play-media commands.
Send get-queue with payload {} and waitForResult=true on the same target and route. queue-contents returns currentMediaId, upcoming mediaIds, complete and an optional queueVersion. complete=false is a limited window, not proof that other songs are absent. Read FRESH media-player observations with endpoint_query/group_query, expand=["media-player"] and forceDeviceAttributeQuery=true before claiming playback.
To add music without restarting, search for another track and send add-to-queue once with {"mediaId":""}. If requiresQueueVersion=true, first read get-queue and include its exact queueVersion in that append payload. Spotify Connect does not accept queueVersion; omit it there. Read the queue again after each append. A conflict or uncertain write requires inspection, never an automatic retry or replacement selection. No saved-playlist command is needed for this live-queue workflow.
A failed search does not establish that the speaker stopped or the whole connection is unavailable. Preserve current playback, report the failed operation, and use fresh device observations for playback claims. Do not substitute remembered song names or invented IDs for returned playable tracks. The search payload type is lowercase "track", not the uppercase capability configuration label "TRACK".
Room lighting scenes: use group_query with expand:["scene"] and forceDeviceAttributeQuery:true, select the requested native provider group/route, and inspect its declared messages. To recall an available scene, send scene/activate with {"sceneId":""} on that group and route. To save a new scene, first set the requested member lighting states, then send its declared scene/create-scene with {"name":""} and waitForResult=true. This snapshots the group's current light settings; it does not activate the scene. Use the returned scene-created.sceneId for activate, and fresh-query available-scenes before repeating an uncertain create. After recall, verify each affected light's fresh power/brightness and supported color state; dispatch acceptance or a scene label alone does not prove every light changed. Never create or recall a scene on another room or provider route as a fallback.
Use only capabilities and commands declared by the selected device or service. Examples of device classes and providers, subject to the connected integration's support:
Lights, switches and plugs: on/off and brightness (Philips Hue, Tuya, TP-Link).
Phones, tablets, laptops, wallets and trackers: locate or ring (Apple Find My, Tile).
Thermostats and temperature sensors: heat/cool settings; read ambient temperature with endpoint_query (Nest, Tuya, ecobee).
Cameras: request a declared get-snapshot command and inspect the returned pixels (Ring, Nest and other cameras). A snapshot is distinct from live video.
Connectivity and battery: check declared observations with endpoint_query for phones, watches, locks and other devices.
Smart locks and PINs: use declared lock and PIN commands (August, Yale, Ring, Seam).
Home appliances: supported controls and running-state observations (Samsung, LG, Xiaomi).
Robot vacuums: clean rooms and return to dock (Roomba, Roborock, Dreame). Send clean-room to the robot listing the room in controllableGroups with {"groupIds": []}. Bounded remote driving requires fresh visual feedback; cleaning is not navigation.
Speakers and announcements: supported speech and audio playback (Sonos, Alexa, Nest cameras).
TVs, remotes and media libraries: playback, volume, search and declared playlist operations (Spotify, Fire TV, YouTube, Chrome, TCL, Samsung, LG).
Files and photos: declared browse, download, upload, rename, move and delete commands (iCloud Photos, iCloud Drive, Google Drive, Outlook). download-file returns a URI; catalog presence alone does not establish upload support.
Litter robots and pet appliances: declared cleaning, waste and dispensing observations or controls.
Water sensors and sprinklers: declared water detection, watering state and controls.
Calendars and reminders: declared list, create, complete, reschedule and delete operations (iCloud Calendar and Reminders). Connected reminders are distinct from assistant-created scheduled tasks.
Read the relevant bundled skill reference or portos://guides/index for unfamiliar workflows. File/reminder deletion and PIN changes modify account data. Inspect partial or uncertain writes before another action. result_timeout means unknown outcome: read state before considering a retry. MESSAGE_UNSUPPORTED or MESSAGE_AMBIGUOUS means nothing was sent; correct the message from discovery. An unreachable device rejected the command. Never automatically retry a state-changing command or claim success from conflicting observations.
Use endpoint_manage/group_manage to change names, types, membership or merges.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Full Port OS endpoint ID (…/endpoints/…) from endpoint_query or group ID (…/endpoint-groups/…) from group_query. | |
| message | Yes | Full message ID copied from the target's messages: <capability-interface-namespace>/messages/<message-name>, with an @<version> suffix only when the listed ID has one. | |
| payload | Yes | JSON object matching the message payload schema. Use {} for messages without fields. | |
| routeId | No | Optional provider route ID copied from the target routes. Reuse it for pause, resume and volume after playing through that provider. It must belong to id and advertise the requested message. Without it, the route declaring the most interfaces is used, then the highest route ID. | |
| waitForResult | No | Wait for one correlated, schema-validated result for commands that retrieve results, such as camera snapshots, media search or library pages, when outboundMessages are declared. Playback and volume commands do not return correlated results. For power and other response-less controls omit it, then read fresh state with endpoint_query. | |
| correlationToken | No | Optional caller-provided correlation token. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructive=true and openWorld=true, and the description earns that bar by disclosing the crucial behavioral trait that 'accepted' only means dispatch succeeded, not that the physical outcome occurred. It also decodes error semantics (result_timeout = unknown outcome, MESSAGE_UNSUPPORTED/AMBIGUOUS = nothing sent, unreachable = rejected) and forbids automatic retries of state-changing commands — none of which is in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded and organized with numbered steps, but it is extremely long and carries material that duplicates the schema (waitForResult is re-explained three times) and that arguably belongs in a bundled skill — it even advertises itself as being for 'tools-only clients without resources/read.' The device-class catalogue is useful for routing but bloats the definition considerably.
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 six-parameter, open-world, destructive dispatch tool, the description covers discovery, payload construction, route selection, result semantics, failure modes and post-write verification. An output schema exists, so return values needn't be spelled out, yet the status vocabulary (accepted/responded, queue-contents fields) is explained where it affects agent 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 coverage is 100%, so the baseline is 3, but the description adds real routing semantics beyond the schema: which command classes return correlated results and therefore need waitForResult (search, library pages, get-snapshot) versus which must omit it (playback, volume, power), plus the rule to verify with fresh endpoint_query instead. It also clarifies that payload must match the declared message and that {} is used for fieldless commands.
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?
Opens with a specific verb-plus-resource statement ('Control connected devices and services, retrieve results, capture camera snapshots') and immediately positions the tool against its siblings by directing discovery to endpoint_query/group_query and metadata changes to endpoint_manage/group_manage. An agent can tell what this tool does and what it does not do without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states the precondition (discover the endpoint/group first and copy the full id, message and routeId), the when-not (do not use this to rename or change membership — use endpoint_manage/group_manage), and names alternatives throughout. It even supplies end-to-end recipes for the two hardest workflows (live music queue, lighting scenes) with per-step tool routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
endpoint_manageADestructiveInspect
Manage the names, types and registry entries of your devices and connected services.
Choose one operation: RENAME, SET_TYPE, SET_ENABLEMENT, MERGE_INTO, or DELETE. Use endpoint_query first and copy the full endpoint ID. Rename and type changes are durable across provider rediscovery. Disabled endpoints stay available for explicit metadata reads, but cannot receive messages; rediscovery preserves the disabled state. DELETE removes the registry entry, though a provider may rediscover it later. MERGE_INTO retains the source endpoint as disabled and moves supported references to the target; it does not create a source-ID alias, a simulator endpoint can merge only into a target without a simulator route (two simulator endpoints return 409 CONFLICT; disable or delete the duplicate instead), and the target's enablement remains in effect. Before MERGE_INTO or DELETE, identify the actual endpoint and explain the effect to the user; never assume two endpoints are duplicates because their names match. This tool changes registry metadata only and never performs physical control.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | New endpoint name; only for RENAME. | |
| type | No | New ontological endpoint type; only for SET_TYPE. | |
| mergeInto | No | Full target endpoint ID; only for MERGE_INTO. | |
| operation | Yes | ||
| enablement | No | New endpoint enablement; only for SET_ENABLEMENT. | |
| endpointId | Yes | Full endpoint ID from endpoint_query. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (destructive=true, readOnly=false, idempotent=false), yet the description still adds substantial context they cannot: rename/type changes survive provider rediscovery, disabled endpoints stay metadata-readable but cannot receive messages, DELETE may be undone by rediscovery, and MERGE_INTO leaves the source disabled without creating an ID alias.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the operation menu are front-loaded, and nearly every sentence carries non-obvious behavior. It is a dense ~190-word block that would read faster as a per-operation list, and a couple of clauses (rediscovery mentioned twice) could be consolidated.
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 destructive, multi-operation, open-world-adjacent tool this covers preconditions, per-operation consequences, conflict behavior, and the user-confirmation step; return values are handled by the existing output schema, so nothing an agent needs to call it safely is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 83% and each parameter already carries a description, so the description only needs to add constraints. It does add the critical one ('full endpoint ID from endpoint_query') and the conditional applicability of mergeInto, name, type and enablement via the operation list, though it never maps operation values to their required parameters explicitly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('manage the names, types and registry entries of your devices and connected services') and enumerates the exact operation set. It also explicitly distinguishes itself from the sibling 'control' by declaring it never performs physical control, and points to endpoint_query for the ID.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit sequencing ('Use endpoint_query first and copy the full endpoint ID'), a decision rule for the common ambiguity (two simulator endpoints return 409; 'disable or delete the duplicate instead'), and a pre-flight requirement for the irreversible ops ('identify the actual endpoint and explain the effect to the user; never assume two endpoints are duplicates because their names match').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
endpoint_queryARead-onlyIdempotentInspect
Find connected devices and services, discover their controls, and read their state.
Start with a focused name, room or category query; follow paginationContext.nextToken. Results include full IDs, device types, provider routes, capabilities and accepted message IDs. An endpoint is a device or connected service, including a filesystem or media library. Copy IDs verbatim into control. For a known device, use endpointId; inspect its declared capabilities, commands and outbound message IDs. Use group_query for rooms and endpoint_manage for requested inventory cleanup.
To read state, set expand to the declared capabilities you need, for example ["power","connectivity"] or ["battery"]. expand adds observations; it does not discover more devices or send controls. Add forceDeviceAttributeQuery=true to refresh selected attributes from the provider; otherwise readings may come from cache. Only FRESH observations establish the current state. A FRESH value is the current state; a STALE value is the last known state, reported with its sampledAt and never as live or unknown (a forced read may refresh it). Errored, missing or invalid values are unknown, not OFF or a dead battery, and a STALE value alone must not support a safety claim such as locked or off. An attribute with error.code PROVIDER_NO_STATE (forced reads only) means the provider answered but has no value for it: state is unknown and retrying will not help until the provider reports one. FRESH UNREACHABLE means offline even if a power value is present; STALE UNREACHABLE is the last known connectivity. An ID-only lookup retrieves metadata without requesting fresh state.
Supported discovery includes:
Lights, switches and plugs: select by name and power/brightness capabilities as well as type; a light may be typed SWITCH or PLUG.
Thermostats and sensors: read temperature-sensor for ambient temperature; a setpoint is not room temperature. Clarify indoor versus outdoor temperature when ambiguous.
Cameras, locks, appliances, vacuums, pet appliances, sprinklers and water sensors: inspect declared controls and observations.
Phones, Apple Watch and trackers: read battery, charging, connectivity or location capabilities; use control for a declared ring command.
Speakers, TVs and media services: discover playback, volume, search and playlist commands. Alexa devices may be VOICE_ASSISTANT.
Filesystems, photos, calendars and reminders: choose a concrete route-backed service, rather than a generic plugin catalog or an old unrouted record.
Read portos://guides/index or the bundled Port OS skill references for device workflows. Keep the account with every ID; check relevant authorized accounts before reporting a device missing. Names alone do not prove identity. Preserve routeId for the chosen provider and establish identity before merging records. By default lists contain enabled devices; enablement=DISABLED selects disabled devices and enablement=* includes both. Exact endpointId lookup can read metadata regardless of enablement. With group:read, controllableGroups lists rooms a device can act on. Simulator state does not establish household device state.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Optional field-first filter. Omit it to load full context; filter only when the account is large. Each key is a field or a combinator, and all keys of one object must match: {"name": {"like": "living"}, "type": {"in": ["LIGHT", "SWITCH"]}}. Combinators: {"and": [query, ...]}, {"or": [query, ...]}, {"not": query}. Text operators: eq (exact), in (any of a list), like (case-insensitive substring), lt and gt (lexical order). List operators: has (contains the exact value), like (some value contains the substring, case-insensitive). Fields: id (text) full endpoint ID; name (text) endpoint name; type (text) effective endpoint type, including customer overrides, such as LIGHT, SWITCH, PLUG or ROBOT_VACUUM; manufacturer (text) manufacturer name; model (text) model name; ownerId (text, eq only at the top level) principal whose endpoints to list; defaults to the caller; interfaces (list) full capability interface namespaces; messages (list) full message IDs the endpoint accepts; controllableGroups (list) IDs of groups the endpoint can act on, such as rooms a vacuum can clean (needs group:read). | |
| expand | No | Select observations to add to each device result, for example ["power", "connectivity"] or ["battery"]. Use capability names or full namespaces declared by the device. This reads attributes; it does not send commands or broaden the device search. Short names use port1/systems/zero/capability-interfaces. No state reads by default. | |
| nextToken | No | Opaque cursor returned by a previous endpoint_query call. | |
| enablement | No | Filter by ENABLED (default), DISABLED, or * for both. This filter is preserved by pagination. | ENABLED |
| endpointId | No | Return one endpoint by its full Port OS identifier. Cannot be combined with other filters or pagination. Results advertise its declared command and outbound message IDs. | |
| maxResults | No | Maximum number of results (default 10, maximum 100). | |
| forceDeviceAttributeQuery | No | Read selected attributes from devices instead of cache. Requires nonempty expand. Failed reads remain unavailable. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, yet the description goes far beyond them: cache versus forced provider reads, FRESH/STALE/UNREACHABLE semantics, PROVIDER_NO_STATE, and the rule that STALE values cannot support safety claims. That is meaningful behavioral context the annotations cannot express, and it materially changes how an agent interprets results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and usage, but it then expands into a long reference essay with a bulleted taxonomy of device categories and several maxims ('Names alone do not prove identity', 'Simulator state does not establish household device state') that read like documentation rather than selection guidance. Much of it earns its place given the complexity, but the volume and overlap with schema text cost it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be spelled out, and the description covers the remaining decision-relevant gaps: account scoping for IDs, routeId preservation, pagination, enablement defaults, and state-freshness interpretation. Nothing an agent needs in order to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description earns extra credit by disambiguating expand ('adds observations; it does not discover more devices or send controls') and explaining cache behavior behind forceDeviceAttributeQuery. It still restates some schema-level facts (ID-only lookups, default enablement), and the 'paginationContext.nextToken' phrasing drifts from the actual nextToken parameter, so it is strong rather than flawless.
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?
Opens with a specific verb-and-resource cluster (find devices/services, discover controls, read state) and explicitly defines what an endpoint is, including non-obvious cases like a filesystem or media library. It names the sibling tools it is not (group_query for rooms, endpoint_manage for inventory, control for commands), so an agent can route correctly without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit entry guidance ('Start with a focused name, room or category query'), the known-device path ('For a known device, use endpointId'), pagination behavior, and named alternatives with the conditions that select them. It also states the default scope (enabled devices) and how to widen it, which is exactly the kind of when-to-use detail that prevents wrong calls.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
endpoint_showARead-onlyIdempotentInspect
Show Port OS devices with their supported controls.
To show a device, always call this tool: the widget it opens is the device's UI, so never render a second card, map or controls for it; answer in a sentence or two.
Uses the same selection, expansion and pagination arguments as endpoint_query. A single matching device opens its full view with now playing, transport, volume and other controls; several matches open only a list of names to choose from, so pass one full endpoint ID (or a query matching one device) to control a device. Showing a device does not start live video or send a control command.
Pass primary to choose which card leads, one of the device's card ids (every result lists them as cardIds; an unknown id is rejected with the available ones). The device's usual card and every other card stay behind the details toggle. Examples: "what's the battery on the vacuum" -> primary battery; "turn the thermostat fan on" -> primary fan; "how open are the blinds" -> primary closure; "show me the camera on the roborock" -> primary camera. "where is my phone" or "show its location" -> primary location; "show the roborock's map" or "pick a room to clean" -> primary house-map. Every result already includes the cached readings of the cards it lists (cardIds), so you can answer without a second call; pass expand to choose different capabilities. primary refreshes that card's readings from the device, so the answer is current. Always state the value in words: a FRESH reading is current; a STALE reading is the last known value, so say it is last known and give its age.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Optional field-first filter. Omit it to load full context; filter only when the account is large. Each key is a field or a combinator, and all keys of one object must match: {"name": {"like": "living"}, "type": {"in": ["LIGHT", "SWITCH"]}}. Combinators: {"and": [query, ...]}, {"or": [query, ...]}, {"not": query}. Text operators: eq (exact), in (any of a list), like (case-insensitive substring), lt and gt (lexical order). List operators: has (contains the exact value), like (some value contains the substring, case-insensitive). Fields: id (text) full endpoint ID; name (text) endpoint name; type (text) effective endpoint type, including customer overrides, such as LIGHT, SWITCH, PLUG or ROBOT_VACUUM; manufacturer (text) manufacturer name; model (text) model name; ownerId (text, eq only at the top level) principal whose endpoints to list; defaults to the caller; interfaces (list) full capability interface namespaces; messages (list) full message IDs the endpoint accepts; controllableGroups (list) IDs of groups the endpoint can act on, such as rooms a vacuum can clean (needs group:read). | |
| expand | No | Select observations to add to each device result, for example ["power", "connectivity"] or ["battery"]. Use capability names or full namespaces declared by the device. This reads attributes; it does not send commands or broaden the device search. Short names use port1/systems/zero/capability-interfaces. endpoint_show already includes cached readings for the cards it lists; expand replaces that selection. | |
| primary | No | The card to lead with, one of the device's card ids (shown as cardIds in the result), for example battery, fan, closure, thermostat, camera or remote; house-map for a vacuum's map or room picking (never draw your own map). Needs endpointId. Every other card stays behind the details toggle. | |
| nextToken | No | Opaque cursor returned by a previous endpoint_query call. | |
| enablement | No | Filter by ENABLED (default), DISABLED, or * for both. This filter is preserved by pagination. | ENABLED |
| endpointId | No | Return one endpoint by its full Port OS identifier. Cannot be combined with other filters or pagination. Results advertise its declared command and outbound message IDs. | |
| maxResults | No | Maximum number of results (default 10, maximum 100). | |
| forceDeviceAttributeQuery | No | Read selected attributes from devices instead of cache. Requires nonempty expand. Failed reads remain unavailable. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only/idempotent/no-destruction, yet the description adds substantive behavior: single match vs multi-match results differ, results carry cached card readings so no second call is needed, primary refreshes that card's readings, unknown card ids are rejected with the valid list, and FRESH vs STALE readings must be reported with age. These are exactly the traits an agent cannot infer from the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the 'never render a second card' rule are front-loaded, then argument guidance, then fresh/stale reporting. Every paragraph carries load, but sentences are long and multi-clause, and the primary examples block is dense enough to slow scanning.
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 an 8-parameter, nested-schema, output-schema-bearing read tool, the description covers everything that matters operationally: multi-match degradation, cached vs refreshed readings, card selection, and the UI/rendering constraint. Return values are already in the output schema, so nothing is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3; the description earns above that by adding decision-level meaning for primary (which card ids exist, what each is for, requires endpointId, unknown ids rejected), expand (replaces the default cached selection, short names use capability-interfaces), and the single-device requirement for query. nextToken, enablement and maxResults are left entirely to 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?
Opens with a specific verb+resource: 'Show Port OS devices with their supported controls', and clarifies it opens the device's canonical widget UI. It distinguishes itself from endpoint_query (shares the same selection/expansion/pagination arguments) and from control ('Showing a device does not start live video or send a control command'), though the query-vs-show split is implied rather than stated outright.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit operating instructions: always call this tool to show a device, never render a second card or map, pass one full endpoint ID (or a query matching one device) to get controls, otherwise you get only a name list. It maps common user intents to primary card ids via worked examples. It stops short of saying when endpoint_query is the better choice instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
group_manageADestructiveIdempotentInspect
Organize rooms and device groups: create, rename, change members, enable, disable, merge or delete them.
Create, delete, add/remove members, MOVE_MEMBER and rename default to providerSync BEST_EFFORT: send supported native group changes first, verify provider readback, then save Port OS intent. A provider failure falls back locally and is PARTIALLY_APPLIED. PORTOS_ONLY sends nothing; FAIL_ON_PROVIDER_ERROR fails customer intent if a required provider change fails, while retaining received provider facts. Native effects cannot be rolled back. Undeclared support is NOT_SUPPORTED with reason NOT_DECLARED and does not by itself make the result partial. OUTSIDE_PRINCIPAL means native changes are not attempted through another principal's account; the authorized Port OS change can still apply.
Read group IDs and etags with group_query first. Every reference to one group in a batch uses the same starting etag. MOVE_MEMBER takes memberEndpointId plus source and target group references with both etags; a lone add cannot implicitly displace another exclusive native group. Contradictory edits return 400; list position is not a procedural ordering mechanism. MERGE_INTO and aggregate/route enablement accept only PORTOS_ONLY. Rename does not automatically merge groups.
DELETE_GROUP can delete provider groups. Routes not confirmed retired are disabled and orphaned, so rediscovery cannot resurrect the deleted group. SET_ENABLEMENT can hide an aggregate without deleting it; SET_GROUP_ROUTE_ENABLEMENT changes one provider route's contribution locally. Obtain explicit user authorization for the exact MERGE_INTO or DELETE_GROUP targets and effects before calling.
Hue supports native group creation, deletion, membership and rename. Roborock supports room rename only; membership changes do not reshape robot maps. Sonos native group mutations are not implemented. Declared support is authoritative. Use control for device actions such as power, playback or cleaning.
Customer intent commits as one batch. Set validateOnly=true to report PLANNED or NOT_SUPPORTED dispatches without sending or writing. idempotencyKey is required otherwise: use one unique key per intended change, and reuse it only for the identical request after a lost or uncertain response. A stale etag returns PRECONDITION_FAILED; re-read and resolve the change before a new request.
Inspect status COMMITTED, PARTIALLY_SUCCEEDED or FAILED, each result's APPLIED, PARTIALLY_APPLIED or NOT_APPLIED status, and providerDispatches. Failed batches retain provider facts and report operations whose messages were sent as NOT_APPLIED without group etags; errors identify failing operations. Do not report a partial save as fully synchronized or automatically repeat native writes.
| Name | Required | Description | Default |
|---|---|---|---|
| operations | Yes | Compatible intended changes in one customer batch. Reuse each group's starting etag across its references; contradictory edits cannot be resolved by list order. | |
| validateOnly | No | Validate and authorize the batch and report planned or unsupported provider dispatches without sending messages or writing. | |
| idempotencyKey | No | Unique key for this intended change, at most 255 characters. Required unless validateOnly is true. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructive=true and openWorld=true, but the description goes far beyond them: it discloses that native effects cannot be rolled back, that BEST_EFFORT falls back locally as PARTIALLY_APPLIED, that OUTSIDE_PRINCIPAL suppresses native attempts, and per-provider support (Hue create/delete/membership/rename, Roborock rename only, Sonos unimplemented). It also warns that deleting routes leaves them disabled and orphaned so rediscovery cannot resurrect them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and alternatives are front-loaded, but the body is a dense wall of internal status vocabulary (NOT_SUPPORTED, NOT_DECLARED, OUTSIDE_PRINCIPAL, PARTIALLY_APPLIED) and several sentences restate what the enum descriptions in the schema already say (providerSync, enablement). The information is valuable but the phrasing is spec-leak prose rather than scannable guidance, so not every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-variant, destructive, provider-syncing batch mutation this covers the essentials: authorization requirements, idempotency, etag/precondition handling, per-provider capability matrix, partial-failure semantics, and interpretation of result statuses. The output schema exists, so the added status guidance ('Do not report a partial save as fully synchronized') is interpretation help rather than duplication.
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 operations, etags, providerSync and idempotencyKey; baseline would be 3. The description adds cross-cutting meaning the schema does not: one starting etag shared by every reference to a group in a batch, requestId correlation over position, idempotencyKey reuse only for the identical request, and that MERGE_INTO/SET_ENABLEMENT/route enablement accept only PORTOS_ONLY.
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?
Opens with a concrete verb+resource+scope: 'Organize rooms and device groups: create, rename, change members, enable, disable, merge or delete them.' It explicitly separates itself from siblings by naming group_query for reads and control for device actions, so an agent can route without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States when to use it (group organization), when to use alternatives ('Use control for device actions', 'Read group IDs and etags with group_query first'), and hard prerequisites ('Obtain explicit user authorization for the exact MERGE_INTO or DELETE_GROUP targets'). It also gives the dry-run path via validateOnly and the recovery path for stale etags/idempotency reuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
group_queryARead-onlyIdempotentInspect
Find rooms, floors, zones, homes and device groups, with their members and supported controls.
Returns canonical IDs, names, etags, spatial roles, parent paths, children, member devices, controllers and providers. Call it without arguments first to load full context and follow every paginationContext.nextToken; filter with query only when the account is large.
Controllers are the endpoints that can act on the group, with the message IDs that accept it: to clean a room, call control on the controller endpoint with one of those message IDs and payload {"groupIds": []}.
Messages are message IDs the group itself accepts: send one with control, using the group ID as id. Port OS uses a native group only when it respects effective membership; otherwise it dispatches equivalent actions to individual members or returns unsupported. Disabled provider routes are never control candidates. Room cleaning is not a group message; use the controller as above. If two groups match a spoken room name, ask the user which one, naming each group's parentPath.
Pass id to read one group; a merged group ID resolves to the surviving group and reports redirectedFrom.
To show a room map or let someone pick rooms, call endpoint_show on the vacuum (controller) with primary house-map; never draw a map yourself from spatial geometry.
Expand accepts capability names as in endpoint_query (for example ["speaker","media-player"]); forceDeviceAttributeQuery refreshes those observations. Read route attribute status before trusting a value: omitted or failed fresh values are unavailable.
Each route's membershipComplete is provider-declared: false means incomplete or unreported, and absent means unknown. members lists resolved endpoints, so an empty list does not prove a provider group has no members.
Disabled groups are hidden unless enablement is DISABLED or *; they cannot be targeted, and group_manage SET_ENABLEMENT enables them again. Copy group IDs and etags verbatim into control and group_manage.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Return one group by its full group ID. Cannot be combined with query, maxResults or nextToken. | |
| query | No | Optional field-first filter. Omit it to load full context; filter only when the account is large. Each key is a field or a combinator, and all keys of one object must match: {"role": {"eq": "ROOM"}, "name": {"like": "kitchen"}}. Combinators: {"and": [query, ...]}, {"or": [query, ...]}, {"not": query}. Text operators: eq (exact), in (any of a list), like (case-insensitive substring), lt and gt (lexical order). List operators: has (contains the exact value), like (some value contains the substring, case-insensitive). Fields: id (text) full group ID; name (text) group name; role (text) spatial role a provider declares: HOME, FLOOR, ROOM or ZONE; parentGroupId (text) ID of the containing group; ownerId (text, eq only at the top level) principal whose groups to list; defaults to the caller; children (list) IDs of contained groups; members (list) member endpoint IDs; controllers (list) IDs of endpoints that can act on the group, such as a robot that cleans the room; messages (list) full message IDs the group itself accepts; providers (list) names of the plugins that report the group. | |
| expand | No | Select declared capabilities whose route observations to return, for example ["speaker", "media-player"]. Requires id. This adds state readings to the selected group; it does not expand group membership or send commands. Expanding spatial returns raw room geometry for reading only. To show a map or let someone pick rooms, call endpoint_show on the vacuum with primary house-map; never draw one yourself. | |
| nextToken | No | Opaque cursor returned by a previous group_query call with the same query and maxResults. | |
| enablement | No | Filter by ENABLED (default), DISABLED, or * for both. This filter is preserved by pagination; id reads ignore it. | ENABLED |
| maxResults | No | Maximum number of groups (default 25, maximum 100). | |
| forceDeviceAttributeQuery | No | Requires id and nonempty expand; refresh provider state before returning route observations. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly, idempotent, non-destructive behavior, and the description adds substantial operational context: pagination behavior, merged-ID redirects, controller versus message semantics, disabled-group visibility, and membershipComplete caveats. No behavior contradicts 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 purpose is front-loaded and the description is organized by operational concern. It is dense and lengthy, but most sentences carry useful guidance for a complex query tool, with only minor repetition of schema details.
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, rich schema, annotations, and output schema, the description covers the important call patterns, caveats, and sibling handoffs. An agent has enough information to invoke group_query correctly without opening other definitions first.
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%, but the description still adds meaningful semantics beyond the schema, including that id reads one group, merged IDs report redirectedFrom, expand requires id, forceDeviceAttributeQuery refreshes observations, and enablement survives pagination. These details help an agent choose parameters correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Starts with a specific verb and resource list: find rooms, floors, zones, homes, and device groups, plus their members and controls. It distinguishes the tool from group_manage and control by explaining query versus management/action semantics.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says to call without arguments first to load full context, follow pagination tokens, and filter with query only when the account is large. It also routes related needs to siblings, such as endpoint_show for maps and group_manage SET_ENABLEMENT for disabled groups.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
subscription_cancelADestructiveIdempotentInspect
Stop watching by cancelling one Port OS event subscription using its exact ID from subscription_list or subscription_inspect.
Cancellation is idempotent. Select the intended subscription by name, source endpoint and catalog event; names are not cancellation keys. A stopped monitor requires a new subscription to watch again.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Exact subscription ID returned by subscription_list. Never use a display name or endpoint ID. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, and the description restates idempotency while adding the consequential detail that a stopped monitor needs a new subscription to resume — real context beyond the annotation flags. It still says nothing about required permissions or what the cancellation response contains.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short, front-loaded sentences with no filler, lead sentence states the action and the ID sourcing rule. The middle sentence ('Select the intended subscription by name, source endpoint and catalog event; names are not cancellation keys') is slightly convoluted and could momentarily read as endorsing selection by name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained, and the annotations already carry the destructive/idempotent profile. The description covers the ID sourcing and the irreversibility consequence, leaving only auth/permission expectations unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the property description already states 'Exact subscription ID returned by subscription_list. Never use a display name or endpoint ID.' The prose largely echoes that, so it adds little semantic value beyond the schema; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('cancelling one Port OS event subscription') and scopes it to a single subscription by exact ID. It also implicitly distinguishes itself from subscription_list and subscription_inspect by naming them as the ID sources rather than as the operation itself.
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 directs the agent to obtain the ID from subscription_list or subscription_inspect and warns that names are not cancellation keys, which is the main misuse path for a cancel tool. It does not, however, discuss when cancellation is inappropriate or what alternatives exist for temporarily pausing a monitor.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
subscription_inspectARead-onlyIdempotentInspect
Inspect one Port OS event subscription by its exact ID returned by subscription_list.
Returns its safe query, source endpoint, catalog name and lifecycle status. A retained active subscription establishes registration; it does not prove that any client has received or acted on a camera event.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Exact subscription ID returned by subscription_list. Never use a display name or endpoint ID. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), and the description adds real semantics on top: the returned query is described as 'safe' (implying redaction), and it explicitly warns that a retained active subscription only proves registration, not that a client received or acted on a camera event. That caveat prevents a concrete misreading of the result and is not derivable from any structured field.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the action and resource, followed by the return contents and the one critical caveat. Nothing is redundant with the name or title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A one-parameter read tool with full schema coverage, explicit annotations and an output schema, so return values need not be spelled out further. The description nonetheless names what comes back and closes the main interpretive risk, leaving nothing an agent needs missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single id parameter is documented in detail, including the 'never use a display name or endpoint ID' constraint. The description's 'exact ID returned by subscription_list' largely restates the schema, so it adds little beyond 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?
States a specific verb (Inspect) and a precisely scoped resource (one Port OS event subscription, by exact ID), and names the sibling that produces that ID. An agent can separate it from subscription_list, subscription_cancel and subscription_label_edit without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description tells the agent where the required ID comes from (subscription_list) and the schema forbids substituting a display name or endpoint ID, which rules out the main misuse. It does not contrast this tool with read-adjacent siblings such as endpoint_show, but the lookup path is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
subscription_label_editAIdempotentInspect
Change only the display name of one Port OS event subscription by exact ID.
Use a PLAIN name-value object. The event, endpoint, filter and destination are immutable; to change what is watched, establish a replacement monitor and cancel the old ID.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Exact subscription ID returned by subscription_list. Never use a display name or endpoint ID. | |
| name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true, destructiveHint=false and openWorldHint=false. The description adds substantive context beyond that: the event, endpoint, filter, and destination are immutable, so the mutation surface is confined to a label — useful reassurance that matches the non-destructive annotation.
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, no filler, with the scope constraint front-loaded and the escape hatch to the alternative workflow second. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With rich annotations, a full input schema, and an output schema, the description covers the remaining gaps: immutability of sibling fields and the replacement workflow. Only minor details (e.g., error behavior on unknown ID) are absent, which is acceptable given the structured fields available.
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 only 50%, but the description compensates by telling the agent to use a PLAIN name-value object, which explains the nested {type: 'PLAIN', value: ...} shape that the schema alone presents without rationale. The id parameter's exactness requirement is already covered in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (change display name), a specific resource (one Port OS event subscription), and a precise selector (by exact ID). It is clearly distinguishable from subscription_cancel, subscription_list, and subscription_inspect, which operate on lifecycle or listing rather than the label.
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 scopes the tool to display-name changes only, then names the excluded case (changing what is watched) and prescribes the alternative workflow: create a replacement monitor and cancel the old ID. An agent has no ambiguity about routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
subscription_listARead-onlyIdempotentInspect
Enumerate the user's Port OS event subscriptions, including their exact IDs, names, source endpoint, catalog event and status.
For requests to stop watching a camera, list subscriptions and follow every nextCursor, select the intended monitor, then use subscription_cancel with its exact ID. Creating a monitor uses the host's events/subscribe capability after discovering supported camera events; these tools never accept callback URLs or signing keys.
| Name | Required | Description | Default |
|---|---|---|---|
| cursor | No | Opaque nextCursor from the preceding subscription_list page. Omit for the first page. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare safety (readOnlyHint, idempotentHint, destructiveHint=false, openWorldHint=false), so the bar is low; the description adds real behavior by requiring the agent to exhaust every nextCursor for a complete enumeration. It also discloses a hard constraint, that these tools never accept callback URLs or signing keys, which is not in any structured field.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded first sentence states what is returned; the second paragraph carries use-case and constraint information. Both paragraphs carry weight, though the mention of the monitor-creation path via events/subscribe is only tangentially related to a list tool.
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 rich annotations, an output schema that covers the return shape, and a fully documented single parameter, the description fills the remaining job of telling the agent how to page and what to do next. Only the missing distinction from subscription_inspect keeps it from a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single cursor parameter is documented as an opaque nextCursor, so the baseline is 3. The description earns the extra point by making the pagination contract operational (follow every nextCursor) rather than merely describing the field.
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?
A specific verb (enumerate) plus resource (Port OS event subscriptions), and it names the payload fields returned: exact IDs, names, source endpoint, catalog event, status. That is enough for an agent to distinguish this list operation from subscription_inspect or subscription_cancel without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete trigger and full follow-on procedure: stopping a camera monitor means listing, following every nextCursor, selecting the intended monitor, then calling subscription_cancel with its exact ID. It also pre-empts the creation path (host's events/subscribe capability). It does not explicitly say when to prefer subscription_inspect over this list, so there is a small gap against 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.
10 tool updates
- First observed
control - First observed
endpoint_manage - First observed
endpoint_query - First observed
endpoint_show - First observed
group_manage - First observed
group_query - First observed
subscription_cancel - First observed
subscription_inspect - First observed
subscription_label_edit - First observed
subscription_list
Publisher details
- Operator
- Mirumiru inc. · Publisher source
- Operator website
- https://portoperatingsystem.com · Publisher source
- Vendor relationship
- First-party
- Restrictions
- none · Publisher source
Related MCP Connectors
Connect your AI to your own devices, 3D printers, factory tools and a shared agent task pool.
Home energy for AI assistants: live Power flow, Energy history, solar forecast, and device control.
- mytesla.ioOAuthio.mytesla
Control your Tesla from your AI assistant - climate, charging, access, and security.
Property management AI: work orders, vendors, appliances, and triage for Claude and ChatGPT.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to discover, read and control smart-home devices from multiple vendors through a unified capability model, and to author and trigger YAML scenes that a local deterministic engine executes without the AI in the control loop. High-risk actions such as door locks and garage doors are held in a confirmation queue for a human, and every call is written to a local audit log.Apache 2.0
- AlicenseNot gradedqualityCmaintenanceSmart Device Control 🎮 💡 Lights: Brightness, color, RGB 🌡️ Climate: Temperature, HVAC, humidity 🚪 Covers: Position and tilt 🔌 Switches: On/off 🚨 Sensors: State monitoring Intelligent Organization 🏠 Grouping with context awareness. Robust Architecture 🛠️ Error handling, state validation ...226 npm58Apache 2.0
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Home Assistant smart home devices through natural language. Control devices, manage automations, query entity states, and retrieve historical data across your home automation system.1MIT
- AlicenseNot gradedqualityCmaintenanceA local MCP server that lets AI assistants list and control home devices — lights, air conditioners, cameras, speakers, plugs and scheduled tasks — across Xiaomi (Mi Home), Tuya, Midea, eWeLink (Sonoff) and Huawei SmartHome using accounts you authorize on your own machine. It binds to localhost only and communicates with each vendor cloud, so agents can act on devices through natural language.68 npm1MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.