Tools
Tools are the homer MCP server (tools/speaker/homer_mcp.py) on the speaker computer. Each tool is a narrow action that checks its inputs. It has no shell, no file access and no arbitrary network requests.
The server works at three levels:
- Speaker: Haiku, quick things;
- Tasks: the smart model the speaker hands complex things to (Opus by default);
- Claude Code: your own Claude Code in the terminal, if you connect the server.
List
| Tool | What it does | Speaker | Tasks | Claude Code |
|---|---|---|---|---|
homer_help | Homer help: where each app setting is, how the speaker, brains and log work | ✓ | ✓ | ✓ |
homer_plan | The home plan as Homer sees it: rooms, items, light groups | — | ✓ | ✓ |
plan_add ⚠ | Puts a Home Assistant device on the plan in a room, so the app, Alice and “All lights” see it | — | ✓ | ✓ |
switch_to_light ⚠ | Turns a switch with a lamp on it into a light: in HA, “Change device type” (switch_as_x), on the plan, a light | — | ✓ | ✓ |
memory_save ⚠ / memory_forget ⚠ | The brain's permanent memory: “remember”, “forget” | ✓ | ✓ | ✓ |
memory_read | What the brain remembers permanently | — | ✓ | ✓ |
camera_look | A frame from a home camera: “what can you see”, “is anyone in the kitchen”. It doesn't recognize faces | ✓ | ✓ | ✓ |
house_state | Device states from Home Assistant, with search by name or room | — | ✓ | ✓ |
ha_call | A Home Assistant service for one device: lights, switches, scenes, blinds, climate, fans, media, automations, vacuums | —¹ | ✓ | ✓ |
zigbee_devices | Zigbee network devices: model, manufacturer, whether the interview finished | — | ✓ | ✓ |
zigbee_pair ⚠ | Opens the network for new devices (up to 254 s) and waits to see who joins | — | ✓ | ✓ |
zigbee_stop_pairing ⚠ | Closes the network | — | ✓ | ✓ |
zigbee_rename ⚠ | Renames a device in the bridge and in Home Assistant | — | ✓ | ✓ |
music_play | Yandex Music on the computer speakers or on a Station | ✓ | ✓ | ✓ |
music_control | Stop, next track, volume, what's playing | ✓ | ✓ | ✓ |
timer_set / timer_list / timer_cancel | Timers and reminders by voice | ✓ | ✓ | ✓ |
say | Say a phrase through the speaker | — | ✓ | ✓ |
diag | Whether Home Assistant, the Homer server, the speaker, speaches and the Zigbee bridge are alive | — | ✓ | ✓ |
delegate ⚠ | A task for the smart model | ✓ | — | — |
¹ The speaker controls devices from the snapshot without ha_call too: the actions come right in its answer. ⚠ — every call is written to the log.
Allowed Home Assistant services
| Domain | Services |
|---|---|
light, switch, input_boolean | turn_on, turn_off, toggle |
scene | turn_on |
cover | open_cover, close_cover, stop_cover, set_cover_position |
climate | set_temperature, set_hvac_mode, turn_on, turn_off |
fan | turn_on, turn_off, set_percentage |
media_player | turn_on, turn_off, media_play, media_pause, media_next_track, volume_set, volume_mute |
automation | turn_on, turn_off, trigger |
vacuum | start, stop, return_to_base |
button | press — camera turn, TV “volume up”, “channel up” |
select | select_option — TV channel, input |
number | set_value — TV volume |
The speaker and tasks can't edit configuration, delete devices or restart Home Assistant: only the setup tools below can, and only in your Claude Code.
Home setup (Claude Code only)
| Tool | What it does | Speaker | Tasks | Claude Code |
|---|---|---|---|---|
ha_registry | HA registries: areas, floors, labels, devices, entities | — | ✓ | ✓ |
ha_integrations | Integrations, their state, and what HA found on the network by itself | — | ✓ | ✓ |
ha_template | A query with a Jinja template | — | ✓ | ✓ |
ha_check | Configuration check, open repairs, version | — | ✓ | ✓ |
ha_logs | Errors and warnings from the HA log | — | ✓ | ✓ |
ha_area ⚠ | Create, rename, delete an HA area, floor, label | — | — | ✓ |
ha_entity_update ⚠ | Name, entity_id, area, disable, hide. When entity_id changes, lists what referred to it | — | — | ✓ |
ha_device_update ⚠ | Device name and area, disable | — | — | ✓ |
ha_flow ⚠ | The HA wizard: add an integration or change its options, step by step | — | — | ✓ |
ha_integration ⚠ | Reload, disable, enable, delete an integration | — | — | ✓ |
ha_config_item ⚠ | Automations, scripts and scenes created in the HA UI | — | — | ✓ |
ha_service ⚠ | Any HA service without the allowlist, with a response; HA restart | — | — | ✓ |
ha_ws ⚠ | A raw HA WebSocket API command; auth/* is closed | — | — | ✓ |
ha_onboard ⚠ | First start of a fresh HA: owner, location, language, token | — | — | ✓ |
ha_connect ⚠ | Check a token and switch the server to another HA | — | — | ✓ |
homer_connect ⚠ | Connect to the Homer server as owner; give it an HA token | — | — | ✓ |
homer_settings ⚠ | Homer brains, speaker names, microphones, voice | — | — | ✓ |
homer_packages ⚠ | HA packages homer_*.yaml: write with auto-rollback, confirm, roll back | — | — | ✓ |
homer_invite ⚠ | An invite for a new device in Homer | — | — | ✓ |
What is closed and why:
- Secrets don't get into the conversation. Tools write passwords and tokens to
secrets/and name only the file in the answer. An integration password in a wizard step is passed as asecret:<file>:<key>reference; the server fills in the value itself. - The PIN, full access and cloud keys are not changed by
homer_settings: only the owner does that by hand in the app. - Packages are written with auto-rollback: if you don't come back with
confirmwithinconfirm_withinseconds (300 by default), the Homer server restores the previous version itself. - Automations from packages are not touched by
ha_config_item: saving there would create a duplicate inautomations.yaml.
TV, cameras and Alice groups
The speaker sees not only the item on the plan, but also its neighbors on the same Home Assistant device: for a TV, volume, channel, input, mute and pause; for a camera, the turn buttons. Service entities (child lock, relay timer) don't get into the snapshot. Cameras are always included; “Homer, who's in the kitchen?” makes the speaker take a frame with camera_look and describe it in one sentence.
Things are called the same way Alice calls them: the Homer server fetches names and groups from the Yandex app every ten minutes. “Homer, turn off the monitors”: the “Monitors” group from the Yandex app expands into three outlets. A device that isn't in Home Assistant (connected to Alice by another skill) is passed by the speaker to Alice with the same phrase. Alice works only in a Russian home.
A switch as a light, and “All lights”
“All lights” (light.homer_house) is every light.* placed on the home's plans: the Homer server gives them the homer_house label, and the group collects its members by it. A switch (switch.*) is not in it, even if a lamp is connected to it; it has to be made a light first.
By voice: “Homer, make the kitchen switch a light and add it to all lights”. The speaker hands this to the smart model, which calls switch_to_light: in Home Assistant a light.… with the same name appears (the switch itself is hidden), on the plan the switch is replaced with a light, and if it wasn't on the plan, the light is placed in the named room. A minute later the light joins “All lights”. Every step is in the log.
By hand: Home Assistant → Settings → Devices & services → Helpers → “Change device type of a switch” → the switch → “Light”; then in Homer place the new light on the plan (plan editing → “Devices and items”).
Turning tools on and off
Settings → Speaker → Homer brains → Allowed. Each tool has a checkbox per level.
You can:
- turn off any tool at any level. For example, forbid your Claude Code to search for Zigbee devices, or turn off tasks by removing
delegatefrom the speaker; - restore everything with the Defaults button.
You can't:
- turn a tool on where it doesn't exist (a dash);
- add a new tool from settings. Tools are code, and each checks its own inputs. A new ability built from existing tools is added as a skill.
The speaker picks up changes within a minute, tasks from the next task, Claude Code at the next session start. Every change of the set is written to the log: who turned what on or off.
How to write a new tool
For developers: a tool is a Python function in tools/speaker/homer_mcp.py with type annotations and a docstring. The model sees the docstring as instructions.
def vacuum_room(room: str) -> str:
"""Clean one room with the robot vacuum: room is "kitchen", "bedroom"."""
...Then:
- add the function to the level list (
VOICEorFULL) at the end of the file; - describe it in the Homer server's
AGENT_TOOLScatalog (sidecar/src/alice/agent.ts): name, description, levels, danger; - for the speaker, add a hint to
TOOL_HINTSinspeaker.py(and toTOOL_HINTS_ENfor an English home).