hubitat-mcp · diff

git:20260627.de08e11 to git:20260702.697af4f

26 added, 161 removed. Audit A to A.

---
name: hubitat-mcp
description: Smart home assistant for Hubitat Elevation hubs via MCP. Use when controlling devices, creating automation rules, managing rooms, or administering a Hubitat hub through MCP tools.
---
# Hubitat MCP Server - Smart Home Assistant
- You are connected to a Hubitat Elevation smart home hub via the MCP Rule Server. You have access to 117 distinct MCP tools for device control, automation rules, room management, hub administration, diagnostics, built-in app visibility, Rule Machine interop, native rule CRUD, library management, Easy Dashboard CRUD, HPM package state introspection, and Developer Mode self-administration. The tools are organized as **13 flat core tools** (always visible) plus **23 domain-named gateways** that proxy the remaining tools — call a gateway with no args to see full schemas, or with `tool` and `args` to execute. That makes **36 entries** on `tools/list` in gateway mode (13 flat + 23 gateways) — **37 when Developer Mode is on**, which surfaces `hub_update_package` as an additional top-level tool. Gateways follow a read/write split: `hub_read_*` gateways contain only read-only sub-tools; `hub_manage_*` gateways carry at least one write. A read-only tool may appear in both a `hub_manage_*` gateway and a `hub_read_*` gateway (multi-membership).
+ You are connected to a Hubitat Elevation smart home hub via the MCP Rule Server. The server exposes tools for device control, automation rules, room management, hub administration, diagnostics, file management, code management, dashboards, and Developer Mode self-administration. The catalog is organized as a small set of **flat core tools** (always visible) plus **domain-named gateways** that proxy the rest — call a gateway with no args to see full schemas for its sub-tools, or with `tool` and `args` to execute one. Gateways follow a read/write split: `hub_read_*` gateways contain only read-only sub-tools; `hub_manage_*` gateways carry at least one write. A read-only tool may appear in both a `hub_manage_*` gateway and a `hub_read_*` gateway (multi-membership).
+ Do not rely on this skill for per-tool inventory or counts — the live server is authoritative. Discover tools with `hub_search_tools` (natural-language BM25 search across the whole catalog, with gateway attribution) and read the deep per-topic reference with `hub_get_tool_guide` (pass a `section` key from its enum to minimize tokens).
+
## Core Principles
1. **Safety first** - Never control a device without confirming the correct match. Critical systems (locks, HVAC, garage doors) require extra care.
2. **Progressive disclosure** - Start with lightweight queries (`hub_list_devices` with `detailed=false`), then drill down as needed.
3. **Inform before acting** - Tell the user what you plan to do before executing write operations.
4. **Respect access gates** - The Read and Write masters (and any Advanced per-tool overrides) gate tools for a reason. Follow pre-flight checklists.
## Tool Naming Conventions
- All tools in this server follow these conventions. Use the conventions to predict tool shape even before consulting the full reference.
+ All tools in this server follow these conventions. Use the conventions to predict tool shape even before consulting the live catalog.
- Every tool name begins with `hub_`.
- Tool names follow verb-noun order. The allowed verbs are: `list`, `get`, `search`, `test`, `create`, `update`, `delete`, `set`, `call`, `manage`, `restore`, `import`, `export`, `clone`, plus `read`/`write` for file-manager tools and the destructive-ops exceptions `reboot` / `shutdown`. There is one locked-to-one-tool verb: `report` (used only by `hub_report_issue`).
- - Gateways are named `hub_read_<noun>` or `hub_manage_<noun>`. A `hub_read_*` gateway's every sub-tool is read-only; a `hub_manage_*` gateway contains at least one write (mixed read+write or write-only). Call a gateway with no args to see the catalog of sub-tools; call with `tool=<name>` and `args={...}` to execute one. A read-only tool may be listed in both its mixed `hub_manage_*` gateway and a `hub_read_*` gateway (multi-membership). There is a narrow exception: a flat tool with a small action enum (e.g. `hub_manage_virtual_device` with `action: "create"/"delete"`) may also use `manage_`.
+ - Gateways are named `hub_read_<noun>` or `hub_manage_<noun>`. A `hub_read_*` gateway's every sub-tool is read-only; a `hub_manage_*` gateway contains at least one write (mixed read+write or write-only). Call a gateway with no args to see the catalog of sub-tools; call with `tool=<name>` and `args={...}` to execute one. There is a narrow exception: a flat tool with a small action enum (e.g. `hub_manage_virtual_device` with `action: "create"/"delete"`) may also use `manage_`.
- Read tools never modify state. Write tools require user confirmation per the safety guide.
## Device Control
### Finding Devices
Start with `hub_list_devices(detailed=false)` to get names and IDs. Use `hub_get_device` for full details on a specific device.
### Device Authorization (CRITICAL)
- **Exact name match** (case-insensitive): Use the device directly.
- **No exact match**: Present similar options and **wait for user confirmation** before acting.
- **Tool failure**: Report the failure. Never silently use a different device as a workaround.
**Why**: The wrong device could control locks, HVAC, security systems, or garage doors.
### Sending Commands
Use `hub_call_device_command` with the device ID and command name. Common commands:
- Switches: `on`, `off`
- Dimmers: `setLevel` (params: `[level]` or `[level, duration]`)
- Color lights: `setColor` (params: `[hue, saturation, level]`), `setColorTemperature`
- Locks: `lock`, `unlock`
- Thermostats: `setHeatingSetpoint`, `setCoolingSetpoint`, `setThermostatMode`
Always check the device's `supportedCommands` (from `hub_get_device`) before sending commands.
- `hub_call_device_command` returns a `state` snapshot — a map keyed by attribute name, each entry `{value, timestamp}` — read AS OF the command. This snapshot is an immediate read taken in the same request that fires the command, so it shows the PRE-effect value (even for virtual/local devices) because the hub commits the change after the request returns; the per-attribute `timestamp` is the freshness signal (`null` if that attribute has never emitted an event). `state` is `{}` when the device exposes no readable attributes, or if the read-back fails — the command itself still succeeds in either case.
-
- To get the CONFIRMED resulting state in the same call, pass `waitFor`: `hub_call_device_command(deviceId, command="on", waitFor={attribute:"switch", expectedValue:"on", timeoutMs:5000})`. It block-polls the attribute until it converges (or times out), then the `state` snapshot reflects the converged value and a `waitFor` result block reports `{attribute, expected, converged, finalValue, elapsedMs}`. Provide exactly one of `expectedValue` or `expectedValues` (for a list: `eq` matches ANY member, `ne` matches NONE of them). `timeoutMs` is MILLISECONDS (default 5000, max 30000 on the `waitFor` path — capped lower than the standalone `hub_get_device_attribute` poll because a `waitFor` poll pins a hub thread for the full timeout). `pollIntervalMs` defaults to 250 (vs 200 on the standalone poll, since a post-command poll follows a write and wider spacing reduces read contention).
-
- Both `waitFor` and standalone `hub_get_device_attribute` poll mode also take `comparator` and `stableForMs`. `comparator` (default `eq`) selects the match: `eq`/`ne` test set membership/non-membership; `gt`/`gte`/`lt`/`lte` numerically compare the value against a single threshold in `expectedValue` (e.g. wait until `temperature` `gte` `"72"`); `between` tests an inclusive numeric range from `expectedValues` (exactly two bounds `[low, high]`). Numeric comparators never match a null/non-numeric value -- if the attribute reports a non-numeric value the whole window, the timeout flags `nonNumericAttribute` (use `eq`/`ne` for a string attribute). `stableForMs` (default 0) requires the matched condition to hold continuously for that many MILLISECONDS before converging (debounce a flapping sensor); it must be `< timeoutMs`. A bad spec (invalid comparator, wrong expected-value shape for the comparator, or `stableForMs >= timeoutMs`) is rejected up front — on the `waitFor` path, before the command fires.
-
- Standalone `hub_get_device_attribute` poll mode also awaits a condition across SEVERAL devices in one bounded call: pass `deviceIds` (a list of device IDs, mutually exclusive with `deviceId`, max 20) and the same condition (`attribute` + `comparator` + `expectedValue`/`expectedValues` + `stableForMs`) is applied to every device. `mode` (default `all`) converges when EVERY device matches; `mode: "any"` converges as soon as ONE device matches. The result is a compact per-device array (`devices: [{deviceId, device, finalValue, matched}, ...]`) plus `convergedCount` -- not full device objects; on timeout each device entry adds `neverReported`/`nonNumericAttribute` only where true. A missing device ID or an unsupported attribute is rejected up front, naming which device; `mode` with a single `deviceId` is rejected. (Multi-device is the standalone poll only -- `waitFor` stays single-device because it blocks that one command's in-flight write thread; to confirm a multi-device command sequence, fire the commands then call `hub_get_device_attribute` with `deviceIds` to await the aggregate.)
-
- When a `waitFor` poll does NOT converge, the result block carries a diagnostic flag so you can tell the cases apart: `timedOut` (the window elapsed with a wrong value), `interrupted` (the hub was reloading), `neverReported` (the attribute never emitted a value at all), `nonNumericAttribute` (a numeric comparator was used on an attribute that reported a non-numeric value the whole window, so it can never match — a `note` names the comparator/attribute and suggests `eq`/`ne`), or `error` (the poll loop threw — the command still fired). On a timeout specifically, `transitioning` is also present: `true` if the value was still changing across polls (the device is likely still settling — common on slow-reporting groups whose reports lag the physical change), `false` if it sat stable at a non-target (a real mismatch). It is best-effort — only reliable when the timeout spans one of the device's reporting jumps, so a short timeout can read `transitioning: false` on a device that is in fact still settling. On the `state` side, a non-`{}` failure surfaces a `stateError` string (error class + message) with `state` set to `{}`; an empty `state: {}` with NO `stateError` means the device legitimately has no readable attributes. When a confirmation step degrades this way (`stateError` set and/or `waitFor.error` set), the top-level response also carries `partial: true`.
-
- Alternatively, confirm separately with `hub_get_device_attribute` and an `expectedValue` to block-poll. Either way, polling BLOCKS the MCP request for up to `timeoutMs`; use sparingly, prefer event-driven flows, and avoid running it in parallel with other MCP calls.
+ The `state` snapshot returned by `hub_call_device_command` is read AS OF the command, so it shows the PRE-effect value. To confirm the resulting state in the same call, pass `waitFor` (block-polls the attribute until it converges or times out); to confirm separately — or to await a condition across several devices at once via `deviceIds` — use `hub_get_device_attribute` with an expected value. Both support comparators (`eq`/`ne`/`gt`/`gte`/`lt`/`lte`/`between`) and a `stableForMs` debounce; non-convergence comes back with a diagnostic flag telling you why. The full semantics live in the two tools' own descriptions. Polling BLOCKS the MCP request for up to `timeoutMs`; use sparingly, prefer event-driven flows, and avoid running it in parallel with other MCP calls.
### Virtual Devices
- MCP can create and delete virtual devices (switches, sensors, buttons, dimmers, etc.) via `hub_manage_virtual_device` (a core tool, always visible) using `action="create"` or `action="delete"`. These are automatically accessible without manual selection. Use `hub_list_devices` with `filter='virtual'` to see MCP-managed virtual devices. Do not use `hub_delete_device` for MCP-managed virtual devices.
-
- For `action="create"`, provide exactly ONE of (mutually exclusive; supplying both -- including a blank/whitespace `deviceType` alongside `customDriver` -- is an error):
- - `deviceType` -- one of the 15 built-in virtual driver names (see `hub_get_tool_guide` for the full list). Not-found surfaces as an isError platform error (firmware gap).
- - `customDriver={namespace, name}` -- a user-installed driver (HPM or pasted); use `hub_read_apps_code(tool="hub_list_drivers")` to find installed namespace + name values. Not-found surfaces as an input error (-32602) with a `hub_list_drivers` hint.
-
- Create response: `{success, message, tips, device: {id, name, label, deviceNetworkId, driverNamespace, driverType, typeName, capabilities, commands, attributes}}`. `typeName` is a deprecated alias for `driverType` -- prefer `driverType` in new code.
-
- Delete response: `{success, deviceId, deviceNetworkId, deviceLabel, message}`.
-
- `hub_list_devices(filter='virtual')` response: `{devices: [...], count, message}`. Per-device includes `driverNamespace` (authoritative for devices created by this tool -- the namespace is persisted at create time; for devices created before this version or by other means it falls back to a best-effort derivation that may report `"hubitat"`), `driverType`, and `typeName` (deprecated alias; prefer `driverType`). `currentStates` is a map of attribute-name to current-value.
+ MCP can create and delete virtual devices (switches, sensors, buttons, dimmers, etc.) via `hub_manage_virtual_device` (a core tool, always visible) using `action="create"` or `action="delete"`. For create, provide exactly ONE of `deviceType` (a built-in virtual driver name) or `customDriver={namespace, name}` (a user-installed driver — discover values via `hub_read_apps_code(tool="hub_list_drivers")`). See `hub_get_tool_guide(section='virtual_devices')` for the built-in type list and response shapes. Created devices are automatically accessible without manual selection. Use `hub_list_devices` with `filter='virtual'` to see MCP-managed virtual devices. Do not use `hub_delete_device` for MCP-managed virtual devices.
## Automation Rules
- Rules are the core automation primitive. Each rule has **triggers** (what starts it), **conditions** (what must be true), and **actions** (what to do).
-
- ### Creating Rules
-
- Use `hub_create_custom_rule` with a JSON structure. For the complete rule structure reference including all trigger types, condition types, action types, and JSON syntax examples, see [rule-patterns.md](rule-patterns.md).
+ Prefer the **native** rule engines for new automations: Visual Rules Builder (`hub_set_visual_rule` — one clean JSON write) and Rule Machine (`hub_set_rule` — the full authoring surface), both in the `hub_manage_rule_machine` gateway. The MCP-native custom rule engine (`hub_*_custom_rule` tools, via the `hub_manage_custom_rules` / `hub_read_rules` gateways) is **legacy**: still supported, but don't reach for it first. See `hub_get_tool_guide(section='rules')` for the custom-rule reference and `section='set_rule_reference'` / `section='visual_rule_reference'` for the native surfaces.
- ### Key Rule Patterns
+ Custom rules have **triggers** (what starts it), **conditions** (what must be true), and **actions** (what to do), created via `hub_create_custom_rule` with a JSON structure:
- **Simple device automation:**
```json
{
"name": "Motion Light",
"triggers": [{"type": "device_event", "deviceId": "123", "attribute": "motion", "value": "active"}],
"conditions": [{"type": "time_range", "startTime": "sunset", "endTime": "sunrise"}],
"actions": [
{"type": "device_command", "deviceId": "456", "command": "on"},
{"type": "delay", "seconds": 300, "delayId": "motion-off"},
{"type": "device_command", "deviceId": "456", "command": "off"}
]
}
```
- **Temperature with debouncing:**
- ```json
- {
- "name": "AC On When Hot",
- "triggers": [{"type": "device_event", "deviceId": "1", "attribute": "temperature", "operator": ">", "value": "78", "duration": 300}],
- "actions": [{"type": "device_command", "deviceId": "8", "command": "on"}]
- }
- ```
-
- **Button state machine with local variables:**
- ```json
- {
- "name": "Toggle Scenes",
- "localVariables": {"lastScene": "natural"},
- "triggers": [{"type": "button_event", "deviceId": "80", "action": "pushed"}],
- "actions": [{
- "type": "if_then_else",
- "condition": {"type": "variable", "variableName": "lastScene", "operator": "equals", "value": "natural"},
- "thenActions": [
- {"type": "activate_scene", "sceneDeviceId": "nightlight-scene"},
- {"type": "set_local_variable", "variableName": "lastScene", "value": "nightlight"}
- ],
- "elseActions": [
- {"type": "activate_scene", "sceneDeviceId": "natural-scene"},
- {"type": "set_local_variable", "variableName": "lastScene", "value": "natural"}
- ]
- }]
- }
- ```
-
- ### Rule Management
-
- Custom rules are reached through two gateways. The read-only tools (`hub_get_custom_rule`, `hub_test_custom_rule`) are surfaced in `hub_read_rules` for pure-read access and ALSO in `hub_manage_custom_rules` for workflow cohesion (multi-membership).
-
- Via `hub_read_rules` gateway (read-only):
- - `hub_get_custom_rule` - View rule configuration; omit `ruleId` to list all rules, or pass `detailed=true` for comprehensive diagnostics on a specific rule
- - `hub_test_custom_rule` - Dry-run to see what would happen without executing
-
- Via `hub_manage_custom_rules` gateway (8 tools):
- - `hub_get_custom_rule` - View rule configuration (also in `hub_read_rules`)
- - `hub_create_custom_rule` - Create a rule from a JSON structure
- - `hub_update_custom_rule` - Modify triggers, conditions, or actions; also handles enable/disable via `enabled=true/false`
- - `hub_test_custom_rule` - Dry-run to see what would happen without executing (also in `hub_read_rules`)
- - `hub_export_custom_rule` / `hub_import_custom_rule` / `hub_clone_custom_rule` - Portability operations (`hub_export_custom_rule` persists to File Manager via saveAs, so it is a write)
- - `hub_delete_custom_rule` - Removes a rule (auto-backs up to File Manager first)
-
- Mark test/throwaway rules with `testRule: true` to skip backup on deletion.
-
- ## Room Management
-
- 5 tools via `hub_manage_rooms` gateway: `hub_list_rooms`, `hub_get_room`, `hub_create_room`, `hub_delete_room`, `hub_update_room`. Room creation/deletion/renaming requires the Write master + confirm. The read-only pair (`hub_list_rooms`, `hub_get_room`) is also surfaced via the pure-read `hub_read_rooms` gateway (2 tools).
+ For the complete rule structure reference including all trigger types, condition types, action types, and JSON syntax examples, see [rule-patterns.md](rule-patterns.md). Deleting a custom rule auto-backs it up to File Manager first; mark test/throwaway rules with `testRule: true` to skip backup on deletion.
## Hub Administration
Every tool is gated by two universal masters — **Read** and **Write**, both ON by default. Read tools are blocked when the Read master is OFF ("Read tools are disabled…"); all other (write) tools are blocked when the Write master is OFF ("Write tools are disabled…"). Destructive write tools additionally require `confirm=true` + a backup within 24h. Individual tools or whole gateways can also be disabled below the masters under **Advanced: Per-tool Overrides** (deny-only) — a disabled tool drops from `tools/list`/`hub_search_tools` and returns "…is disabled in Advanced settings (Per-tool Overrides)…" if still called.
- Core hub admin tools: `hub_create_backup`, `hub_update_firmware` (install pending hub firmware; version reads fold into `hub_get_info`), `hub_report_issue`
-
- Additional hub admin tools are accessed via gateways:
-
- ### Via `hub_manage_destructive_ops` gateway (4 tools)
-
- Destructive write operations (require the Write master + confirm + backup): `hub_reboot`, `hub_shutdown`, `hub_delete_device`, `hub_call_destructive_ops` (by `target`: radio reset/wipe + firmware for zwave/zigbee/matter, network disconnect_wifi/disconnect_ethernet, or cloud disable/enable)
-
- ### Via `hub_read_apps_code` gateway (9 tools — read-only)
-
- `hub_list_apps` (`scope`: "types"/"instances" — lists installed app types or app instances), `hub_list_drivers`, `hub_get_source` (`type`: "app"/"driver"/"library"; `id`; chunked `offset`/`length`), `hub_list_backups`, `hub_get_backup`, `hub_list_device_dependents`, `hub_get_app_config`, `hub_list_app_pages`, `hub_list_hpm_packages`
-
- ### Via `hub_manage_code` gateway (8 tools — write operations)
-
- `hub_create_app`, `hub_create_driver`, `hub_update_app`, `hub_update_driver`, `hub_delete_item` (`type`: "app"/"driver"/"library"), `hub_restore_backup`, `hub_create_library`, `hub_update_library`
-
- - `hub_create_app` / `hub_create_driver` accept `source` (inline) OR `sourceFile` (File Manager filename). Token-economy tip: upload source via local CLI first, then pass filename. Includes post-install verification -- returns `success: false` if the Groovy failed to compile, even when the hub returned a redirect.
- - `hub_create_driver` supports bulk mode via an `installs` array of `{source|sourceFile}` objects. Continue-on-error; top-level `success: true` only if all items pass. Cannot combine with single-driver fields. Returns per-item `driverId`. Practical limit ~10-20 drivers/call. (`hub_create_app` is single-item only -- apps are typically one-of-a-kind installs.)
- - `hub_update_driver` supports bulk mode via an `updates` array of `{driverId, sourceFile}` objects. Continue-on-error; top-level `success: true` only if all items pass. Cannot combine with single-driver fields.
-
### Pre-flight checklist for destructive write operations (the confirm+backup tier)
1. A hub backup must exist within the last 24 hours (`hub_create_backup`)
2. Tell the user what you are about to do
3. Get explicit confirmation
4. Pass `confirm=true` to the tool
For complete safety protocols and tool-specific requirements, see [safety-guide.md](safety-guide.md).
### Dangerous Operations
- `hub_reboot` - 1-3 min downtime, automations stop
- `hub_shutdown` - Powers off completely, needs manual restart
- `hub_delete_device` - No undo, intended for ghost/orphaned devices only
- `hub_call_destructive_ops` - by `target`: radio reset/wipe + firmware (orphans paired devices), network disconnect (WiFi/Ethernet), or cloud disable/enable (stops Alexa/Google, cloud dashboards, subscriptions); no undo
- `hub_delete_item` (via `hub_manage_code`, `type`: "app"/"driver"/"library") - Auto-backs up source first
- ## Diagnostics and Monitoring
-
- `hub_list_device_events` (via `hub_read_devices` / `hub_manage_devices`) - recent events for a device; add `hoursBack` for a relative window (up to 7 days) or `since` for an absolute bookmark (events after an exact timestamp; round-trip a returned `date` for change-watching loops; response echoes `sinceMode` = `explicit`/`relative` and `since` or `hoursBack`) (omit `deviceId` for mode/HSM/hub-variable/sendLocationEvent location events)
-
- The pure-read `hub_read_diagnostics` gateway (9 tools) surfaces the read-only diagnostics for safe access: `hub_get_logs`, `hub_get_performance_stats`, `hub_get_jobs`, `hub_get_debug_logs`, `hub_get_metrics`, `hub_get_memory_history`, `hub_get_device_health`, `hub_get_radio_details`, `hub_list_captured_states`. The write-bearing diagnostics live in `hub_manage_logs`, `hub_manage_diagnostics`, and `hub_manage_radio` below (reads multi-membered into those surfaces).
-
- Via `hub_manage_logs` gateway (6 tools):
- - `hub_get_logs` - Hub log entries, most recent first; filter by level/source/pattern (regex) or multi-pattern AND/OR (`patternMode`); time-window via `since`/`until` (ISO-8601 or relative offset like `'30m'`, max 30d -- throws if exceeded; use ISO-8601 for longer ranges); or scope server-side to a single `deviceId` / `appId` (mutually exclusive). `pattern` matches the message field only (not source/name). Pathological regex like `(.*)*` may hang the matcher; prefer simple alternation.
- - `hub_get_performance_stats` - Device/app performance stats (count, % busy, total ms, state size, events). Sortable by pct/count/stateSize/totalMs/name
- - `hub_get_jobs` - Scheduled jobs, running jobs, and hub actions
- - `hub_get_debug_logs` / `hub_delete_debug_logs` - MCP-specific debug logs; pass `mode='status'` to `hub_get_debug_logs` to view logging system statistics
- - `hub_set_log_level` - Set MCP log level
-
- Via `hub_manage_diagnostics` gateway (7 tools):
- - `hub_get_metrics` - Retrieve hub metrics with CSV trend history (read-only by default; `recordSnapshot` defaults to false — also in `hub_read_diagnostics`)
- - `hub_get_memory_history` - Free OS memory and CPU load history with summary stats (Read master)
- - `hub_call_gc` - Force JVM GC; returns before/after free memory (Write master)
- - `hub_get_device_health` - Find stale/offline devices; optional ICMP ping for arbitrary IPs
- - `hub_get_radio_details` - Radio info; `radio`: "zwave" or "zigbee" (omit for both — also in `hub_manage_radio`)
- - `hub_list_captured_states` / `hub_delete_captured_state` - State snapshots (omit `stateId` on delete to clear all)
-
- Via `hub_manage_radio` gateway (6 tools):
- - `hub_get_radio_details` - Radio info; `radio`: "zwave" or "zigbee" (omit for both — also in `hub_read_diagnostics` / `hub_manage_diagnostics`)
- - `hub_set_zwave` / `hub_set_zigbee` - Configure Z-Wave / Zigbee radio settings (Write master)
- - `hub_call_zwave` - Z-Wave radio operations incl. network repair (5-30 min) via `action` (Write master)
- - `hub_call_zigbee` - Zigbee radio operations via `action` (Write master)
- - `hub_call_matter` - Matter radio operations via `action` (Write master)
-
- (Destructive radio ops — reset/wipe, firmware — are `hub_call_destructive_ops` (target=zwave|zigbee|matter) in `hub_manage_destructive_ops`, which also covers network disconnects and cloud-controller disable. For per-rule diagnostics, use `hub_get_custom_rule` with `detailed=true`.)
-
- ## File Manager
-
- Via `hub_manage_files` gateway (4 tools): `hub_list_files`, `hub_read_file`, `hub_write_file`, `hub_delete_file`. Write/delete require the Write master + confirm + a recent backup. The read-only pair (`hub_list_files`, `hub_read_file`) is also surfaced via the pure-read `hub_read_files` gateway (2 tools). Files live at `http://<HUB_IP>/local/<filename>`.
-
- ## Item Backup System
-
- Source code is automatically backed up before modify/delete operations. Use `hub_list_backups`, `hub_get_backup` (via `hub_read_apps_code` gateway) to view backups, and `hub_restore_backup` (via `hub_manage_code` gateway) to restore apps and drivers. For libraries, restore via `hub_update_library` with the backup file.
-
- ## System Tools
-
- Core tools (always visible):
- - `hub_get_info` - Comprehensive hub info (hardware, health, MCP stats) always available; PII/location data (name, IP, timezone, coordinates, zip) is included whenever the Read master is ON (the default), and omitted only when Read is explicitly OFF
- - `hub_list_modes` / `hub_manage_mode` / `hub_set_mode_manager` - Location modes (Home/Away/Night/…) + Mode Manager
- - `hub_get_hsm_status` / `hub_set_hsm` - Home Security Monitor
-
- Via `hub_manage_variables` gateway (8 tools):
- - `hub_list_variables` / `hub_get_variable` - Read hub variables (also in `hub_read_variables`)
- - `hub_set_variable` / `hub_create_variable` / `hub_delete_variable` - Mutate hub variables
- - `hub_create_connector` / `hub_delete_connector` - Variable connector devices
- - `hub_list_variable_changes` - Variable change history (also in `hub_read_variables`)
+ All of these live in write-bearing gateways (`hub_manage_destructive_ops`, `hub_manage_code`); call the gateway with no args for the full schemas.
- The read-only subset (`hub_list_variables`, `hub_get_variable`, `hub_list_variable_changes`) is also surfaced via the pure-read `hub_read_variables` gateway (3 tools).
+ ## Other Domains
- ## HPM Package Introspection
+ Each domain has its own gateway pair — call the gateway with no args for its sub-tool catalog, or find a tool with `hub_search_tools`:
- Via `hub_read_apps_code` gateway (gated by the Read master):
- - `hub_list_hpm_packages` - List all HPM-tracked packages with full component inventory. Data-quality issues (non-scalar heID, empty heID, whitespace-padded heID) emit inline `_warning` on each component **because** consumers enumerate components per-package and need the warning co-located. Pass `includeDrift=true` to also cross-reference HPM state against the hub (results nest under a `drift` key); surfaces `missing-required`, `orphan-app`, `orphan-driver` signals, with data-quality issues kept in a separate `dataQualityWarnings[]` aggregate **because** consumers need to distinguish actionable drift signals from data-quality issues without conflating them in a single `signals[]` count.
+ - **Rooms**: `hub_manage_rooms` / `hub_read_rooms`
+ - **Diagnostics & logs**: `hub_read_diagnostics` (pure-read), `hub_manage_logs`, `hub_manage_diagnostics`, `hub_manage_radio`
+ - **Files**: `hub_manage_files` / `hub_read_files` — files live at `http://<HUB_IP>/local/<filename>`
+ - **Hub variables**: `hub_manage_variables` / `hub_read_variables`
+ - **Apps, drivers, libraries, bundles, HPM state**: `hub_read_apps_code` (read), `hub_manage_code` (write). Source code is automatically backed up before modify/delete operations.
+ - **Backups**: `hub_manage_backup` — list, restore, and delete hub-database and code backups (create is the flat core tool `hub_create_backup`)
+ - **Native rules & classic apps**: `hub_manage_native_rules_and_apps`, `hub_manage_rule_machine`
+ - **Dashboards**: `hub_manage_dashboards` / `hub_read_dashboards`
+ - **Modes & HSM**: flat core tools (`hub_list_modes`, `hub_manage_mode`, `hub_set_mode_manager`, `hub_get_hsm_status`, `hub_set_hsm`), alongside `hub_get_info`, `hub_create_backup`, `hub_update_firmware`, and `hub_report_issue`
## Performance Tips
- Use `hub_list_devices(detailed=false)` first, then paginate `detailed=true` in batches of 20-30
- Use `labelFilter` (substring) and `capabilityFilter` (exact capability name) for server-side narrowing -- far cheaper than fetching all devices and filtering client-side
- `format='ids'` returns a flat integer array (cheapest shape); `fields=[...]` projects only named fields to reduce payload and skip hub reads
- `hub_list_device_events` default limit 10, max recommended 50
- `hub_get_logs` default 100, max 500 - use filters to narrow
- Make tool calls sequentially, not in parallel (hub is single-threaded)
- - For Hubitat Cloud connections, responses are limited to 128KB - use `labelFilter`, `capabilityFilter`, `fields`, or pagination to stay under the limit
+ - Every `tools/call` response is bounded by a 120KB size guard; an oversized response comes back as a `{response_too_large: true, ..., suggestion}` envelope — follow the per-tool `suggestion`, or opt into cursor pagination on list tools (`cursor: ""` for the first page, iterate `nextCursor` until absent)
+ - For Hubitat Cloud connections, use `labelFilter`, `capabilityFilter`, `fields`, or pagination to stay under the response-size limit
## On-Demand Reference
- Call `hub_get_tool_guide` to retrieve the full tool reference directly from the MCP server. This is the most authoritative and up-to-date tool documentation.
+ `hub_get_tool_guide` serves the single consolidated tool reference directly from the MCP server — always in lockstep with the server you are talking to, and the authoritative source for per-tool detail, wire formats, and worked examples. Pass a `section` key (see the tool's enum) to fetch just the topic you need. The same content is mirrored in the repository as [TOOL_GUIDE.md](https://github.com/kingpanther13/Hubitat-local-MCP-server/blob/main/TOOL_GUIDE.md) for human readers.
- For additional reference material:
+ For additional reference material bundled with this skill:
- [rule-patterns.md](rule-patterns.md) - Complete rule structure with all trigger, condition, and action types
- [safety-guide.md](safety-guide.md) - Safety protocols and pre-flight checklists
- - [tool-reference.md](tool-reference.md) - Detailed tool usage guide