Skip to content

Repository files navigation

Claude for Home Assistant

Claude for Home Assistant

Chat with Claude from Home Assistant Assist, and call it from your automations — powered by the companion Claude Code add-on running on your own hardware. Requires Home Assistant OS or Supervised.

release release date HACS Default Home Assistant Python License: MIT

quality scale: platinum coverage: 100% Checked with mypy Ruff pre-commit

hassfest hacs lint tests secret-scan


claude_ha exposes Claude to Home Assistant itself. It talks to Claude through the Claude Code add-on over Home Assistant's internal network — the add-on holds the login and runs Claude, while this integration is a thin, secure client. Nothing here calls the Anthropic cloud directly.

💬 Conversation agent Talk to Claude from HA Assist — replies stream in live, it acts on benign requests immediately and confirms important ones (judged per action).
👁️ Camera vision Optionally, a visual question ("who's at the door?") sends one snapshot of an Assist-exposed camera to Claude. Off by default.
🗨️ Dashboard chat card A bundled Lovelace card to chat with Claude and Apply/Dismiss its suggestions.
⚙️ claude_ha.ask action Send a prompt to Claude from automations, optionally confirming changes via a phone notification.
📟 Sensors Add-on readiness, active model, and Claude token usage + prompt-API cost.
🩺 Health checks Detects the "chat can't see your home" gaps and raises a repair with the exact fix.
🎙️ Local voice one-click claude_ha.setup_voice installs Whisper + Piper and builds an Assist pipeline for your language.
🔒 Secure by design Read-only by default, bearer-token auth, scoped writes, no cloud calls.
🚀 Zero-touch setup Discovered, installed and started for you via the Supervisor.

Contents

How it works

HA Assist ─┐
           ├─► claude_ha (this integration) ──HTTP + bearer──► Claude Code add-on ──► Claude
Automation ┘        conversation entity                        (own agentic loop,
                    claude_ha.ask action                         scoped HA access)

