agentleFS
omarshahineomarshahine/HomeClaw/skills/homeclaw/SKILL.md

homeclaw

Skill191 starsChanged 45 days agoMITView on GitHub

Control HomeKit smart home accessories via HomeClaw MCP tools. Also includes reference data for accessory categories, characteristics, and value formats. This skill should be used when the user wants to: - Turn lights on or off, set brightness, or change color temperature - Lock or unlock doors - Set thermostat temperature or HVAC mode - Run a HomeKit scene like "Good Morning" or "Movie Time" - Check which devices are on, off, or unreachable - List accessories in a room or search by name - Check HomeClaw status or configure default home - Look up characteristic names, value types, ranges, or enum mappings Example triggers: "turn on the kitchen lights", "lock all doors", "set the thermostat to 72", "run the goodnight scene", "what lights are on", "list devices in the living room", "is HomeClaw running", "what characteristics does a thermostat have", "what are the lock state values"

The file

We split this skill into the rules it gives an agent

10 rules. About 0 are common, 2 are distinctive, and 8 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 8

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this tool first: when you need to understand the device landscape before controlling devices.

    line 54
  2. Very specific:

    Search for the light: homekit_accessories with action: "search", query: "kitchen"

    line 134
  3. Very specific:

    Read the current_temperature characteristic from the response

    line 152
  4. Very specific:

    Check button services: homekit_accessories with action: "get", accessory_id: "<button-uuid>" to see how many buttons and press types …

    line 184
  5. Very specific:

    Create automation: homekit_automations with action: "create", name: "Room Open", accessory_id: "<button-uuid>",

    line 185
  6. Distinctive:

    Use when the automation should trigger an existing scene:

    line 189
  7. Very specific:

    Create automation: homekit_automations with action: "create", name: "Button → Movie Time", accessory_id: "<button-uuid>", scene_id: "Movie …

    line 192
  8. Very specific:

    Write the new definition. Actions are {"accessory", "property", "value"}.

    line 199
  9. Very specific:

    Use --service-index (CLI) or service_index (MCP) to target a specific button in fast mode.

    line 231
  10. Very specific:

    Use homekit_config to view and modify settings.

    line 286

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

HomeKit Smart Home Control

HomeClaw exposes Apple HomeKit accessories via MCP tools. Use the homekit_* tools as the interface for all HomeKit operations.

MCP Tools

The plugin registers 8 MCP tools.

ToolDescription
homekit_statusCheck bridge connectivity, home count, accessory count
homekit_accessoriesList, get details, search, or control accessories
homekit_roomsList rooms and their accessories
homekit_scenesList, get details of, trigger, import, or delete scenes
homekit_device_mapGet LLM-optimized device map with semantic types, aliases, and zone hierarchy
homekit_eventsQuery recent HomeKit events (characteristic changes, scene triggers, control actions)
homekit_automationsManage automations: list, create (inline actions or scene), delete, enable/disable
homekit_webhookManage webhook configuration: setup, test, reset circuit breaker, status
homekit_configView or update bridge configuration

homekit_device_map

Returns a complete LLM-optimized device map organized by home/zone/room hierarchy. Each device includes:

FieldDescription
semantic_typeFunctional type: lighting, climate, security, door_lock, window_covering, sensor, power, media, network, other
display_nameRoom-prefixed name for disambiguation (only when duplicates exist)
aliasesAuto-generated search terms like "kitchen light", "overhead in kitchen"
controllableList of writable characteristics (e.g., ["power", "brightness"])
state_summaryOne-line state: "on 75%", "72°F heating", "locked", "off", "unreachable"
manufacturerDevice manufacturer
descriptionNatural-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 Reference

Semantic TypeMaps FromKey Distinction
lightinglightbulbsDevices with brightness/color control
climatethermostats, fans, air purifiers
securitydoors, garage doors, cameras, doorbells, security systems
door_locklocks
window_coveringwindows, blinds, shades
sensormotion, contact, temperature, humidity sensors
poweroutlets, switches, programmable switchesIn-wall switches get light aliases for search
mediaspeakers, televisions

