Generate a Long-Lived Access Token in the Home Assistant user profile page; this token is used to authenticate WebSocket connections
Open a WebSocket connection to ws://<ha-host>:8123/api/websocket; after connection, Home Assistant sends an auth_required message
Authenticate by sending: {"type": "auth", "access_token": "YOUR_TOKEN"}; Home Assistant responds with auth_ok or auth_invalid
Subscribe to state_changed events: send {"id": 1, "type": "subscribe_events", "event_type": "state_changed"} and receive real-time updates for every entity state change
Call a service (e.g., turn on a light): send {"id": 2, "type": "call_service", "domain": "light", "service": "turn_on", "service_data": {"entity_id": "light.living_room"}}
Unsubscribe from events when done: send {"id": 3, "type": "unsubscribe_events", "subscription": 1} using the id from the subscribe call
Known gotchas
Each message requires a unique numeric id field; reusing IDs causes responses to be misrouted — use a monotonically incrementing counter
The WebSocket API is not versioned and can change between Home Assistant releases; pin or test against your deployed HA version
Long-lived tokens do not expire but are invalidated if the user account is deleted or the token is revoked; build token-refresh or reconnect logic for long-running integrations
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp