Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 48 additions & 9 deletions docs/HOME-ASSISTANT.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,24 @@ CAAL connects to Home Assistant's MCP server but exposes only two simplified too
| `hass_control(action, target, value)` | Control devices |
| `hass_get_state(target)` | Get device status |

This simplification (from 15 raw MCP tools to 2 wrapper tools) dramatically improves LLM tool-calling reliability.
This simplification (from 15+ raw MCP tools to 2 wrapper tools) dramatically improves LLM tool-calling reliability.

### Automatic Prefix Detection

Different Home Assistant MCP implementations use different tool naming conventions:
- Official HA MCP: bare names like `HassTurnOn`
- Some community servers: prefixed names like `assist__HassTurnOn`

CAAL automatically detects which prefix your server uses at startup, so you don't need to configure anything.

### Domain-Aware Intent Mapping

CAAL caches device information from Home Assistant to provide intelligent intent mapping. For example:
- "open the garage door" → Uses `HassOpenCover` (not `HassTurnOn`) because it's a cover device
- "turn on the office lamp" → Uses `HassTurnOn` for lights/switches
- "set thermostat to 72" → Uses `HassClimateSetTemperature` for climate devices

This domain-aware approach significantly improves reliability for devices like garage doors, blinds, and thermostats.

## hass_control

Expand All @@ -28,31 +45,51 @@ Control Home Assistant devices with a simple action/target interface.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `action` | string | Yes | The action to perform (see table below) |
| `target` | string | Yes | Device name (e.g., "office lamp", "apple tv") |
| `value` | integer | No | Value for `set_volume` (0-100) |
| `target` | string | Yes | Device name (e.g., "office lamp", "garage door", "thermostat") |
| `value` | integer | No | Value for `set_volume`/`set_brightness` (0-100) or `set_temperature` (degrees) |

### Supported Actions

| Action | HASS MCP Tool | Description |
|--------|---------------|-------------|
| `turn_on` | HassTurnOn | Turn on a device/switch |
| `turn_off` | HassTurnOff | Turn off a device/switch |
| `turn_on` | HassTurnOn / HassOpenCover* | Turn on a device/switch (or open a cover) |
| `turn_off` | HassTurnOff / HassCloseCover* | Turn off a device/switch (or close a cover) |
| `open` | HassOpenCover | Open a cover (garage door, blinds, etc.) |
| `close` | HassCloseCover | Close a cover |
| `stop` | HassStopMoving | Stop a cover mid-motion |
| `toggle` | HassToggle | Toggle device state |
| `set_brightness` | HassLightSet | Set light brightness (requires `value` 0-100) |
| `set_temperature` | HassClimateSetTemperature | Set thermostat temperature (requires `value`) |
| `pause` | HassMediaPause | Pause media playback |
| `play` | HassMediaUnpause | Resume media playback |
| `next` | HassMediaNext | Skip to next track |
| `previous` | HassMediaPrevious | Go to previous track |
| `volume_up` | HassSetVolumeRelative | Increase volume |
| `volume_down` | HassSetVolumeRelative | Decrease volume |
| `set_volume` | HassSetVolume | Set volume to specific level (requires `value`) |
| `set_volume` | HassSetVolume | Set volume to specific level (requires `value` 0-100) |
| `mute` | HassMediaPlayerMute | Mute audio |
| `unmute` | HassMediaPlayerUnmute | Unmute audio |

*Domain-aware: `turn_on`/`turn_off` automatically use cover intents for cover devices.

### Examples

```
"Turn on the office lamp"
→ hass_control(action="turn_on", target="office lamp")

"Open the garage door"
→ hass_control(action="open", target="garage door")

"Close the blinds"
→ hass_control(action="close", target="blinds")

"Set the thermostat to 72"
→ hass_control(action="set_temperature", target="thermostat", value=72)

"Set bedroom lights to 50 percent"
→ hass_control(action="set_brightness", target="bedroom lights", value=50)

"Pause the Apple TV"
→ hass_control(action="pause", target="apple tv")

Expand Down Expand Up @@ -91,12 +128,14 @@ The default prompt (`prompt/default.md`) includes instructions for using these t
# Home Control (hass_control)

Control devices with: `hass_control(action, target, value)`
- **action**: turn_on, turn_off, volume_up, volume_down, set_volume, mute, unmute, pause, play, next, previous
- **target**: Device name like "office lamp" or "apple tv"
- **value**: Only for set_volume (0-100)
- **action**: turn_on, turn_off, open, close, toggle, volume_up, volume_down, set_volume, mute, unmute, pause, play, next, previous, set_brightness, set_temperature, stop
- **target**: Device name like "office lamp", "garage door", or "thermostat"
- **value**: For set_volume/set_brightness (0-100), set_temperature (degrees)

Examples:
- "turn on the office lamp" → `hass_control(action="turn_on", target="office lamp")`
- "open the garage door" → `hass_control(action="open", target="garage door")`
- "set thermostat to 72" → `hass_control(action="set_temperature", target="thermostat", value=72)`
- "set apple tv volume to 50" → `hass_control(action="set_volume", target="apple tv", value=50)`

Act immediately - don't ask for confirmation. Confirm AFTER the action completes.
Expand Down
8 changes: 5 additions & 3 deletions prompt/default.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,14 @@ Speaking about an action is not the same as performing it. CALL the tool.
# Home Control (hass_control)

Control devices with: `hass_control(action, target, value)`
- **action**: turn_on, turn_off, volume_up, volume_down, set_volume, mute, unmute, pause, play, next, previous
- **target**: Device name like "office lamp" or "apple tv"
- **value**: Only for set_volume (0-100)
- **action**: turn_on, turn_off, open, close, toggle, volume_up, volume_down, set_volume, mute, unmute, pause, play, next, previous, set_brightness, set_temperature, stop
- **target**: Device name like "office lamp", "garage door", or "thermostat"
- **value**: For set_volume/set_brightness (0-100), set_temperature (degrees)

Examples:
- "turn on the office lamp" → `hass_control(action="turn_on", target="office lamp")`
- "open the garage door" → `hass_control(action="open", target="garage door")`
- "set thermostat to 72" → `hass_control(action="set_temperature", target="thermostat", value=72)`
- "set apple tv volume to 50" → `hass_control(action="set_volume", target="apple tv", value=50)`

Act immediately - don't ask for confirmation. Confirm AFTER the action completes.
Expand Down
9 changes: 6 additions & 3 deletions src/caal/integrations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
MCP integrations for voice assistant.
"""

from .hass import create_hass_tools, detect_hass_tool_prefix
from .mcp_loader import MCPServerConfig, initialize_mcp_servers, load_mcp_config
from .n8n import discover_n8n_workflows, execute_n8n_workflow
from .web_search import WebSearchTools

__all__ = [
"load_mcp_config",
"initialize_mcp_servers",
"MCPServerConfig",
"create_hass_tools",
"detect_hass_tool_prefix",
"discover_n8n_workflows",
"execute_n8n_workflow",
"initialize_mcp_servers",
"load_mcp_config",
"MCPServerConfig",
"WebSearchTools",
]
Loading