homekit_accessories

The main workhorse tool. Supports 4 actions via the action parameter:

ActionRequired ParamsDescription
list—List all accessories. Optional: room. Returns enriched results with semantic_type, display_name, manufacturer, zone.
getaccessory_idGet full detail with all characteristics
searchquerySearch by name, room, category, semantic type, manufacturer, or aliases (e.g., "kitchen light" matches switches with lightbulb services). Optional: category
controlaccessory_id, characteristic, valueSet a characteristic value

homekit_scenes

ActionRequired ParamsDescription
list—List all scenes with name, type, and action count
getscene_idGet full scene detail including all actions (accessory, room, characteristic, target value)
triggerscene_idExecute a scene by name or UUID

homekit_events

ParamRequiredDescription
sinceNoDuration shorthand (1h, 30m, 2d) or ISO 8601 timestamp
typeNoFilter: characteristic_change, scene_triggered, accessory_controlled, homes_updated
limitNoMax events to return (default: 50)

homekit_automations

ActionRequired ParamsDescription
list—List all automations with event summaries and linked scenes
getidDetail view with events, action sets, and button info
createname, accessory_id, plus actions or scene_idCreate a button-press automation (see below)
deleteidDelete an automation
enableidEnable a disabled automation
disableidDisable an automation without deleting

Each scene, and each entry in an automation's action_sets, carries last_execution_date (ISO-8601 UTC, or null). HomeKit leaves it null for most runs, including automations a home hub runs, so null means "none recorded", not "never ran". Use events for what actually happened.

Create parameters:

ParamRequiredDescription
nameYesHuman-readable automation name
accessory_idYesButton accessory UUID or name
actionsOne ofInline actions array (default, no visible scene). Each entry: {accessory, property, value}
scene_idOne ofExisting scene UUID or name to trigger
press_typeNo0=single (default), 1=double, 2=long press
service_indexNoButton index for multi-button accessories (1 or 2)
dry_runNoPreview 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.

homekit_config

ActionRequired ParamsDescription
get—Show current configuration
setat least one settingSet default_home_id, accessory_filter_mode, allowed_accessory_ids, or temperature_unit

Common Workflows

Turn on a light

  1. Search for the light: homekit_accessories with action: "search", query: "kitchen"
  2. Identify the accessory UUID from the results
  3. Turn it on: homekit_accessories with action: "control", accessory_id: "<uuid>", characteristic: "power", value: "true"

Set brightness

  1. Find the light UUID (via search or list)
  2. Set brightness: homekit_accessories with action: "control", accessory_id: "<uuid>", characteristic: "brightness", value: "50"

Lock all doors

  1. Find all locks: homekit_accessories with action: "search", category: "lock"
  2. For each lock: homekit_accessories with action: "control", accessory_id: "<uuid>", characteristic: "lock_target_state", value: "locked"

Check temperature

  1. Find thermostats: homekit_accessories with action: "search", category: "thermostat"
  2. Get details: homekit_accessories with action: "get", accessory_id: "<uuid>"
  3. Read the current_temperature characteristic from the response

Set thermostat

  1. Find the thermostat UUID (via search)
  2. Set temperature: homekit_accessories with action: "control", accessory_id: "<uuid>", characteristic: "target_temperature", value: "72"
  3. Set mode: homekit_accessories with action: "control", accessory_id: "<uuid>", characteristic: "target_heating_cooling", value: "auto"

Run a scene

  1. List scenes: homekit_scenes with action: "list"
  2. Trigger: homekit_scenes with action: "trigger", scene_id: "Movie Time"

Inspect what a scene does

  1. Get scene detail: homekit_scenes with action: "get", scene_id: "Good night"
  2. Response includes all actions: accessory name, room, characteristic, and target value

List accessories by room

  1. Filter by room: homekit_accessories with action: "list", room: "Living Room"

