Skip to content

Tool reference ​

45 tools, prefixed ha_. All read tools carry the readOnlyHint annotation. Responses are compact JSON with a standard list envelope:

json
{ "items": [...], "returned": 50, "total": 734, "has_more": true, "next_offset": 50, "note": "..." }

Entities ​

ha_search_entities ​

Fuzzy search by name, entity_id, Assist alias, area, floor or label. The natural entry point. Aliases weigh like the name; area, floor and labels weigh less.

ParamTypeNotes
querystring, requirede.g. kitchen light
limitnumberdefault 20, max 50

ha_list_entities ​

Paginated list, filterable by domain, area, floor, label, search and state. Called without any filter, it returns a histogram (counts per domain and per area) instead of a dump.

ParamTypeNotes
domainstringe.g. light, sensor, automation
areastringarea name, case insensitive
searchstringfuzzy filter
statestringexact state, e.g. on
limit / offsetnumberdefault 50, max 200

ha_get_entity ​

Full state and attributes of one entity (long attribute values truncated), plus its floor, Assist aliases and labels when it has any.

ParamType
entity_idstring, required

ha_list_areas ​

All areas with their floor and entity counts. No parameters.

ha_list_devices ​

Devices with manufacturer, model, area. Child devices (HA 2026.9) carry parent_device_id and show their parent's area. Params: area, limit, offset.

Services ​

ha_list_services ​

Without parameters: domains and their service counts. With domain: detailed services and fields. With search: cross-domain lookup.

ha_call_service write ​

Only registered when allow_write is enabled. Subject to the write rules.

ParamTypeNotes
domain / servicestring, requirede.g. light / turn_on
targetobjectentity_id, device_id, area_id (prefer entity_id)
dataobjectservice data, e.g. { "brightness_pct": 50 }
dry_runbooleanpreview without executing
confirm_tokenstringtoken from a confirmation_required answer (sensitive domains)
return_responsebooleanfor services that return data

On domains listed in confirm_domains (locks and alarms by default), the first call answers confirmation_required with a single-use confirm_token bound to that exact call; execute by calling again with the same arguments plus the token.

ha_run_script write ​

Runs a script, optionally with variables. Same guarded path as ha_call_service.

ParamTypeNotes
entity_idstring, requiredmust be a script.* entity
variablesobjectpassed to the script
dry_run / confirm_tokenas in ha_call_service

ha_trigger_automation write ​

Triggers an automation now. skip_condition defaults to true (actions run even if conditions do not hold).

ParamTypeNotes
entity_idstring, requiredmust be an automation.* entity
skip_conditionbooleandefault true
dry_run / confirm_tokenas in ha_call_service

ha_set_automation write ​

Enables or disables an automation.

ParamTypeNotes
entity_idstring, requiredmust be an automation.* entity
enabledboolean, requiredtrue to enable
dry_run / confirm_tokenas in ha_call_service

ha_create_helper write ​

Creates a helper: a pure state container with no behaviour (input_boolean, input_number, input_select, input_text, input_datetime, counter, timer). Audited; no confirmation step, creating a helper cannot make the house act.

ParamTypeNotes
helper_typestring, requiredone of the seven types above
namestring, requireddisplay name
optionsobjecttype-specific settings (e.g. min/max for input_number, options list for input_select), passed to HA as-is

ha_delete_helper write ​

Deletes a UI-managed helper by entity_id. The collection id is resolved through the entity registry, so renamed helpers are handled; YAML-defined helpers are refused with a clear message. Subject to the entity allow/deny lists, audited.

ha_snapshot_scene write ​

Captures the CURRENT state of the given entities as a scene ("capture the living room mood as Movie night"), via scene.create with snapshot_entities. The scene is volatile by Home Assistant design (it lives until the scenes reload or a restart); replay it with scene.turn_on. Entity lists bound what is capturable; an existing scene id is refused.

ha_send_notification write ​

Sends a notification to a phone or any notify target. Without target: lists the available targets (legacy notify.* services and modern notify entities); the right call is routed automatically. Goes through the same guarded path as ha_call_service (denylist, audit, dry_run) and is capped at 6 notifications per minute per target: a notification physically disturbs someone, a looping assistant must not hammer.