The integration and the add-on are separate projects that connect through a small, versioned HTTP contract (a bearer-authenticated prompt server on the add-on's internal port). The connection details — host, port and a shared token — are handed to the integration automatically through Supervisor discovery, so there is nothing to type in.

Requirements

  • Home Assistant OS or Supervised (the integration manages a Supervisor add-on).
  • The Claude Code add-on. Home Assistant doesn't ship it, so add its repository URL — https://github.com/LayerTM/ClaudeInHA — to your add-on store once, then install the add-on from there.

Installation

HACS

This integration is listed in the HACS default store. A freshly listed repository takes a few hours to reach every HACS install, so the button below is the reliable route in the meantime — if your HACS doesn't know the repository yet, it offers to add it.

Open in HACS

  1. Click Open in HACS above and install Claude. (Accept the prompt if HACS asks to add the repository first.) You can also search HACS for claude-ha — search for Claude alone and you'll get several similarly-named integrations, while claude-ha matches only this one.
  2. Restart Home Assistant.
  3. Install the Claude Code add-on. Once it starts, Home Assistant offers to set up the Claude integration automatically — accept it. No configuration needed.

Neither route working? Add LayerTM/claude-ha as a custom repository (category Integration). If HACS replies that the repository already exists in the store, then it is already listed — search for claude-ha instead.

Manual

Copy custom_components/claude_ha into your Home Assistant config/custom_components/ directory and restart.

Configuration

Setup is zero-touch: when the Claude Code add-on starts it advertises its host, port and a freshly generated token through Supervisor discovery, and Home Assistant surfaces a one-click setup. You can also add it from Settings → Devices & services → Add integration → Claude; it will find, install and start the add-on for you. There are no options to fill in.

Usage

Conversation agent

Select Claude as a conversation agent under Settings → Voice assistants, or target it directly. It answers in any language, and it can act on your home. Answers stream in live, token by token (with the Claude Code add-on ≥ 1.17.0; older add-ons return the whole answer at once).

Every request is read first. If it would change state, Claude proposes the exact actions, and the integration decides — per action, from live entity metadata — whether to carry it out immediately or confirm:

  • Benign, low-risk actions run right away (e.g. turning a light on) and reply Done: ….
  • Important actions are held and confirmed with a plain yes / no — anything the deterministic classifier flags (locks, alarms, garage/door/gate covers, firmware updates, router/AP and other config entities, and opaque-effect wrappers like scenes, scripts and automations), anything Claude itself marks non-low-risk, or anything you pin as critical. The classifier only auto-runs an action it can positively prove benign — anything it can't resolve or bound falls back to confirmation. The confirmation replays the exact validated actions, so it never depends on the model remembering them.

Criticality is judged per action, not per domain — a shade and a garage door are both cover, but only the garage door is confirmed. Requires the Claude Code add-on ≥ 1.8.0 (older add-ons simply confirm everything). Tune it under the integration's Configure options: turn off auto-execute to confirm every change, or list entities that must always be confirmed.

Claude can only ever touch entities you have exposed to Assist — that exposure list is the outer ceiling; the per-action classifier is the inner gate.

Camera vision (opt-in, off by default; add-on ≥ 1.17.0). Turn on Let Claude look at cameras in the options and a clearly visual question — "who's at the door?", "look at the backyard camera" — sends one snapshot to Claude. Only a camera you have exposed to Assist is ever sent, only when the message is visual and exactly one camera resolves (by name, area or floor); it never guesses between cameras. The add-on fetches and downscales the snapshot itself; the integration passes only the entity id.

Dashboard card

A chat card ships with the integration — no separate install. Add a Manual card (or pick Claude Chat in the card picker) with:

type: custom:claude-chat-card
title: Claude

Type a message and the card shows Claude's reply. If Claude proposes a change, an inline Apply / Dismiss appears; Apply runs the confirmed write.

The claude_ha.ask action

action: claude_ha.ask
data:
  prompt: Summarise today's calendar and suggest what to wear.
response_variable: claude

claude.text holds Claude's answer; the response also includes proposal (a described state change, or null), tools_used, and truncated.

To act on something, use the two-phase flow: a read call returns a proposal with intents; after your own confirmation, echo those exact intents back in a write call. Writes are scoped by the Claude Code add-on to just those confirmed intents — only use write from automations you control, never on untrusted input.

# 1. Ask (read) — get the proposed intents.
- action: claude_ha.ask
  data:
    prompt: Turn off everything in the garage.
  response_variable: claude
# 2. Confirm, then act (write) — echo the confirmed intents back.
- action: claude_ha.ask
  data:
    prompt: Turn off everything in the garage.
    mode: write
    intents: "{{ claude.proposal.intents }}"

Or let Home Assistant ask you to confirm on your phone: pass a notify target, and if Claude proposes a change you get an actionable Approve / Dismiss notification — Approve runs the confirmed write for you.

action: claude_ha.ask
data:
  prompt: Turn off everything in the garage.
  notify: mobile_app_my_phone

Sensors

  • Status (sensor.claude_code_status) — ready / initializing, with the add-on version, Claude version, active model, whether a scoped HA MCP is configured and reachable, a health summary and the count of entities exposed to Assist as attributes.
  • Chat health (sensor.claude_code_chat_health) — a rolling summary of recent chat outcomes (ok / degraded). It asks whether failures are still happening, not whether any ever did. Three failed chats in a row raises it straight away — that's an outage, whatever the longer-run numbers say — and so does one chat in ten or more failing. It clears again once the clean chats since the last failure outnumber the failures behind them, or that failure is over 6 hours old. So a single old blip no longer nags for days, while a problem that is happening right now shows up before it has had time to move an average, and one chat getting through mid-outage isn't enough to call it recovered. The attributes show the working: recent/ok/degraded/recovered counts, the failure_rate the state turns on, consecutive_ok and consecutive_failed (chats since the last failure, and since the last success), the last degrade reason (a token, never prompt content) and the window's timestamps. Needs add-on ≥ 1.20.0; unavailable otherwise. The run counters and the timestamps need add-on ≥ 1.49.0 and are null without it — an add-on that reports none of them is judged on the rate alone, so a missing field neither quiets a warning nor invents one.
  • Daily budget spend (sensor.claude_code_daily_budget_spend) — today's spend in USD against the add-on's daily budget, with limit / remaining / fraction_used / a soft near_cap flag as attributes (a limit of 0 = unlimited leaves those null). Diagnostic; never a repair. Needs add-on ≥ 1.21.0.
  • Token usage today (sensor.claude_code_token_usage_today) — today's input + output tokens (unit tokens), with the full usage report (per-period and per-model token totals, message counts) as attributes. Polled slowly (~5 min; the add-on caches it).
  • Prompt API cost (sensor.claude_code_prompt_api_cost) — the total prompt-API cost in USD (interactive-console use is measured in tokens, not dollars). The usage/cost sensors need the Claude Code add-on ≥ 1.7.0 and stay unavailable otherwise.

Entity ids above are the defaults (device Claude Code + entity name); adjust to your own if you've renamed them.

Usage dashboard

A ready-made overview using only built-in cards — paste it into a dashboard (Edit dashboard → Add card → Manual) to see cost, budget, chat health and MCP state at a glance. No extra install; adjust the entity ids if yours differ, and set the gauge max to your add-on's daily budget cap.

type: vertical-stack
cards:
  - type: entities
    title: Claude
    entities:
      - entity: sensor.claude_code_status
        name: Status
      - entity: sensor.claude_code_chat_health
        name: Chat health
      - entity: sensor.claude_code_daily_budget_spend
        name: Budget spent today
      - entity: sensor.claude_code_token_usage_today
        name: Tokens today
      - entity: sensor.claude_code_prompt_api_cost
        name: Total API cost
  - type: gauge
    entity: sensor.claude_code_daily_budget_spend
    name: Daily budget
    needle: true
    max: 5 # set to your add-on's daily budget cap
    severity:
      green: 0
      yellow: 3.5
      red: 4.5
  - type: history-graph
    title: API cost (24 h)
    hours_to_show: 24
    entities:
      - sensor.claude_code_prompt_api_cost
  - type: history-graph
    title: Tokens today (24 h)
    hours_to_show: 24
    entities:
      - sensor.claude_code_token_usage_today

Cost (USD) and tokens are on separate graphs on purpose — a single graph shares one y-axis, so the small USD range would be flattened against the much larger token count. The budget gauge is only meaningful with a daily budget set on the add-on; with no budget (unlimited) the spend still shows but the gauge scale is arbitrary.

Health checks

The most common "dead on arrival" failure is a chat that reaches Claude but can't actually see your home. The integration checks for this on every status poll and raises a repair with the exact fix when it finds:

  • Claude isn't logged in (the add-on is up but unauthenticated);
  • Claude has no Home Assistant token to read your home;
  • the Model Context Protocol Server integration is missing or unreachable;
  • nothing is exposed to Assist (so there's nothing to see or control).

These checks cost nothing (they read the status poll, not Claude). Press the Check Claude health button to run a deeper probe — a tiny read that confirms Claude can actually reach the MCP server right now. Needs the add-on ≥ 1.14.0 for the reachability signal.

Local voice (one-click)

claude_ha.setup_voice turns local voice chat with Claude into one action. Give it a language and it installs and starts the official Whisper (speech-to-text) and Piper (text-to-speech) add-ons, then creates an Assist pipeline whose conversation agent is Claude:

action: claude_ha.setup_voice
data:
  language: uk        # uk, pl, en, de, …
  # tts_voice: uk_UA-ukrainian_tts-medium   # override the default voice
  # stt_model: small-int8                    # override the Whisper model

Then pick the new pipeline on your phone. Honest caveats: Whisper on CPU takes a few seconds per phrase, and some voices (Ukrainian especially) are weaker than others — pass tts_voice or switch to Cloud TTS if the default doesn't fit. The service returns the engines it wired and the pipeline id.

Security model

The security-critical work lives in the add-on; this integration deliberately does the least it can.

  • Bearer token, not network trust. Every request carries a token issued via Supervisor discovery. It never appears in the UI and is redacted from diagnostics.
  • Read-only by default. Chat is treated as untrusted input and runs deny-by-default; state changes require explicit, scoped, confirmed intents.
  • No cloud calls from HA. The integration only talks to the local add-on.

See SECURITY.md for the reporting policy, and the add-on for the full picture (env-scrubbed child processes, per-call statelessness, rate limiting, output redaction and audit logging).

How data is updated

The status sensor is refreshed by a DataUpdateCoordinator that polls the add-on's /api/status endpoint every 60 seconds. Prompts (chat turns and the ask action) are sent on demand.

Known limitations

  • Requires Home Assistant OS / Supervised — the add-on is a Supervisor add-on and is not available on Home Assistant Container or Core installs.
  • One Claude instance per Home Assistant (one add-on → one config entry).
  • The conversation agent surfaces proposed state changes but does not run a full confirm-and-act handshake from chat; use claude_ha.ask with mode: write from a trusted automation for that.

Troubleshooting

  • "The Claude Code add-on is not running". A repair issue offers to start it; or start it from the add-on page. Home Assistant retries setup automatically.
  • Setup keeps retrying. Check that the add-on is installed, started and healthy; the status endpoint must be reachable on the internal network.
  • Diagnostics. Download diagnostics from the integration's device page (the token is redacted) to inspect the last known status.

Removal

Delete the Claude integration from Settings → Devices & services. If Home Assistant installed the Claude Code add-on for you, remove it separately from the add-on store.

Development

python3.14 -m venv .venv && source .venv/bin/activate
pip install -r requirements_test.txt
pre-commit install

ruff check custom_components tests scripts
ruff format --check custom_components tests scripts
mypy custom_components/claude_ha
pytest --cov=custom_components.claude_ha --cov-report=term-missing
python scripts/secret_scan.py .

CI runs hassfest, HACS validation, ruff, mypy, the test suite (100% coverage) and a secret scan on every push and pull request. See CONTRIBUTING.md.

Brand images live under custom_components/claude_ha/brand/ and are served by Home Assistant's Brands Proxy API (2026.3+) — no separate brands submission needed.

License

MIT © LayerTM

About

Chat with Claude from Home Assistant Assist and automations — via the Claude Code add-on. Conversation agent, claude_ha.ask action, status sensor. HACS-ready, quality-scale platinum.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages