Voice Assistant
Pick brAIn as a conversation agent under Settings → Voice Assistants and every Assist pipeline — voice satellites, the chat dialog, the mobile app — routes through Claude with full knowledge of your home.
Why it’s fast
Typical commands answer in ~3–5 seconds, and replies stream, so TTS starts speaking at the first sentence on streaming-capable pipelines. Two mechanisms:
- Fast mode (
assist_fast_mode, default on): a pool of pre-warmed Claude worker processes — one per active conversation plus a hot spare — so voice turns skip CLI boot and MCP handshake entirely. Budget ~150–300 MB RAM per warm worker (max 3). If a worker ever errors, the add-on falls back to a one-shot spawn automatically. - The area map: a cached area → entity map (controllable domains plus Weather and People) is spliced into the system prompt, so “turn off the kitchen lights” acts directly — no lookup turns.
binary_sensor.brain_system_assist_healthy reports pool health (worker count, spare, last-request latency), and brain doctor probes the whole path end-to-end.
Personalities
Each conversation agent you create gets its own name, model, and system prompt — a butler, a snarky roommate, a kid-friendly narrator. Prompts are layered deliberately:
- Your personality leads, and explicitly owns identity, tone, and verbosity.
- An operational block follows — tools, the area map, timezone, routing rules — deliberately identity-free so it can’t fight your persona.

Without a personality, a built-in default applies (“helpful, efficient, 1–2 short sentences”). With one, that default is dropped entirely — so if your persona should stay brief for TTS, say so in the persona: “…no matter how excited you get, keep spoken replies under two sentences.”
New agents default to Claude Haiku for snappy responses; pick any model per agent in the integration options.
You can run several at once, each with its own name, model, personality and deny-list:
"Jarvis" You are Jarvis, a dry British butler. Address me as "sir". However excited you get, keep spoken replies under two sentences. Blocked: nothing.
"Kids' speaker" You are a cheerful helper for a 7-year-old. Short, simple words. Never mention alarms or locks; if asked, say you'll fetch a grown-up. Blocked: lock.unlock, lock.open, alarm_control_panel.*, script.*The deny-list is enforced where every control tool funnels through, and it’s checked
against what a call does, not what it’s called: Home Assistant’s meta-services forward to
the target’s own domain, so homeassistant.turn_on aimed at cover.garage_door is a
cover call, and the chokepoint resolves meta-calls to their targets and refuses any that
touch a restricted domain — or whose targets it can’t resolve at all, like a whole area.
fire_event, which can trigger an automation that does exactly what the deny-list forbids,
is refused entirely on restricted channels. (Before 1.26.0 the check matched only the
spelled service name, so a meta-call could sidestep it.)
Because voice reads the same memory as everything else, an agent already knows the house it’s talking about:
“Turn on the beacon.” → memory says the beacon is the office lamp.
“It’s too cold in here.” → memory says the heating is a heat pump on weather compensation, not a boiler, so it raises the flow temperature instead of asking for a target temperature that would do nothing.
Conversation memory
While the same Assist chat or voice session stays open, Home Assistant keeps the same conversation_id — and the add-on resumes the same Claude session for each turn, so follow-ups genuinely remember the conversation. A new session starts a clean slate; brain.clear_conversation resets one (or all) manually. If session resume isn’t possible, the integration replays recent turns instead, so follow-ups still work with shorter memory. (Before 1.26.0 a follow-up turn could be handed the pre-warmed spare worker — which knows nothing — and lose the conversation’s context for good; the spare now only serves conversations that genuinely start from nothing.)
Voice is also how the house learns: say “remember that we call the office lamp ‘the beacon’” and it’s stored instantly.
Safe by default: tool scoping
Voice can control everything but can’t run shell commands or edit files — assist_tool_access: mcp_only is the default. Two more dials:
assist_max_turnscaps agentic loops per request (default 8) so a misunderstood command can’t spiral. It stays deliberately modest where the other channels are generous: latency is the product for voice, and a twenty-turn voice command is a failed interaction whatever it answers. Worth knowing on older versions: until 1.26.0, neither this norassist_tool_accessreached fast mode — the default — at all; the worker pool never saw them, so voice always ran at 5 turns whatever the option said.- Per-agent service deny-lists (e.g. forbid
lock.unlockfor the kids’ satellite): every control tool funnels through one chokepoint, so the deny-list covers all of them —homeassistant.*meta-calls included, resolved against their targets as above.brain.*is a one-click deny option too: it keeps a restricted agent away from all 65 registry-admin Power Tools, includingbrain.create_user, which can mint an admin login. See the Reference for the option syntax.
With Power Tools installed, voice requests can also reorganize — “create a zone for the gym”, “hide the child-lock switches” — with the same validation and admin gating as everywhere else.