ParamTypeNotes
messagestring, requiredtruncated beyond ~1000 chars
targetstringe.g. mobile_app_pixel or notify.telephone; omit to list
title / datastring / objectplatform extras passed as-is
dry_run / confirm_tokenas in ha_call_service

ha_announce write ​

Speaks a message in the house ("announce that dinner is ready"). Without target: lists Assist satellites, media players and TTS engines. Satellites use their native announce; media players go through tts.speak (engine auto-picked or passed via engine). Same guarded path as every service call, and capped at 3 announcements per minute per target: a voice in the living room disturbs more than a vibration. Messages truncated at ~500 chars (it is audio).

ha_create_automation config write ​

Creates a NEW automation. Only registered when allow_config_write is enabled (independent from allow_write). The flow is deliberately heavy: Home Assistant validates the blocks first, then the answer carries the complete YAML and a confirm_token; the client must show the YAML to the human and call again with the token. Existing automations (same alias) are refused: creation only, no modification. variables and max_exceeded are accepted at creation (#158), no need to create then update.

ParamTypeNotes
aliasstring, requiredautomation name
description / modestring / enumsingle (default), restart, queued, parallel
triggersarray, requiredmodern syntax, e.g. [{"trigger": "state", ...}]
conditionsarrayoptional
actionsarray, requirede.g. [{"action": "light.turn_on", ...}]
dry_run / confirm_tokenpreview / second-step token

ha_create_script config write ​

Creates a NEW script, same guarded two-step flow. The entity id derives from the alias (script.<slug>); an existing one is refused.

ParamTypeNotes
aliasstring, requiredscript name
description / modeas above
sequencearray, requiredaction sequence
dry_run / confirm_tokenpreview / second-step token

ha_create_from_blueprint config write ​

Creates a NEW automation (or script) from an installed blueprint: the behaviour is already written and vetted, the assistant only fills its typed inputs (required ones are checked before anything is offered, unknown ones are refused). Paradoxically the SAFEST way to program the house. Same guarded two-step flow and creation-only rule as ha_create_automation.

ha_update_automation / ha_update_script config write ​

Update an EXISTING UI-managed automation or script. Provided blocks replace the current ones wholesale (a provided actions list replaces all actions); untouched blocks are preserved. Blueprint-based targets take inputs instead (replaces the whole use_blueprint input set, checked against the installed blueprint); raw blocks are refused on them with a clear message, and alias/description/mode work on both kinds. A provided modern block also removes its legacy twin key (trigger/condition/action) from the stored config, so legacy-to-modern syntax migrations work through the tool. The root tuning keys are covered too (#158): variables (where non-trivial automation logic lives), max_exceeded, initial_state (automations only) and trace, each replaced wholesale like the blocks; passing null removes the key from the stored config (an empty object writes an empty object), which is how leftovers like editor metadata get cleaned up. The confirmation shows a before/after diff, and the base configuration is fingerprinted: if it changes between the two passes (simultaneous UI edit), the token is refused and the flow restarts. The success answer carries the full previous YAML for manual rollback. YAML-defined targets are refused.

ha_delete_automation / ha_delete_script config write ​

Delete an EXISTING UI-managed automation or script. The most destructive tool gets the strongest belts: the first answer carries the complete YAML of what will disappear (not a diff) plus the confirm_token; the client must show it to the human before calling again. The base configuration is fingerprinted like an update: a UI edit between the two passes invalidates the token. The success answer returns deleted_yaml, so ha_create_automation / ha_create_script can recreate it if the deletion turns out to be a mistake; the add-on itself stores nothing. YAML-defined items are out of reach (their lifecycle belongs to the user's files), and the entity allow/deny lists apply.

Automations and scripts ​

ha_list_automations ​

entity_id, name, enabled, last_triggered, and source: ui for automations editable through the config tools, yaml for those defined in the user's files (read and trace only). Params: limit, offset.

include_config: true (#160) attaches each UI automation's full configuration and shrinks the page (default 5, max 10): the paginated way to export or diff a fleet without one call per automation (66 automations = ~13 pages instead of 66 calls). The page stays valid JSON, always: a config too large for it is omitted whole per item (config_omitted, fetch it with ha_get_automation), never truncated mid-value; yaml items get config: null without wasting a fetch. Honest position: for the one-shot bootstrap of a very large fleet, the plain REST API remains the better tool; include_config targets deltas and medium fleets.

ha_get_automation ​

State plus, for UI-created automations, the full configuration (triggers, conditions, actions). YAML-defined automations return their state with a note. This tool has a raised response cap (~64 KB instead of the global ~15 KB, #159): its output feeds ha_update_automation, so it must round-trip whole; values are never truncated individually. A config that still exceeds the raised cap (inline base64 media) gets an honest message pointing to the UI editor instead of filters that do not exist here.

ha_list_scripts ​

entity_id, name, running, last_triggered. Params: limit, offset.

ha_list_blueprints ​

Installed automation (or script) blueprints with their inputs: name, description, which inputs are required, defaults and selector types. The natural first stop before creating an automation: ha_create_from_blueprint fills typed holes in vetted behaviour.

ha_get_automation_trace ​

Step-by-step record of recent automation or script runs, the first reflex for "why did this fire (or not)?". Without run_id: the list of recent runs (trigger, outcome, last step, error). With run_id: the ordered step path with condition verdicts, errors, and since 1.3.0 the targets of each step (service, entity/device/area ids, joined from the stored config the way the 2026.9 trace UI does; YAML-defined items carry no targets). Variables are deliberately omitted (size, and they would leak other entities' states past filter_reads). Home Assistant keeps only the last few runs in memory, since its last restart.

Diagnostics ​

ha_explain_event ​

Explains WHY an entity changed: follows Home Assistant's context chain (the immediate actor, what triggered it in turn, the human when there was one, resolved to their person entity when one is linked and visible), up to 4 hops. Since 1.4.0 the answer opens with cause_kind, the same root-cause taxonomy as the 2026.9 Activity dialog: person, schedule, state_change, integration, or an honest unknown. Without at: the entity's last change. Hidden causes appear as (hidden entity) under filter_reads. The missing link between the logbook (what) and ha_get_automation_trace (how); the answer points to the trace when an automation is in the chain.

ha_get_self_test ​

Diagnoses the ADD-ON itself, not the house: WebSocket and REST connectivity with latencies, live state map status, Supervisor availability, and an overall ok / degraded / broken verdict. Contains no data from your home, by design: paste its output into a support issue.

ha_get_health ​

One-call health report: Home Assistant's own Repairs issues, entities unavailable/unknown with age, low batteries (battery_threshold, default 20 %), enabled automations that have not fired for a while (stale_days, default 30), entities without an area. Sections are capped with total counts, and qualified rather than judged: a seasonal sensor is not a defect. Pair it with the health-report prompt.

History ​

ha_get_history ​

State changes of one entity, or of up to 5 at once to compare them (entity_id accepts a string or a list; a list returns a series object keyed by entity). Window: hours (min 0.25, default 24, max 168) or start/end ISO 8601. The first point is the state already in effect at window start; the 250-point budget is shared between the requested entities and downsampled with a note beyond it.

ha_get_statistics ​

Recorder aggregates (mean, min, max, sum) for numeric sensors. statistic_id (string or list up to 10), period among 5minute, hour, day, week, month, window up to one year. Prefer this over ha_get_history for long ranges.

ha_get_logbook ​

Human-readable events, window from 0.25 h up to 7 days, capped at 100 events. Filter by entity_id, or since 1.5.0 by a whole area or floor (one scope at a time): the room is resolved through the catalog into explicit visible entities (filter_reads applies, up to 60 entities with a note beyond), so "what happened in the kitchen tonight?" is one call.

Dashboards ​

ha_list_dashboards ​

Without dashboard: the Lovelace dashboards (title, url_path, editable or YAML-managed). With dashboard: its views (index, title, layout, card count), what ha_add_dashboard_card needs.

ha_add_dashboard_card config write ​

Inserts ONE card into a dashboard view (draft it with propose-dashboard-card first). Same guarded flow as ha_update_automation: before/after diff of the view, the whole-dashboard hash in the confirmation fingerprint (a simultaneous UI edit invalidates the token), previous view YAML returned for rollback. Classic cards and modern sections layouts are both handled; YAML-managed dashboards are refused. Only insertion exists: no card removal, no view rewrite.

Energy and presence ​

ha_get_energy ​

Energy totals from the configured energy dashboard (energy/get_prefs names the exact statistics: grid import/export, solar, battery, gas, water, per-device consumption) over period (day default, week, month). With compare: true, the previous period and the deltas in percent ("this week vs last week"). Totals sum the per-period change statistic, the dashboard's own math. Clear error when no dashboard is configured.

ha_get_presence ​

Who is home, in which zone, since when, plus a compact timeline of zone changes over the window (hours, default 24, max 168) and the zones with their occupant counts. Zone names only, never coordinates: latitude, longitude and tracker sources are never read, by design. filter_reads hides persons like any entity; if you hand out read tokens to third parties, denylisting person.* is the intended control.

Weather ​

ha_get_forecast ​

Without entity_id: lists the weather entities with their current condition. With entity_id: the forecast ("will it rain tomorrow?") via weather.get_forecasts, type among hourly (capped at 48 entries), daily (default, 14) and twice_daily where the provider supports it (its error is relayed otherwise). Units come from the weather entity attributes. Current conditions live on the entity itself (ha_get_entity).

Calendar and to-do ​

ha_get_calendar ​

Without entity_id: lists the calendar entities. With entity_id: events over a window (hours default 24, max 720, or start/end ISO 8601).

ha_get_todo_list ​

Without entity_id: lists the to-do entities. With entity_id: the items on that list (optional status filter). Read only, via todo.get_items.

ha_manage_todo write ​

Adds, completes, unchecks, removes or renames an item ("add milk to the shopping list"). Items are referenced by their text, as Home Assistant does. Same guarded path as every service call (denylist, audit, dry_run).

ParamTypeNotes
entity_idstring, requireda todo.* list
actionenum, requiredadd, complete, uncomplete, remove, rename
itemstring, requiredthe item text
new_namestringrename only
dry_run / confirm_tokenas in ha_call_service

Cameras ​

ha_get_camera_snapshot opt-in ​

Returns the current still image of a camera.* entity as an MCP image, so the assistant can describe what it sees. Registered only when the allow_camera option is enabled (independent from allow_write); filter_reads and entity_denylist still apply, and every snapshot is audited.

Add-ons and system ​

ha_get_addons ​

Without slug: list of installed add-ons. With slug: details of one. Read only. Requires the Supervisor (unavailable in dev mode).

ha_render_template ​

Evaluates a Jinja2 template server-side and returns the rendering. Read only, very powerful for computed queries. Not registered when filter_reads is enabled (a template can read any entity):

{{ states.light | selectattr('state','eq','on') | list | count }}

ha_get_system ​

section: "config": HA version, name, timezone, units, integration count. section: "error_log": recent errors and warnings, structured, from the system log (WS), with a legacy REST fallback for old cores. section: "updates": pending Core, OS and add-on updates; the Core and OS parts need a higher Supervisor role and answer a structured note under the minimal one, while the add-on part always works. section: "backups": last backup age and recent backups (structured note under the minimal role). No section ever leaks a raw HTTP error. The mounts section (1.4.0) reports network storage mounts with their usage and the same fill alerts as the HA Storage page (warning above 85 %, critical above 95 %); per-mount probes are independent and degrade to structured notes.

Resources and prompts ​

Since v0.3 every tool response also carries structuredContent (the same JSON as the text, typed for clients that support it), and the server exposes:

Since 0.18.0, entity-shaped arguments support MCP completions (completion/complete): a client that implements them offers the real ids of your instance while typing, for the automation argument of diagnose-automation and the entity_id of ha://entity/{entity_id}. Same visibility rules as every read (filter_reads applies); client support varies.

Resources (application/json, for clients that pin context without tool calls):

URIContent
ha://areasall areas with their entity counts
ha://servicesservice domains with their service counts
ha://configcompact instance configuration (version, name, timezone, units)
ha://area/{area_id}compact live state of one area (counts per domain, notable active entities); subscribable in session mode

Prompts (guided workflows):

NameArgumentsWhat it does
diagnose-automationautomation (entity_id)step-by-step investigation of why an automation did not run
energy-reporthours (optional)consumption summary built on long-term statistics
health-reportnoneguided instance health check built on ha_get_health
propose-automationgoaldrafts a paste-ready automation YAML from verified entities, writes nothing
propose-dashboard-cardgoaldrafts a paste-ready Lovelace card YAML from verified entities, writes nothing
propose-scriptgoaldrafts a paste-ready script YAML from verified entities, writes nothing
daily-briefingnonethe morning ritual: presence, agenda, weather, energy, urgent issues