Skip to content

How brAIn Controls Your Home

brAIn gives itself three ways to touch Home Assistant, and at first glance they look like three overlapping control panels. They’re not — they’re one brain with one set of hands, plus a toolbox anyone in the house can reach. This page explains what each layer is for, how they interact, and exactly where the (small, deliberate) overlap is.

The three layers in one table

CLI tools (brain, ha)MCP toolsPower Tools (brain.* services)
What it isShell commands in the terminalClaude’s live API into HAReal HA services registered by the integration
Who can call itYou and Claude, in the terminal onlyClaude only (terminal, voice, tasks)Anyone: Claude, automations, scripts, Developer Tools, voice
What it touchesFiles & workflow: YAML, logs, memory, undo, packagesLive state: entities, devices, cameras, history, registries, dashboardsAdmin state: areas, labels, helpers, users, dashboards, zones…
Exampleha reload automationsget_camera_snapshot, control_lightbrain.create_helper

How they fit together

MCP is Claude’s only pair of hands. Everything Claude does to your live home — reading a sensor, turning on a light, looking at a camera, calling any service — goes through the MCP server’s 36 tools. That single funnel is what makes safety enforceable: per-agent service deny-lists and voice tool-scoping are applied at that chokepoint, once, and cover everything.

Power Tools are not a second pair of hands — they’re verbs installed into HA itself. Registering the 65 admin operations as real brain.* services (instead of private Claude abilities) is a deliberate choice with three payoffs:

  1. Claude reaches them through MCP like any other service (call_servicebrain.create_area), so the same deny-lists and budgets apply.
  2. Your automations and scripts get the same superpowers with no Claude in the loop — a nightly automation can call find_orphaned_references by itself.
  3. You can drive them by hand from Developer Tools → Actions, with field pickers and validation.

CLI tools are the workshop bench, and they only exist inside the terminal. They cover the file-and-workflow side that live APIs don’t: editing and reloading YAML, tailing logs, the memory document, the edit journal, persistent packages. brAIn uses them for config work; you use them when you’re in the shell anyway.

They are two commands, split by what they act on: brain for brAIn’s own faculties (memory, learn, ask, undo, doctor) and ha for Home Assistant operations (log, reload, entity, service, addon, notify, share, check, context). See the CLI.

So the flow for any request is:

"Label everything battery-powered and build me a guest-mode toggle"
Claude (terminal / voice / task)
│ MCP — the single funnel (deny-lists enforced here)
├── get_registry ─────────── read: which entities, which labels exist
├── call_service ──────────► brain.add_label (Power Tool)
└── call_service ──────────► brain.create_helper (Power Tool)
"Fix my automations.yaml indentation and reload"
Claude (terminal)
├── edits the file directly (terminal file access)
└── ha reload automations (CLI tool)

The rule of thumb:

Files → CLI. Live home → MCP. Admin changes → Power Tools (via MCP).

brAIn’s generated context teaches it this routing, so you never have to think about it — you just ask.

A few verbs appear in two layers on purpose — ha service call and call_service hit the same HA endpoint, one for you at a shell prompt and one for Claude (which always goes through MCP, because that’s where the deny-lists live). Collapsing to a single layer would mean either taking services away from your automations or pushing YAML editing through an API that can’t do it.

What brAIn can and can’t reach

The goal is an instance where Claude can do essentially everything — here’s the honest scorecard:

Fully covered: entity/device control for every major domain; cameras; history and statistics; automations, scripts, and scenes (YAML + reload); areas, floors, labels; entity naming, ids, aliases, icons, visibility; helpers (all 8 types); zones; persons; users; dashboards including custom-card resources; blueprints; statistics backfill; integration enable/disable/reload and removal; device and entity deletion, including orphan sweeps that dry-run by default; repairs; logs, traces, templates; and undo of any file it edited.

Deliberately excluded:

  • Adding an integration — config flows are interactive (OAuth, discovery, pairing buttons), so Claude walks you to the right screen and you click. Removing one it can do: brain.delete_integration drops the config entry and reports the entities and devices that went with it.
  • Credentials and auth internals — API keys inside core.config_entries, tokens, MFA. Never read, never written, never snapshotted into the edit journal.
  • Backing up your configuration — that’s Home Assistant’s own backups’ job. brAIn keeps an edit journal of the files it touched so brain undo can revert one, and nothing more.
  • HA Core/OS updates and add-on installs — Supervisor territory; ha addon covers restarts and logs, but installs stay a human decision.

YAML config is not an exception

Nothing on your disk is off limits. If a dashboard, helper or person is defined in YAML rather than through the UI, the registry service for it declines — a brain.* service edits the registry, and a YAML-defined object isn’t in the registry. brAIn just takes the other route: it opens the file, edits it, validates it, and reloads the domain. Same outcome, and the same edit journal behind it, so brain undo still puts it back.

That is the routing rule doing its job, not a gap in what brAIn can reach. The only thing you’ll notice is which layer the work happened in.