Switch active home

  1. Configure: homekit_config with action: "set", default_home_id: "My Home"

Program a button (inline actions)

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).

  1. Find the button: homekit_accessories with action: "search", query: "Office Button"
  2. Find target devices and note their UUIDs: homekit_accessories with action: "list", room: "Sarah's Bedroom"
  3. Check button services: 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)
  4. Create automation: 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: 1

Program a button (with a named scene)

Use when the automation should trigger an existing scene:

  1. Find the button and identify the scene
  2. Create automation: homekit_automations with action: "create", name: "Button → Movie Time", accessory_id: "<button-uuid>", scene_id: "Movie Time", press_type: 0

Edit a scene's actions in place (CLI)

Repoints an existing scene at different accessories/values without changing its UUID, so automations that trigger it stay wired. Only update-scene / import-scene (CLI) can do this — there is no MCP tool for it. Common use: point a slow "set each shade" scene at a single vendor "scene switch" so one press moves everything at once.

  1. Inspect current actions: homeclaw-cli get-scene "Main Blinds - Open" --json
  2. Write the new definition. Actions are {"accessory", "property", "value"}; characteristic is accepted as an alias for property, so get-scene output round-trips. Reference accessories by UUID when names collide.
    { "name": "Main Blinds - Open",
      "actions": [ { "accessory": "Open Main Blinds", "property": "power", "value": "1" } ] }
  3. Dry-run, then apply. Pipe via stdin (-) to avoid the sandbox file limit below:
    cat scene.json | homeclaw-cli update-scene - --dry-run    # check resolved_actions
    cat scene.json | homeclaw-cli update-scene -
    --dry-run reports resolved_actions; if it's below your action count, an accessory/property didn't resolve — read the warnings.

Sandbox file access. homeclaw-cli is sandboxed to the app group, so it can only open files under ~/Library/Group Containers/group.com.shahine.homeclaw/ (or system paths). Files in /tmp, ~/Desktop, or agent temp dirs fail with "couldn't be opened because you don't have permission to view it" — this is not fixed by granting Full Disk Access. Pipe JSON via stdin (-), or place the file in the group container.

Detach a hidden scene from a button (CLI)

Buttons sometimes carry hidden, trigger-owned scenes (e.g. an auto-generated close-all fired alongside an open) that get-scene can see but update-scene/delete-scene cannot edit (they only search visible scenes). Detach them from the automation instead:

  1. Find the automation: homeclaw-cli automations list --json
  2. Detach the scene (--add-scene/--remove-scene repeatable, --dry-run supported, trigger UUID preserved):
    homeclaw-cli automations rewire "<automation id>" --remove-scene "<scene name or uuid>" --dry-run
    homeclaw-cli automations rewire "<automation id>" --remove-scene "<scene name or uuid>"

Button modes and service_index

Programmable switches (Aqara, Hue, etc.) may operate in different modes:

  • Fast mode: Multiple buttons (e.g., Button 1 and Button 2), each single-press only. Fires instantly with no delay. Identified by input_event metadata max: 0 on each service.
  • Multi-event mode: One button with single, double, and long press. Adds ~300ms delay to detect press type. Identified by 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.

Name each gang of a multi-gang accessory, and set Display As

A dual relay (e.g. Aqara Dual Relay T2) is one accessory with two switch services; every gang shares the accessory UUID and serial. Separating its tiles in the Home app only changes layout. Plain rename names the accessory and its primary tile only — name the other gang by service:

homeclaw-cli get "Downlight 1" --json          # services[] lists each gang's id, name, index, display_as
homeclaw-cli rename "Downlight 1" "Downlight 2" --service-name "Switch 2"   # or --service-index 2 / --service-id <uuid>
homeclaw-cli rename <service-uuid> "Downlight 2"                            # a service UUID also works as the target
homeclaw-cli set-display-as "Downlight 1" light --service-name "Downlight 2" --dry-run

Group accessories into one tile

