From homeclaw
Controls HomeKit smart home accessories via HomeClaw MCP tools: manage lights, doors, thermostats, scenes; query status, list devices/rooms; reference characteristics and values.
npx claudepluginhub omarshahine/homeclaw --plugin homeclawThis skill uses the workspace's default tool permissions.
HomeClaw exposes Apple HomeKit accessories via MCP tools. Use the `homekit_*` tools as the interface for all HomeKit operations.
Controls HomeKit accessories, manages homes/rooms/action sets/triggers, reads/writes characteristics, and commissions Matter devices in Swift/iOS apps.
Controls Home Assistant entities like lights, switches, climate, scenes, scripts via REST API; runs automations and receives webhook events.
Creates and manages Home Assistant automations including rules, triggers, conditions, actions, scripts, scenes, and blueprints. Covers device triggers and conditional logic.
Share bugs, ideas, or general feedback.
HomeClaw exposes Apple HomeKit accessories via MCP tools. Use the homekit_* tools as the interface for all HomeKit operations.
The plugin registers 8 MCP tools.
| Tool | Description |
|---|---|
homekit_status | Check bridge connectivity, home count, accessory count |
homekit_accessories | List, get details, search, or control accessories |
homekit_rooms | List rooms and their accessories |
homekit_scenes | List, get details of, trigger, import, or delete scenes |
homekit_device_map | Get LLM-optimized device map with semantic types, aliases, and zone hierarchy |
homekit_events | Query recent HomeKit events (characteristic changes, scene triggers, control actions) |
homekit_automations | Manage automations: list, create (inline actions or scene), delete, enable/disable |
homekit_webhook | Manage webhook configuration: setup, test, reset circuit breaker, status |
homekit_config | View or update bridge configuration |
Returns a complete LLM-optimized device map organized by home/zone/room hierarchy. Each device includes:
| Field | Description |
|---|---|
semantic_type | Functional type: lighting, climate, security, door_lock, window_covering, sensor, power, media, network, other |
display_name | Room-prefixed name for disambiguation (only when duplicates exist) |
aliases | Auto-generated search terms like "kitchen light", "overhead in kitchen" |
controllable | List of writable characteristics (e.g., ["power", "brightness"]) |
state_summary | One-line state: "on 75%", "72°F heating", "locked", "off", "unreachable" |
manufacturer | Device manufacturer |
description | Natural-language summary: "Lutron lighting (power, brightness), on 75%" |
Use this tool first when you need to understand the device landscape before controlling devices. It resolves name collisions and identifies switches that actually control lights.
| Semantic Type | Maps From | Key Distinction |
|---|---|---|
lighting | lightbulbs | Devices with brightness/color control |
climate | thermostats, fans, air purifiers | |
security | doors, garage doors, cameras, doorbells, security systems | |
door_lock | locks | |
window_covering | windows, blinds, shades | |
sensor | motion, contact, temperature, humidity sensors | |
power | outlets, switches, programmable switches | In-wall switches get light aliases for search |
media | speakers, televisions |
The main workhorse tool. Supports 4 actions via the action parameter:
| Action | Required Params | Description |
|---|---|---|
list | — | List all accessories. Optional: room. Returns enriched results with semantic_type, display_name, manufacturer, zone. |
get | accessory_id | Get full detail with all characteristics |
search | query | Search by name, room, category, semantic type, manufacturer, or aliases (e.g., "kitchen light" matches switches with lightbulb services). Optional: category |
control | accessory_id, characteristic, value | Set a characteristic value |
| Action | Required Params | Description |
|---|---|---|
list | — | List all scenes with name, type, and action count |
get | scene_id | Get full scene detail including all actions (accessory, room, characteristic, target value) |
trigger | scene_id | Execute a scene by name or UUID |
| Param | Required | Description |
|---|---|---|
since | No | Duration shorthand (1h, 30m, 2d) or ISO 8601 timestamp |
type | No | Filter: characteristic_change, scene_triggered, accessory_controlled, homes_updated |
limit | No | Max events to return (default: 50) |
| Action | Required Params | Description |
|---|---|---|
list | — | List all automations with event summaries and linked scenes |
get | id | Detail view with events, action sets, and button info |
create | name, accessory_id, plus actions or scene_id | Create a button-press automation (see below) |
delete | id | Delete an automation |
enable | id | Enable a disabled automation |
disable | id | Disable an automation without deleting |
Create parameters:
| Param | Required | Description |
|---|---|---|
name | Yes | Human-readable automation name |
accessory_id | Yes | Button accessory UUID or name |
actions | One of | Inline actions array (default, no visible scene). Each entry: {accessory, property, value} |
scene_id | One of | Existing scene UUID or name to trigger |
press_type | No | 0=single (default), 1=double, 2=long press |
service_index | No | Button index for multi-button accessories (1 or 2) |
dry_run | No | Preview without creating |
Inline actions vs scenes: Use actions for simple button-to-device mappings (creates a scene named after the automation). Use scene_id to trigger an existing shared scene. Note: Apple's Home app uses a private API for hidden automation-only action sets; inline actions created via HomeClaw will appear as visible scenes.
| Action | Required Params | Description |
|---|---|---|
get | — | Show current configuration |
set | at least one setting | Set default_home_id, accessory_filter_mode, allowed_accessory_ids, or temperature_unit |
homekit_accessories with action: "search", query: "kitchen"homekit_accessories with action: "control", accessory_id: "<uuid>", characteristic: "power", value: "true"homekit_accessories with action: "control", accessory_id: "<uuid>", characteristic: "brightness", value: "50"homekit_accessories with action: "search", category: "lock"homekit_accessories with action: "control", accessory_id: "<uuid>", characteristic: "lock_target_state", value: "locked"homekit_accessories with action: "search", category: "thermostat"homekit_accessories with action: "get", accessory_id: "<uuid>"current_temperature characteristic from the responsehomekit_accessories with action: "control", accessory_id: "<uuid>", characteristic: "target_temperature", value: "72"homekit_accessories with action: "control", accessory_id: "<uuid>", characteristic: "target_heating_cooling", value: "auto"homekit_scenes with action: "list"homekit_scenes with action: "trigger", scene_id: "Movie Time"homekit_scenes with action: "get", scene_id: "Good night"homekit_accessories with action: "list", room: "Living Room"homekit_config with action: "set", default_home_id: "My Home"Creates a scene named after the automation and links it to the button press. Always use UUIDs for target accessories to avoid name collisions (many accessories share names like "Overhead" or "Blinds" across rooms).
homekit_accessories with action: "search", query: "Office Button"homekit_accessories with action: "list", room: "Sarah's Bedroom"homekit_accessories with action: "get", accessory_id: "<button-uuid>" to see how many buttons and press types (input_event max: 0=single only, 2=single+double+long)homekit_automations with action: "create", name: "Room Open", accessory_id: "<button-uuid>", actions: [{accessory: "<light-uuid>", property: "power", value: "true"}, {accessory: "<blind-uuid>", property: "target_position", value: "100"}], press_type: 0, service_index: 1Use when the automation should trigger an existing scene:
homekit_automations with action: "create", name: "Button → Movie Time", accessory_id: "<button-uuid>", scene_id: "Movie Time", press_type: 0Programmable switches (Aqara, Hue, etc.) may operate in different modes:
input_event metadata max: 0 on each service.input_event metadata max: 2.Use --service-index (CLI) or service_index (MCP) to target a specific button in fast mode. The mode itself is configured in the manufacturer's app (e.g., Aqara Home), not via HomeKit.
| Error | Cause | Resolution |
|---|---|---|
| "HomeClaw is not running" | App not launched or socket missing | Launch HomeClaw.app |
| "Connection failed" | Socket exists but app not responding | Restart the app |
0 homes / ready: false | Missing entitlement or iCloud not signed in | Check codesign entitlements and iCloud |
| "Accessory not found" | Wrong UUID or name | Use search to find the correct identifier |
| "Characteristic not writable" | Trying to set a read-only characteristic | Check the writable column in the characteristics tables below |
Values show "nil" | Accessory is unreachable or bridge hasn't synced | Check reachable field; unreachable devices return nil for all state values |
Config file: ~/.config/homeclaw/config.json
| Setting | Values | Default |
|---|---|---|
default_home_id | Home name or UUID | Primary home |
accessory_filter_mode | all, allowlist | all |
allowed_accessory_ids | Array of UUIDs | [] |
temperature_unit | fahrenheit, celsius, auto | auto (uses system locale) |
Use homekit_config to view and modify settings. When temperature_unit changes, the characteristic cache is automatically invalidated and refreshed.
Categories are mapped from Apple's HMAccessoryCategoryType constants. Homebridge devices that don't map to a known category will show the raw UUID string.
| Category | Description |
|---|---|
lightbulb | Lights, bulbs, LED strips |
switch | Generic on/off switches |
outlet | Smart plugs and outlets |
fan | Ceiling fans, standing fans |
thermostat | HVAC thermostats |
lock | Door locks |
door | Door sensors/controllers |
garage_door | Garage door openers |
window | Window actuators |
window_covering | Blinds, shades, curtains |
sensor | Temperature, humidity, motion, contact sensors |
security_system | Home security systems |
programmable_switch | Buttons, remote controls |
air_purifier | Air purifiers and filters |
camera | IP cameras |
doorbell | Video doorbells |
speaker | Speakers, cameras with audio (UniFi Protect cameras show as speaker) |
valve | Water valves, sprinkler controllers (Water Shutoff, Eve Aqua) |
bridge | HomeKit bridges (Homebridge, Hue Bridge, etc.) |
range_extender | Network range extenders |
| Characteristic | Type | Range | Writable |
|---|---|---|---|
power | boolean | true/false | Yes |
brightness | integer | 0-100 | Yes |
hue | float | 0-360 | Yes |
saturation | float | 0-100 | Yes |
color_temperature | integer | 140-500 (mireds) | Yes |
| Characteristic | Type | Range | Writable |
|---|---|---|---|
current_temperature | string | Formatted with unit, e.g. "71°F" | No |
target_temperature | string | Formatted with unit, e.g. "70°F". Set with plain number in user's unit. | Yes |
current_heating_cooling | enum | 0-3 | No |
target_heating_cooling | enum | 0-3 | Yes |
temperature_units | enum | 0=Celsius, 1=Fahrenheit | No |
current_humidity | float | 0-100 | No |
target_humidity | float | 0-100 | Yes |
Note: Temperature values are returned as formatted strings with the user's preferred unit (e.g.,
"71°F"or"22°C"). This applies to allcurrent_temperaturereadings across all accessory types (thermostats, sensors, leak detectors, etc.).
| Characteristic | Type | Range | Writable |
|---|---|---|---|
lock_current_state | enum | 0-3 | No |
lock_target_state | enum | 0-1 | Yes |
| Characteristic | Type | Range | Writable |
|---|---|---|---|
current_door_state | enum | 0-4 | No |
target_door_state | enum | 0-1 | Yes |
obstruction_detected | boolean | true/false | No |
| Characteristic | Type | Range | Writable |
|---|---|---|---|
active | boolean | true/false | Yes |
rotation_speed | float | 0-100 | Yes |
rotation_direction | enum | 0=clockwise, 1=counter | Yes |
swing_mode | enum | 0=disabled, 1=enabled | Yes |
current_fan_state | enum | 0-2 | No |
target_fan_state | enum | 0=manual, 1=auto | Yes |
| Characteristic | Type | Range | Writable |
|---|---|---|---|
current_position | integer | 0-100 | No |
target_position | integer | 0-100 | Yes |
position_state | enum | 0=decreasing, 1=increasing, 2=stopped | No |
| Characteristic | Type | Range | Writable |
|---|---|---|---|
motion_detected | boolean | true/false | No |
contact_state | enum | 0=detected, 1=not detected | No |
current_temperature | float | varies | No |
current_humidity | float | 0-100 | No |
current_light_level | float | 0.0001-100000 (lux) | No |
battery_level | integer | 0-100 | No |
low_battery | boolean | true/false | No |
charging_state | enum | 0-2 | No |
| Value | Name | Writable as |
|---|---|---|
| 0 | Off | off or 0 |
| 1 | Heat | heat or 1 |
| 2 | Cool | cool or 2 |
| 3 | Auto | auto or 3 |
| Value | Name | Writable as |
|---|---|---|
| 0 | Unsecured | unlocked, unsecured, or 0 |
| 1 | Secured | locked, secured, or 1 |
| 2 | Jammed | (read-only) |
| 3 | Unknown | (read-only) |
| Value | Name | Writable as |
|---|---|---|
| 0 | Open | open or 0 |
| 1 | Closed | closed or 1 |
| 2 | Opening | (read-only) |
| 3 | Closing | (read-only) |
| 4 | Stopped | (read-only) |
list / search ResponseEach accessory includes name, id, category, room, reachability, and a summary of current state values.
| Field | Type | Description |
|---|---|---|
name | string | Accessory display name |
id | string | UUID identifier |
category | string | Category type (see above) |
room | string | Room assignment |
reachable | boolean | Whether accessory is online |
state | object | Key-value map of current characteristic values |
get ResponseFull detail includes all services and their characteristics, each with name, current value, and writable flag.
| Field | Type | Description |
|---|---|---|
name | string | Accessory display name |
id | string | UUID identifier |
category | string | Category type |
room | string | Room assignment |
reachable | boolean | Whether accessory is online |
services | array | Services with nested characteristics array |
services[].characteristics[].name | string | Characteristic name |
services[].characteristics[].value | string | Current value |
services[].characteristics[].writable | boolean | Whether value can be set |
status Response| Field | Type | Description |
|---|---|---|
ready | boolean | Whether HomeKit is connected |
homes | integer | Number of homes |
accessories | integer | Number of accessories |
cache.cached_accessories | integer | Number of accessories with cached values |
cache.is_stale | boolean | Whether cache needs refresh |
cache.last_warmed | string? | ISO timestamp of last cache warm, or null |