A Home app group ("Group with Other Accessories") is one tile and one Siri target for several accessories, e.g. all ceiling lights in a room. Members are services, so one gang of a dual relay can join on its own via its service UUID. Separating a multi-gang accessory's tiles is different: that's layout only, not a group.

homeclaw-cli groups                                                    # existing groups and members
homeclaw-cli groups create "Lounge Ceiling" "Downlight 1" <switch-2-service-uuid> --dry-run
homeclaw-cli groups add "Lounge Ceiling" "Stairs LED"
homeclaw-cli groups remove "Lounge Ceiling" "Stairs LED"
homeclaw-cli groups rename "Lounge Ceiling" "Lounge Lights"
homeclaw-cli groups delete "Lounge Lights"                             # accessories are untouched

Members must be lights, switches, outlets, fans, or window coverings, and one kind per group (lights with lights), as in the Home app; set a relay's Display As to light first so it counts as a light, or pass --allow-mixed. MCP: homekit_manage actions list_groups, create_group, add_to_group, remove_from_group, rename_group, delete_group with group, members, allow_mixed.

MCP: homekit_manage with action: "rename" or action: "set_display_as" plus service_name / service_index / service_id. This writes the home's service name, so it works even when the gang's HAP name characteristic is read-only. Display As (light, fan, or the service's own switch / outlet; default restores it) applies only to switch and outlet services — a gang bridged over Matter as a light has no Display As, in the Home app or here.

Error Handling

ErrorCauseResolution
"HomeClaw is not running"App not launched or socket missingLaunch HomeClaw.app
"Connection failed"Socket exists but app not respondingRestart the app
0 homes / ready: falseMissing entitlement or iCloud not signed inCheck codesign entitlements and iCloud
"Accessory not found"Wrong UUID or nameUse search to find the correct identifier
"Characteristic not writable"Trying to set a read-only characteristicCheck the writable column in the characteristics tables below
Values show "nil"Accessory is unreachable or bridge hasn't syncedCheck reachable field; unreachable devices return nil for all state values
"couldn't be opened because you don't have permission to view it"update-scene/import-scene given a file outside the sandbox (e.g. /tmp)CLI is app-sandboxed — pipe JSON via stdin (homeclaw-cli update-scene -) or put the file under ~/Library/Group Containers/group.com.shahine.homeclaw/. FDA does not help.
"Scene not found" on update-scene for a scene get-scene can seeIt's a hidden, trigger-owned sceneUse automations rewire <automation> --remove-scene <scene> to detach it; it can't be edited in place
Dry-run shows resolved_actions: 0 with "missing fields"Action used characteristic on an old build, or lacks accessory/property/valueUse property (or update to a build where characteristic is an accepted alias); ensure all three keys are present

Configuration

Config file: ~/.config/homeclaw/config.json

SettingValuesDefault
default_home_idHome name or UUIDPrimary home
accessory_filter_modeall, allowlistall
allowed_accessory_idsArray of UUIDs[]
temperature_unitfahrenheit, celsius, autoauto (uses system locale)

Use homekit_config to view and modify settings. When temperature_unit changes, the characteristic cache is automatically invalidated and refreshed.


Accessory Categories

Categories are mapped from Apple's HMAccessoryCategoryType constants. Homebridge devices that don't map to a known category will show the raw UUID string.

CategoryDescription
lightbulbLights, bulbs, LED strips
switchGeneric on/off switches
outletSmart plugs and outlets
fanCeiling fans, standing fans
thermostatHVAC thermostats
lockDoor locks
doorDoor sensors/controllers
garage_doorGarage door openers
windowWindow actuators
window_coveringBlinds, shades, curtains
sensorTemperature, humidity, motion, contact sensors
security_systemHome security systems
programmable_switchButtons, remote controls
air_purifierAir purifiers and filters
cameraIP cameras
doorbellVideo doorbells
speakerSpeakers, cameras with audio (UniFi Protect cameras show as speaker)
valveWater valves, sprinkler controllers (Water Shutoff, Eve Aqua)
bridgeHomeKit bridges (Homebridge, Hue Bridge, etc.)
range_extenderNetwork range extenders

Characteristics by Category

Lightbulb

CharacteristicTypeRangeWritable
powerbooleantrue/falseYes
brightnessinteger0-100Yes
huefloat0-360Yes
saturationfloat0-100Yes
color_temperatureinteger140-500 (mireds)Yes

Thermostat

CharacteristicTypeRangeWritable
current_temperaturestringFormatted with unit, e.g. "71°F"No
target_temperaturestringFormatted with unit, e.g. "70°F". Set with plain number in user's unit.Yes
current_heating_coolingenum0-3No
target_heating_coolingenum0-3Yes
temperature_unitsenum0=Celsius, 1=FahrenheitNo
current_humidityfloat0-100No
target_humidityfloat0-100Yes

Note: Temperature values are returned as formatted strings with the user's preferred unit (e.g., "71°F" or "22°C"). This applies to all current_temperature readings across all accessory types (thermostats, sensors, leak detectors, etc.).

Lock

CharacteristicTypeRangeWritable
lock_current_stateenum0-3No
lock_target_stateenum0-1Yes

Door / Garage Door

CharacteristicTypeRangeWritable
current_door_stateenum0-4No
target_door_stateenum0-1Yes
obstruction_detectedbooleantrue/falseNo

Fan

CharacteristicTypeRangeWritable
activebooleantrue/falseYes
rotation_speedfloat0-100Yes
rotation_directionenum0=clockwise, 1=counterYes
swing_modeenum0=disabled, 1=enabledYes
current_fan_stateenum0-2No
target_fan_stateenum0=manual, 1=autoYes

Window Covering

CharacteristicTypeRangeWritable
current_positioninteger0-100No
target_positioninteger0-100Yes
position_stateenum0=decreasing, 1=increasing, 2=stoppedNo

Sensor (common)

CharacteristicTypeRangeWritable
motion_detectedbooleantrue/falseNo
contact_stateenum0=detected, 1=not detectedNo
current_temperaturefloatvariesNo
current_humidityfloat0-100No
current_light_levelfloat0.0001-100000 (lux)No
battery_levelinteger0-100No
low_batterybooleantrue/falseNo
charging_stateenum0-2No

Enum Value Mappings

Heating/Cooling State

ValueNameWritable as
0Offoff or 0
1Heatheat or 1
2Coolcool or 2
3Autoauto or 3

Lock State

ValueNameWritable as
0Unsecuredunlocked, unsecured, or 0
1Securedlocked, secured, or 1
2Jammed(read-only)
3Unknown(read-only)

Door State

ValueNameWritable as
0Openopen or 0
1Closedclosed or 1
2Opening(read-only)
3Closing(read-only)
4Stopped(read-only)

JSON Response Structure

list / search Response

Each accessory includes name, id, category, room, reachability, and a summary of current state values.

FieldTypeDescription
namestringAccessory display name
idstringUUID identifier
categorystringCategory type (see above)
roomstringRoom assignment
reachablebooleanWhether accessory is online
stateobjectKey-value map of current characteristic values

get Response

Full detail includes all services and their characteristics, each with name, current value, and writable flag.

FieldTypeDescription
namestringAccessory display name
idstringUUID identifier
categorystringCategory type
roomstringRoom assignment
reachablebooleanWhether accessory is online
servicesarrayServices with nested characteristics array
services[].characteristics[].namestringCharacteristic name
services[].characteristics[].valuestringCurrent value
services[].characteristics[].writablebooleanWhether value can be set

status Response

FieldTypeDescription
readybooleanWhether HomeKit is connected
homesintegerNumber of homes
accessoriesintegerNumber of accessories
cache.cached_accessoriesintegerNumber of accessories with cached values
cache.is_stalebooleanWhether cache needs refresh
cache.last_warmedstring?ISO timestamp of last cache warm, or null

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.