Home Assistant MCP Server
OfficialServer Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| HOMEASSISTANT_URL | Yes | The URL of your Home Assistant instance | |
| HOMEASSISTANT_TOKEN | Yes | A long-lived access token for Home Assistant |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
Filing ha-mcp issues
Before filing any GitHub issue about ha-mcp, feature requests included, run ha_report_issue and put the issue_body it returns in the issue unchanged. A bug report filed without it is closed automatically after 24 hours.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": true
} |
| resources | {
"subscribe": false,
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description | |||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ha_get_appA | Get installed or available Home Assistant apps (add-ons), or details for one. Do not use this tool to change app state or configuration; use
Requires Home Assistant OS or Supervised. | |||||||||||||||||||||||||||||||||
| ha_manage_appA | Manage Home Assistant apps (add-ons) or proxy an app API. For app inventory, status, and Supervisor metadata, call Use exactly one mode: lifecycle/store action, configuration fields,
Requires Home Assistant OS or Supervised. When ha-mcp itself runs as an
app it cannot update its own running slug; update ha-mcp from the Home
Assistant Apps UI. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. manage app apps addon add-on configure settings options port network boot watchdog auto_update supervisor ingress proxy websocket api rest esphome nodered node-red frigate mosquitto mqtt zigbee2mqtt zigbee z-wave zwave appdaemon hacs studio code server file editor terminal ssh samba grafana influxdb deconz motioneye compile validate upload deploy firmware ota flash yaml device logs flows events stats | |||||||||||||||||||||||||||||||||
| ha_list_floors_areasA | List floors sorted by level ascending, each with their assigned areas nested, plus areas without a floor. Use for location-based reasoning where floor-to-area relationships matter, such as "which rooms are on the ground floor" or operations scoped to a level. Floors with level=None sort alongside level 0 (ground floor). Areas without a floor assignment appear in unassigned_areas; areas whose floor_id points to a non-existent floor appear in orphaned_areas. When the ha_mcp_tools component's registries capability is available, both registries come from a single in-process snapshot, so this classification is always consistent. Without it (legacy path), the two registries are fetched via independent WebSocket calls and a registry change between reads may transiently misclassify an area. | |||||||||||||||||||||||||||||||||
| ha_remove_area_or_floorA | Remove a Home Assistant area or floor. Removing an area unassigns its entities and devices (the entities and devices themselves are not removed). Removing a floor unassigns its areas. May break automations referencing the removed area/floor. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_set_area_or_floorA | Create or update a Home Assistant area or floor. Pass kind='area' (with optional floor_id, picture, labels, temperature_entity_id, humidity_entity_id) or kind='floor' (with optional level). Provide name only to create a new entry; provide id to update an existing one. Cross-kind parameters (e.g., picture or labels under kind='floor') are rejected with VALIDATION_INVALID_PARAMETER. EXAMPLES: ha_set_area_or_floor(kind="area", name="Kitchen") ha_set_area_or_floor(kind="area", id="kitchen", floor_id="ground_floor") ha_set_area_or_floor(kind="area", id="kitchen", labels=["site_home"]) ha_set_area_or_floor(kind="area", id="kitchen", temperature_entity_id="sensor.kitchen_temp", humidity_entity_id=None) ha_set_area_or_floor(kind="floor", name="Basement", level=-1) ha_set_area_or_floor(kind="floor", id="ground_floor", level=0) If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_manage_pipelineA | Manage Home Assistant Assist pipelines. Use action='list' to discover pipeline IDs, action='get' to inspect one pipeline, action='create' or action='update' to write pipeline settings, action='set_preferred' to choose the preferred pipeline, and action='process' to run a sentence through Assist. action='process' sends the sentence straight to Assist's conversation agent, so a matched intent executes: it turns on the light rather than reporting that it would. Its result carries response_type ('action_done', 'query_answer' or 'error') and, on an error, error_code such as 'no_intent_match' — Assist declining a sentence is an answer, not a tool failure, so inspect those fields rather than expecting a raised error. Use ha_call_service to act on an entity directly; use this to test what Assist itself understands. When the built-in agent answers, a matching conversation trigger runs its automation: that agent checks its sentence triggers before it matches intents, so this is not limited to intents. Even with pipeline_id, the sentence goes to the agent directly. So with an agent other than the built-in one, neither sentence triggers nor prefer_local_intents apply — a full pipeline run is what adds those for other agents. EXAMPLES:
Non-nullable fields such as name, language, conversation_language, and conversation_engine must be omitted or non-empty. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_manage_blueprintsA | Manage Home Assistant blueprints — list, read, import, save, delete, or render a standalone config. One interface for the whole blueprint lifecycle in the DO NOT use this to create an automation or script FROM a blueprint —
that is To duplicate a blueprint,
CAVEATS: EXAMPLES:
RELATED TOOLS: If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. blueprint blueprints import delete remove unused substitute take-control list ha_get_blueprint ha_import_blueprint | |||||||||||||||||||||||||||||||||
| ha_report_issueA | Get diagnostics and a finished GitHub issue for a bug, agent feedback or a feature request. Use it before filing any GitHub issue about ha-mcp: a bug report
without this report is closed after 24 hours. Pass the report text in the call: the server combines it with the
diagnostics it collects into The response is LARGE; | |||||||||||||||||||||||||||||||||
| ha_config_get_calendar_eventsA | Get calendar events from a calendar entity within a time range. Returns each event's summary, start, end, description and location, plus the uid, recurrence_id and rrule when the calendar provides them (the edit and remove tools use uid and recurrence_id). To find calendar entities, use ha_search(domain_filter='calendar'). EXAMPLES:
| |||||||||||||||||||||||||||||||||
| ha_config_remove_calendar_eventA | Delete an event from a calendar. Deletes a calendar event via the WebSocket EXAMPLES:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_config_set_calendar_eventA | Create a new event in a calendar, or update an existing one. Creates a one-off event via the calendar.create_event service, or a
recurring series via the WebSocket When NOT to use:
Passing date-only values ( An update replaces the whole event rather than patching it, so
Not every calendar integration supports event creation; recurring events additionally require the integration to support recurrence (the built-in Local Calendar does). Update support is narrower still: Local Calendar implements it, while the core Google Calendar and CalDAV integrations do not. EXAMPLES:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_get_camera_imageA | Get a snapshot image from a Home Assistant camera entity. Fetches the current camera image and returns it directly for visual analysis (security checks, delivery verification, confirming a garage door actually closed), in the format Home Assistant serves (JPEG, PNG, or GIF), alongside a short text block stating the served snapshot's size and retrieval time in Home Assistant local time. Do not use it to inspect the camera's state or attributes — use ha_search or ha_get_state for those; it returns an image, not state. Use it when you need to see the current scene, and on high-resolution cameras pass width and height to reduce token usage. EXAMPLE: ha_get_camera_image(entity_id="camera.backyard", width=640, height=480) | |||||||||||||||||||||||||||||||||
| ha_config_get_categoryA | Get category info - list all categories for a scope or get a specific one by ID. Without a category_id: Lists all Home Assistant categories for the given scope. With a category_id: Returns configuration for that specific category. Categories are domain-scoped organizational groups for automations, scripts, scenes, and helpers. EXAMPLES:
Use ha_config_set_category() to create or update categories. Use ha_set_entity(categories={"automation": "category_id"}) to assign categories to entities. | |||||||||||||||||||||||||||||||||
| ha_config_remove_categoryA | Delete a Home Assistant category. Removes the category from the category registry for the given scope. This will also remove the category assignment from all entities in that scope. EXAMPLES:
Use ha_config_get_category() to find category IDs. WARNING: Deleting a category will remove it from all assigned entities. This action cannot be undone. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_config_set_categoryA | Create or update a Home Assistant category. Creates a new category if category_id is not provided, or updates an existing category if category_id is provided. Categories are domain-scoped organizational groups for automations, scripts, scenes, and helpers. Unlike labels (which are cross-domain), categories are specific to a single domain scope. EXAMPLES:
After creating a category, use ha_set_entity(categories={"automation": "category_id"}) to assign it. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_config_get_automationA | Get a Home Assistant automation's stored configuration.
EXAMPLES:
For comprehensive automation documentation, use ha_get_skill_guide. read inspect fetch view existing automation config triggers conditions actions get show detail | |||||||||||||||||||||||||||||||||
| ha_config_remove_automationA | Delete a Home Assistant automation permanently. A disabled automation is removed too. The returned EXAMPLES:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_config_set_automationA | Create or update a Home Assistant automation. MUST call ha_get_skill_guide OR refer to your locally installed skills first. Prefer native triggers/conditions/actions over templates in logic
positions; templates belong only in Consider a dedicated tool first: a state snapshot with no trigger -> ha_config_set_scene; a value derived from other entities -> ha_config_set_helper(helper_type='template'); a counter / timer / schedule / boolean -> ha_config_set_helper. MODES (pick one; each can also take
IDENTITY: omit entity_id and config['id'] to create with a generated ID.
Reusing an entity_id targets the same automation even if the alias
changes; to rename or replace it, read it first and pass its
config_hash — a changed alias without that hash is rejected before
writing. EXAMPLES:
TAKE CONTROL is one-way: later blueprint edits stop reaching the
automation; to change an input value, update 'use_blueprint.input'
instead. It does NOT free the blueprint — Home Assistant keeps counting
the converted automation as a user, so deleting that blueprint stays
refused until the automation is removed (an automation reload does not
clear it). The response names the blueprint in
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. create update modify edit automation triggers conditions actions new automation write save take control blueprint detach unlink standalone convert enable disable turn on off run trigger now | |||||||||||||||||||||||||||||||||
| ha_config_delete_dashboardA | Delete a storage-mode dashboard completely. WARNING: This deletes the dashboard and all its configuration; with auto-backup on, ha_manage_backup(scope='edits', action='restore') re-creates it. YAML-mode dashboards are defined in configuration.yaml and cannot be deleted via the API. HA internal IDs may differ from url_path (e.g. hyphens → underscores); the tool resolves either form to the actual registry ID before deletion. 'default' is an alias for 'lovelace'. EXAMPLES:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_config_get_dashboardA | Get Lovelace dashboards: list them, read one config, or search their cards. Not for a render alone: ha_get_dashboard_screenshot (screenshot beta feature) returns images without the config. Not for entity discovery: use ha_search. The parameters pick the mode:
Caveats: config_hash stays the same across reads of an unchanged config.
Searches stop at 200 matches ( EXAMPLES:
| |||||||||||||||||||||||||||||||||
| ha_config_set_dashboardA | Create or update a Home Assistant dashboard. MUST call ha_get_skill_guide OR refer to your locally installed skills first.
MODES (pick one):
Use ha_config_get_dashboard(entity_id=...) to get the path of any card, and ha_search / ha_get_overview to find entity IDs — never guess them. For visual re-checks after the write, use ha_get_dashboard_screenshot (when available) instead of re-sending config. title/icon/require_admin/show_in_sidebar can be updated in a metadata-only call or alongside a full config replacement; with python_transform or patch, update metadata in a separate call (combining it with patch is rejected). Strategy dashboards (config {"strategy": {...}}) cannot be converted to custom dashboards here; use "Take Control" in the Home Assistant UI. EXAMPLE: ha_config_set_dashboard(url_path="home-dashboard", title="Home Overview", config={"views": [{"title": "Home", "type": "sections", "sections": [{"title": "Climate", "cards": [{"type": "tile", "entity": "climate.living_room"}]}]}]}) This tool manages storage-mode dashboards only. YAML-mode dashboards (a
.yaml file registered under If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_config_list_helpersA | List Home Assistant helpers of a specific type with their configurations. Returns one page of helpers; For a helper renamed in the UI, id/original_name keep the storage values while entity_id/name reflect the current entity registry (entity_id is the identifier ha_config_set_helper resolves against, so prefer it over id for a renamed helper). entity_id/original_name are present only for storage-collection helpers matched in the entity registry — types with no backing entity (e.g. tag), and every record when the registry read degrades, carry only id/name (a warning flags the degraded case). Storage types list what HA's Listing flow types requires the ha_mcp_tools custom component (>= 1.1.0); without it, such a listing returns a COMPONENT_NOT_INSTALLED error. With helper_type="all", each record carries its own describe=True returns each field's name, type, required flag, options, default and (with helper_id) current value, or the menu_options a menu-based helper needs a menu_choice from. Call it before ha_config_set_helper to learn the config keys for a type. EXAMPLES:
For detailed helper documentation, use ha_get_skill_guide. list all helpers input_boolean input_number input_text counter timer input_datetime input_select | |||||||||||||||||||||||||||||||||
| ha_config_set_helperA | Create or update Home Assistant helpers: storage types, every helper flow HA lists, and config subentries. MUST call ha_get_skill_guide OR refer to your locally installed skills first.
SIMPLE types (pass FLOW types (pass CONFIG_SUBENTRY type (Config Subentry Flow API): pass Behavior:
EXAMPLES:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. create update new add helper input_boolean input_button input_number input_text input_datetime input_select counter timer schedule zone person tag template group utility_meter derivative min_max threshold integration statistics trend random filter tod generic_thermostat switch_as_x generic_hygrostat history_stats mold_indicator | |||||||||||||||||||||||||||||||||
| ha_config_get_sceneA | Get a scene's complete configuration, or list and search scenes without scene_id. Use ha_search for cross-domain discovery and dependency searches. For ordinary scene discovery, use this tool and pass a returned scene_id back to retrieve the complete entities dict and config_hash for editing (pass that hash to ha_config_set_scene for python_transform updates). Listing returns compact metadata. Integration-managed scenes have no editable storage config or scene_id. Partial content-search results explicitly report unread configs and are not exhaustive. EXAMPLES:
For detailed scene configuration help, use ha_get_skill_guide. | |||||||||||||||||||||||||||||||||
| ha_config_remove_sceneA | Delete a Home Assistant scene. EXAMPLE: ha_config_remove_scene("old_scene") Only scenes created via the Home Assistant UI can be deleted. Scenes defined in YAML configuration files (scenes.yaml or configuration.yaml) cannot be deleted through the API and return a 405 Method Not Allowed error; edit the configuration file directly instead. WARNING: Deleting a scene that is referenced by automations or scripts
(via If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_config_set_sceneA | Create or update a Home Assistant scene. MUST call ha_get_skill_guide OR refer to your locally installed skills first. Supports two modes: full config replacement ( WHEN TO USE:
WHEN NOT TO USE:
SCENE SHAPE: Automations use a list of actions; scenes capture a snapshot of states as a dict. EXAMPLE: ha_config_set_scene(scene_id="movie_night", config={ "name": "Movie Night", "entities": { "light.living_room": {"state": "on", "brightness": 50}, }, "icon": "mdi:movie", }) The top-level If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. create update modify edit scene entities snapshot activate apply turn on | |||||||||||||||||||||||||||||||||
| ha_config_get_scriptA | Get Home Assistant script configuration. Returns the complete configuration for a script, including sequence, mode, fields, and other settings. The returned The returned EXAMPLES:
For detailed script configuration help, use ha_get_skill_guide. read inspect fetch view existing script config sequence actions get show detail | |||||||||||||||||||||||||||||||||
| ha_config_remove_scriptA | Delete a Home Assistant script. EXAMPLE: ha_config_remove_script("old_script") Only scripts created via the Home Assistant UI can be deleted. Scripts defined in YAML configuration files (scripts.yaml or configuration.yaml) cannot be deleted through the API and return a 405 Method Not Allowed error; edit the configuration file directly instead. WARNING: Deleting a script that is used by automations may cause those automations to fail. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_config_set_scriptA | Create or update a Home Assistant script. MUST call ha_get_skill_guide OR refer to your locally installed skills first. Prefer native actions ( Scripts use 'sequence', NOT 'trigger' or 'action'; for trigger-based execution use ha_config_set_automation. MODES (pick one):
EXAMPLES:
TAKE CONTROL is one-way: later blueprint edits stop reaching the script; to change an input value, update 'use_blueprint.input' instead. It does NOT free the blueprint — Home Assistant keeps counting the converted script as a user, so deleting that blueprint stays refused until the script is removed. To preview the rendering without writing anything, use ha_manage_blueprints(action="substitute", domain="script", path=..., input=...). If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. create update modify edit script sequence actions new script write save take control blueprint detach unlink standalone convert run start stop execute | |||||||||||||||||||||||||||||||||
| ha_manage_energy_prefsA | Manage the Home Assistant Energy Dashboard preferences: grid / solar / battery / gas / water energy sources, device consumption sensors for electricity and water, and cost tariffs. WHEN NOT TO USE:
WHEN TO USE:
RELATED TOOLS: Use ha_get_history(source="statistics") with the returned statistic IDs for consumption, totals, and trends. Metadata comes directly from the running Core, including stored and display units. CAVEATS:
EXAMPLES:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. read get inspect energy dashboard preferences prefs electricity price prices pricing tariff tariffs rate rates cost costs kwh peak off-peak offpeak contract utility bill grid solar battery gas water consumption number_energy_price entity_energy_price stat_energy_from | |||||||||||||||||||||||||||||||||
| ha_get_entityA | Get entity registry information for one or more entities. Returns detailed entity registry metadata: area, custom name/icon, original name, disabled_by/hidden_by (with enabled/hidden shorthands), aliases (a null entry = the entity's own name), labels, categories, device_class override, per-domain options, platform, device_id, config_entry_id and unique_id. RESOLVER MODE:
Pass unique_id (instead of entity_id) to resolve a stable integration
unique_id to its entity_id(s). Since the registry's unique key is
(domain, platform, unique_id), the same unique_id can match multiple
platforms — all matches are returned in entity_entries with a When config_entry_id is non-null — e.g. for UI-created template / group /
utility_meter / derivative helpers — pass it to
Resolved-name enrichment (present only when the ha_mcp_tools component
advertises it; otherwise these keys are absent): RELATED TOOLS: ha_set_entity() to modify these properties; ha_get_state() for current state/attributes; ha_search() to find entities. EXAMPLES:
get entity state attributes details single specific entity_id | |||||||||||||||||||||||||||||||||
| ha_remove_entityA | Remove one or more entities from the Home Assistant entity registry. Permanently removes the entity registration; the entity will no longer appear in the UI or be available to automations. Use only for orphaned or stale entity entries: if the underlying device, integration or stored helper is still there, the entity may be re-added on the next HA restart or reload; for a stored helper's entity a single-id removal names the tool that removes the helper. Added again, it gets back its registry settings while its config entry exists, and for 30 days after that entry, or an entity without one, was removed. For most use cases, consider disabling instead: ha_set_entity(entity_id="sensor.old", enabled=False). BULK MODE: Pass a list of entity IDs to remove up to 100 at once — handy for clearing the restored=true orphans an integration leaves behind after its filters change. Removals run sequentially and return: {removed: [...], skipped: [...], errors: [{entity_id, code, message}]} where skipped = ids already absent (not-found is idempotent). A lost connection stops the run; not_attempted lists the ids never sent (the failing one too if it never left), safe to retry. Only single-id removal is auto-backed-up. EXAMPLES:
Use ha_search / ha_get_entity to verify an entity before removing it. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_set_entityA | Update entity properties in the entity registry. Allows modifying entity metadata such as area assignment, display name, icon, "Show As" device class override, per-domain registry options, enabled/disabled state, visibility, aliases, labels, voice assistant exposure, and entity_id rename in a single call. BULK OPERATIONS: When entity_id is a list, only labels, expose_to, and categories parameters are supported. Other parameters (area_id, name, use_device_name, icon, device_class, options, enabled, hidden, aliases, use_entity_name_alias, new_entity_id, new_device_name) require single entity. SHOW AS / DEVICE CLASS: a device_class change applies instantly, no reload needed. REGISTRY OPTIONS: multi-domain options are sent as separate registry updates because HA's WS schema requires options_domain + options to be paired one domain at a time. ENTITY ID RENAME: Voice exposure settings are preserved automatically. WARNING: Renaming an entity_id does NOT update references in automations, scripts, templates, or dashboards. All consumers of the old entity_id must be updated manually — HA does not propagate the rename automatically. Rename limitations:
DEVICE RENAME: new_device_name can be combined with new_entity_id to rename both in one call. The device is looked up automatically. Use ha_search() or ha_get_device() to find entity IDs. Use ha_config_get_label() to find available label IDs. EXAMPLES:
ENABLED/DISABLED WARNING: A disabled entity will NOT appear in state queries, dashboards, or automations until re-enabled AND the integration is reloaded. This is NOT the same as "turning off" an entity. For automations and scripts, enabled=False is blocked. For automations, use ha_config_set_automation(entity_id="automation.xxx", enabled=False) (or enabled=True to re-enable). For scripts, ha_config_set_script(script_id="script.xxx", run="stop") only stops a currently running execution; it does not disable the script. Home Assistant has no script runtime enable/disable service. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_config_list_groupsA | List Home Assistant entity groups with their member entities. Returns one page of old-style groups created via the group.set service
or YAML configuration (platform-specific groups such as light or cover
groups are separate entities); EXAMPLE: ha_config_list_groups(offset=100) | |||||||||||||||||||||||||||||||||
| ha_config_remove_groupA | Remove a service-based Home Assistant entity group via the group.remove service. When NOT to use: for groups created through When to use: removing groups created with EXAMPLES:
Use ha_config_list_groups() to find existing groups. WARNING:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_config_set_groupA | Create or update a service-based Home Assistant entity group via the group.set service. When NOT to use: for typical "combine these entities into one controllable group"
requests, prefer When to use: compatibility with existing groups already configured via group.set
or YAML, or the rare case where entity-registry membership is explicitly unwanted.
Groups created here are only removable via Core creates group.<object_id> when it does not exist (members from entities or add_entities) and updates it otherwise. entities, add_entities, and remove_entities are mutually exclusive. EXAMPLES:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_get_hacs_infoA | Get HACS (Home Assistant Community Store) data — search the store or fetch repository details. On Home Assistant 2026.11+ HACS is the built-in Marketplace; the tool
uses whichever the instance has. Use DASHBOARD TIP: Examples:
Caveats: | |||||||||||||||||||||||||||||||||
| ha_manage_hacsA | Manage HACS (Home Assistant Community Store) — install/update, remove, add custom repositories, or refresh repository information. On Home Assistant 2026.11+ HACS is the built-in Marketplace; the tool
uses whichever the instance has. This tool performs writes; to search the
store or read repository details use Examples:
Caveats: Installing an integration usually needs a Home Assistant restart to
activate; new Lovelace cards need a browser cache clear. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_get_historyA | Get historical data from Home Assistant's recorder. WHEN NOT TO USE: For current values, use ha_get_state. To inspect Energy Dashboard preferences and configured statistics, use ha_manage_energy_prefs(mode="get", include_statistics=True). WHEN TO USE: Use source="history" (default) to troubleshoot why a value changed, check event sequences, or analyze recent patterns. Use summary=True when the question needs a count or a duration ("was it ever unavailable?") rather than the rows. Use source="statistics" for long-term trends and period averages. CAVEATS: History rows rename Core's compact keys once: s -> state, a -> attributes, lu -> last_updated, lc -> last_changed. History event times are ISO strings in HA's timezone (UTC if unavailable). When Core omits lc, last_changed falls back to last_updated; this may not be the actual state-change time with significant_changes_only (default) or a window-start snapshot. Attributes and unknown fields pass through unchanged. Statistics timestamps use Unix milliseconds. Minimal history may omit attributes. No duplicate compact aliases are added. include_schema=True retains core_contract even when fields selects other data keys. Output units come from Core recorder metadata and reflect its display-unit conversion; unresolved units include a reason. statistics_metadata preserves Core's native fields. All data is fetched from HA before slicing; limit/offset are client-side. With multiple entity_ids, offset must be 0 — use a single entity_id for offset > 0. Use has_more and next_offset from the response to paginate. With source="history", summary=True does not combine with offset > 0. Administrators can optionally enable recorder workload guardrails in Advanced settings. When enabled, oversized entity/time workloads are rejected before the recorder query is issued; narrow the time range or entity list to stay within the budget. Calendar statistics may first read HA's configured timezone so the estimate follows local calendar boundaries. EXAMPLES:
| |||||||||||||||||||||||||||||||||
| ha_get_integrationA | Get integration (config entry) information with pagination. Without an entry_id: Lists all configured integrations with optional filters. With an entry_id: Returns detailed information including full options/configuration. WHEN NOT TO USE:
EXAMPLES:
OPTIONS: with the component, Each entry carries | |||||||||||||||||||||||||||||||||
| ha_remove_helpers_integrationsA | Remove a Home Assistant helper or integration config entry. Unifies three backend removal mechanisms — simple-helper websocket delete, config-entry delete, and config-subentry delete — behind one entry point; helper_type picks the path, or the entity registry does when an entity_id comes without one. WHEN NOT TO USE:
ROUTING:
A target that cannot be removed raises a structured error rather than returning silent success: ENTITY_NOT_FOUND when the entity_id is absent from both the state machine and the entity registry, or for a bare helper_id no stored helper has (a bare helper_id on a FLOW target also raises it — FLOW resolution needs a full entity_id); RESOURCE_NOT_FOUND when it exists but is not storage- or registry-managed (a YAML-configured helper, or an entity with a state but no registry entry), for a config entry the backend reports as 404, or for a missing config subentry. Calling N times gives the same response. Transient connectivity failures raise their own codes (WEBSOCKET_DISCONNECTED, CONNECTION_FAILED) so retry logic can branch separately. EXAMPLES:
WARNING: Removing a helper or integration that is referenced by automations, scripts, or other integrations may cause those to fail. Use ha_search() / ha_get_integration() to verify before removal. ha_manage_backup(scope="edits", action="restore") recreates removed FLOW helpers whose options could be snapshotted, and config subentries. It cannot recreate custom helper integrations (their options are withheld) or otp (no stored options); re-add those yourself, otp through the user in the HA UI. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_set_integrationA | Manage an integration (config entry): enable/disable, add, update options, reconfigure, or send its own commands. Modes (pick one):
Flows, one step per call: a call answers the step the flow is at and returns Home Assistant's next answer. A form comes back with its fields (type, default, current value, Home Assistant's help text) and flow_id; a menu with menu_options. Answer with flow_id and config (a form) or menu_choice (a menu); flow_id alone returns the step again, and flow_id with abort=True ends the flow. Without flow_id a new flow starts: its first form gets config, and without config the call returns that first step. A form Home Assistant rejects is an error with errors and error_text (Core's text), and the flow stays open to correct it. A flow stays open until Home Assistant finishes it or you abort it; while a setup flow is open, Home Assistant refuses another one for the same device as already_in_progress. WHEN NOT TO USE:
Use ha_get_integration() to find entry IDs, and ha_get_integration(entry_id=..., include_schema=True) to inspect the options fields. Its supports_reconfigure field tells you whether an entry qualifies for reconfigure=True, and ha_get_integration(entry_id=..., include_ws_commands=True) lists the commands ws_command accepts with their schemas. Caveats: adding an integration runs its config flow exactly as the HA UI would (may pair devices, scan the network, create entities). Flows requiring a browser step (OAuth) are refused at that step and aborted. A progress step (Home Assistant working in the background) is waited out for up to 120 s; after that the error carries flow_id to ask again. When Home Assistant does not answer a submit or a progress poll (or, on reconfigure, answers with any 5xx), the error carries status applied_but_unverified: the entry may exist or the change may be saved, so check it before retrying. An aborted flow returns Core's own text next to the key (reason_text). Reconfigure edits the settings a live integration connects with: a wrong host or credential takes it offline, and there is no automatic rollback. A finished reconfigure waits for the reload Home Assistant runs and reports the entry's state as entry_state: status applied_and_verified once it is loaded, applied_but_unverified otherwise. EXAMPLES:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. integration config entry enable disable add options reconfigure log level debug logging | |||||||||||||||||||||||||||||||||
| ha_config_get_labelA | Get label info - list all labels or get a specific one by ID. Without a label_id: Lists all Home Assistant labels with their configurations. With a label_id: Returns configuration for that specific label. EXAMPLES:
Use ha_config_set_label() to create or update labels. Use ha_set_entity(labels=["label1", "label2"]) to assign labels to entities, ha_set_device(labels=[...]) for devices, or ha_set_area_or_floor(kind="area", labels=[...]) for areas. | |||||||||||||||||||||||||||||||||
| ha_config_remove_labelA | Delete a Home Assistant label. Removes the label from the label registry. This will also remove the label from all entities, devices, and areas that have it assigned. EXAMPLES:
Use ha_config_get_label() to find label IDs. WARNING: Deleting a label will remove it from all assigned entities. This action cannot be undone. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_config_set_labelA | Create or update a Home Assistant label. Creates a new label if label_id is not provided, or updates an existing label if label_id is provided. Labels are a cross-domain tagging system for entities, devices, and areas. EXAMPLES:
After creating a label, use ha_set_entity(labels=["label_id"]) to assign it to entities, ha_set_device(labels=["label_id"]) for devices, or ha_set_area_or_floor(kind="area", labels=["label_id"]) for areas (replaces the area's set). If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_get_logsA | Get Home Assistant logs from various sources. Prefer source='system' for triage: it returns HA's own deduplicated system_log entries with counts, first_occurred and the full exception traceback, and its counts run since each error first occurred. error_log with structured=True counts only what is inside the fetched window (reported as window_start/window_end; every install reads a capped window) and drops tracebacks; structured=False returns the raw records instead, so it covers what falls outside system_log's WARNING+ in-memory buffer. Use structured=True for the per-component rollup; in structured mode limit/order do not apply: issues are ranked by count, then severity, then recency, over a fixed deep window. Raw-text sources (error_log, supervisor, system_service) read a bounded window per call, so level/search filter and limit slice within that window only; window_lines reports the size requested. Logbook responses carry has_more plus a pagination_hint; error_log and fault_log carry has_more with a next_offset to pass back while it stays true. | |||||||||||||||||||||||||||||||||
| ha_manage_radioA | Manage Home Assistant radios — Z-Wave, Zigbee, Matter, and Thread. For node diagnostics and network summaries prefer ha_get_device / ha_get_system_health, which mirror 'diagnostics' and 'network_status'. This tool also exposes active 'ping' probes and parameter reads. Z-Wave 'get_config_params' lists cached configuration values/metadata; 'get_config_param' reads one from the cache or explicitly from the device. Neither enables or creates entities. Write actions perform inclusion/commissioning, removal, healing, reconfiguration, firmware updates and credential provisioning. Caveats: long-running actions (inclusion, rebuild routes, firmware) start the operation and return immediately with long_running=true; completion happens out-of-band. Interactive Z-Wave S2 secure inclusion (read-the- PIN pairing) is not scriptable — use SmartStart/QR provisioning here or the HA UI. HA administrator access is required for parameter reads. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_get_deviceA | Get device information with pagination, including Zigbee (ZHA/Z2M) and Z-Wave JS devices. Without device_id/entity_id: Lists devices with optional filters and pagination. With device_id or entity_id: Returns full detail for that specific device. List devices (paginated):
Single device lookup (always full detail):
Zigbee: integration="zha" or "zigbee2mqtt". Returns ieee_address, radio metrics. Z-Wave: integration="zwave_js". Returns node_id, node_status. Matter: integration="matter". Returns node_diagnostics (network type, reachability, IPs, fabrics). For management use ha_manage_radio. | |||||||||||||||||||||||||||||||||
| ha_remove_deviceA | Remove an orphaned device from the Home Assistant device registry. WARNING: This removes the device entry from the registry.
Works only when the integration supports removing devices. EXAMPLES:
NOTE: For most use cases, consider disabling the device instead: ha_set_device(device_id="abc123", disabled_by="user") If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_set_deviceA | Update device properties such as name, area, disabled state, or labels. IMPORTANT: Renaming a device does NOT rename its entities! Device and entity names are independent. To rename entities, use ha_set_entity(new_entity_id=...). Common workflow for full rename:
EXAMPLES:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_config_delete_dashboard_resourceA | Delete a dashboard resource. Removes a resource from Home Assistant. The resource will no longer be loaded on dashboards. WARNING: Deleting a resource used by custom cards in your dashboards will cause those cards to fail to load. EXAMPLES: ha_config_delete_dashboard_resource(resource_id="abc123") Note: Use ha_config_list_dashboard_resources() to find resource IDs before deleting. Ensure no dashboards depend on the resource. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_config_list_dashboard_resourcesA | List Lovelace dashboard resources (custom cards, themes, CSS/JS). Returns one page of registered resources; EXAMPLES:
Home Assistant 2026.6+ exposes resource management in the UI by default; API access works regardless of UI availability. | |||||||||||||||||||||||||||||||||
| ha_config_set_dashboard_resourceA | Create or update a dashboard resource (inline code or external URL). Provide exactly one of:
EXAMPLES:
Inline writes return the stored content's config_hash. After adding a resource, a browser cache clear or hard refresh (Ctrl+Shift+R) is needed to load it. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_get_overviewA | Get AI-friendly system overview with intelligent categorization. Returns comprehensive system information at the requested detail level, including Home Assistant base_url, version, location, timezone, entity overview, and active persistent notifications (if any). Use 'minimal' (default) for most queries. Domain counts and states_summary are always complete regardless of entity pagination. Requests whose fields= are composed only of system_info, notification, repair, or server metadata fields skip the unrelated state, service, and registry reads. Do not use this tool to inspect a known entity or a narrow set of entities. Use ha_get_state for one entity, ha_get_entity for registry metadata, or ha_search with a domain or area filter. An unprojected overview collects system-wide state, service, and registry data and can be expensive on large Home Assistant installations. When the ha-mcp settings-UI sidecar is running (stdio mode, e.g. Claude
Desktop / Claude Code) the response carries The response also carries
| |||||||||||||||||||||||||||||||||
| ha_get_stateA | Get current status, state, and attributes of one or more entities (lights, switches, sensors, climate, covers, locks, fans, etc.). Pass a string entity_id for one entity, or a list (max 100, duplicates deduplicated) for several, fetched in parallel. A bulk call returns success=True if at least one state was retrieved; check 'error_count' for failed lookups.
EXAMPLES:
get current state value single entity check status bulk multiple states which lights | |||||||||||||||||||||||||||||||||
| ha_searchB | Search for entities (lights, sensors, switches, climate, etc.) by name, domain, or area — AND inside automation/script/scene/helper/dashboard configurations — in one call. find entities configs lookup discover search lights sensors switches covers climate fans media_player binary_sensor device_tracker person weather automation script helper input_boolean input_number automations scripts scenes helpers dashboards | |||||||||||||||||||||||||||||||||
| ha_bulk_controlA | Manage explicit operations or one deterministic structural bulk action. When NOT to use: use Operations mode ( Selector mode ( If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_call_eventA | Execute a custom event on the Home Assistant event bus. When NOT to use: for controlling entities (lights, switches, climate) — use ha_call_service instead. To run an automation now, use ha_config_set_automation(entity_id=..., run_actions=True). Use this to publish custom event types consumed by event-triggered automations, Node-RED flows, or custom integrations that subscribe to specific event types. Caveats: Events are fire-and-forget; a successful dispatch reports the bus accepted the event and how many listeners were registered for it, not that any of them acted. A timeout means dispatch is unconfirmed. listener_count covers the exact event type; wildcard_listener_count covers match-all listeners (the recorder is one, and it only stores the event). The counts come from the component's dispatch reply when it serves the fire, otherwise from a GET /api/events lookup taken before dispatch; a route that cannot report them omits both fields. The response carries the event's context_id (and context) when Home Assistant reports it. An automation triggered by this event records that id as the parent_id of its run's context, so looking up that automation trace proves whether a listener acted — which the counts cannot show, because an event trigger that filters on event_data still registers as a listener when the payload does not match. Events fire in-process through the ha_mcp_tools component when it is installed, otherwise over Home Assistant's own WebSocket fire_event command; both carry the event type in the message body, so any type Core accepts fires as written and Core's rejection comes back as the error text (for example its 64-character event-type limit). state_changed alone keeps the REST route, because only that route rebuilds its old_state/new_state payloads into State objects; there event_type must be a plain name with no / \ ? # or % characters. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_call_serviceA | Call any Home Assistant service or one-shot WebSocket command: the catch-all escape hatch. When NOT to use: a dedicated tool that covers the job. It validates the request, reports the outcome in its own terms, and stays available where a security policy gates this tool. For example: turn an automation on or off or run it now with ha_config_set_automation (enabled / run_actions); start or stop a script with ha_config_set_script (run); activate a scene with ha_config_set_scene (activate); manage apps (add-ons) with ha_manage_app; handle updates and Repairs issues with ha_manage_updates; set an integration's log level with ha_set_integration (log_level). When to use: a service no dedicated tool covers. Services follow the pattern domain.service (e.g., light.turn_on, climate.set_temperature); ha_list_services lists them with their fields. EXAMPLES:
Result compaction (default ON): For detailed service documentation, use ha_get_skill_guide. WebSocket command escape hatch (advanced):
Some Home Assistant operations are WebSocket-only commands, not
registered services. Pass Unavailable in Read Only Mode, including read-like services and WebSocket commands. Use dedicated read tools while that mode is enabled. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_get_operation_statusA | Get the status of one or more device operations with real-time WebSocket verification. Bulk checks poll all operations concurrently under one shared timeout_seconds window and report per-item failures inside detailed_results instead of aborting the batch. Use this to track the operation_ids that ha_bulk_control returns. For current entity states, use ha_get_state instead. | |||||||||||||||||||||||||||||||||
| ha_list_servicesA | List available Home Assistant services with optional pagination and detail control. Discovers services/actions that can be called via ha_call_service. EXAMPLES:
| |||||||||||||||||||||||||||||||||
| ha_get_system_healthA | Get Home Assistant system health, including Zigbee (ZHA), Z-Wave JS, and per-integration diagnostics dumps. Returns health check results from integrations, system resources, and
connectivity; available information varies by installation type and
loaded integrations. Optional sections are selected with The result may include EXAMPLES:
| |||||||||||||||||||||||||||||||||
| ha_reload_coreA | Execute a Home Assistant configuration reload without a full restart. Reloads specific configuration components so changes take effect without restarting Home Assistant — much faster than a full restart. Use it after editing automation/script YAML, adding YAML helpers, or changing customize.yaml or themes. EXAMPLES:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_restartA | Execute a Home Assistant restart. WARNING: restarts the entire Home Assistant instance; all automations are unavailable during the restart, which typically takes 1-5 minutes. Config is validated automatically before the restart proceeds (to pre-check, call ha_get_system_health(include="config_check")). For configuration changes, consider ha_reload_core() instead, which reloads specific components without a full restart. When this server runs inside Home Assistant (embedded), it replies before the restart starts and is unreachable until Home Assistant is back; with safe_mode it stays down until Home Assistant is next restarted normally, because it is itself a custom integration. EXAMPLE: ha_restart(confirm=True) If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_manage_themeA | Manage Home Assistant frontend themes. When NOT to use: themes are YAML files - Home Assistant has no API to create or edit them. Installing community themes goes through HACS (the Marketplace on 2026.11+, both via ha_manage_hacs); editing custom theme files goes through ha_config_set_yaml (beta, edits themes/.yaml keyed by theme name and attempts an automatic theme reload). When to use: action='list' discovers installed theme names and the current defaults; action='set' selects the backend default theme (optionally per light/dark mode). SCREENSHOT-ENGINE ACTIONS (per-user, not the backend default): Taking a dashboard screenshot makes the Puppet engine write the saved theme of the Home Assistant user its token belongs to, which also flips that user's live web and mobile sessions. The screenshot tools are read-only and only report this; use action='set_engine_theme' with the value quoted in their warning to put it back, and action='get_engine_theme' to inspect it. These act on that engine account's per-user profile via frontend/set_user_data, which is a different layer from the backend default that action='set' changes. Giving the engine its own dedicated user and token avoids the issue entirely. Caveats: action='set' changes the backend-selected default only - users who explicitly picked a theme in their profile keep their choice. Theme names are validated by Home Assistant at call time. EXAMPLES:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_get_todoA | Get todo lists or items - list all todo lists or get items from a specific list. Without an entity_id: lists every entity in the 'todo' domain (shopping lists and other todo-type integrations) with entity_id, friendly_name and state (number of incomplete items or current status). With an entity_id: returns that list's items as Home Assistant reports them — uid, summary, status, and description, due and completed where set. EXAMPLES:
| |||||||||||||||||||||||||||||||||
| ha_remove_todo_itemA | Remove items from a Home Assistant todo list. Give EXAMPLES:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_set_todo_itemA | Create, update or reorder a todo item in Home Assistant. Without EXAMPLES:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_get_automation_tracesA | Get execution traces for automations and scripts to debug issues. Traces show what triggered a run, which conditions passed or failed, which actions executed (for 'choose', which branch was taken), any errors, and variable values during execution. Home Assistant keeps only the most recent runs of each automation or script (its stored_traces setting), so older runs are not available. The 'state' field shows 'stopped' (completed), 'running', or an error state. USAGE MODES:
| |||||||||||||||||||||||||||||||||
| ha_manage_updatesA | Manage Home Assistant updates (list, details, install, skip) and Repairs issues (ignore). Covers Core, OS, supervisor, apps (add-ons), device firmware, and HACS update entities, plus the Repairs issues in Settings > System > Repairs. Repairs are listed by ha_get_overview (not here); pass their domain and issue_id to 'ignore_repair' / 'unignore_repair'. In Read Only Mode the read actions ('list', 'get') stay available; write actions are blocked. 'install' blocks until each update finishes (minutes). One that outlasts the request timeout ends the call with a connection timeout while it keeps running, and a Core update restarts Home Assistant; neither means failure, but later batch targets were not started. Confirm per entity with action='get'; finished updates drop out of 'list', which also returns ha_mcp_update — this MCP server's own update status {current, latest, update_available}, so a newer ha-mcp release can be flagged. EXAMPLES:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. update updates install skip firmware core os repair repairs issue ignore dismiss unignore | |||||||||||||||||||||||||||||||||
| ha_eval_templateA | Execute a Jinja2 template render, or an automation condition check, in Home Assistant. Renders templates with Home Assistant's template engine (all states, functions and filters available), or checks a condition block the way an automation would and returns true/false. When to use: any one-shot answer DERIVED from current HA state (an average across sensors, a count of entities matching a condition, a rendered message with live values), and testing a template or condition before embedding it in an automation. One render beats fetching N states and doing the math yourself. When NOT to use: a plain single-entity value is ha_get_state /
ha_search. Templates in automation Results: a render that works but hits something suspect (an undefined
variable, a missing attribute) still returns its result with the
messages in EXAMPLES:
| |||||||||||||||||||||||||||||||||
| ha_get_entity_exposureA | Get entity exposure settings - list all or get settings for a specific entity. Without an entity_id: lists the entities that have explicit exposure
settings for voice assistants (Alexa, Google Assistant, Assist) as
With an entity_id: returns EXAMPLES:
When the ha_mcp_tools component advertises the exposure capability, each record is additively enriched with the entity's name/area so no second ha_search is needed to identify it: friendly_name, domain, area, floor, and labels (plus state for entities that have one) on a single-entity lookup, and a parallel entity_info map keyed by entity_id when listing. These fields are absent when the component is unavailable. | |||||||||||||||||||||||||||||||||
| ha_get_zoneA | Get zone information - list all zones or get details for a specific one. Without a zone_id: Lists all Home Assistant zones with their coordinates and radius. With a zone_id: Returns detailed configuration for a specific zone. EXAMPLES:
Zones outside the zone storage, the home zone (from the general
settings) and YAML zones, are listed with | |||||||||||||||||||||||||||||||||
| ha_remove_zoneA | Remove a Home Assistant zone. EXAMPLES:
WARNING: Removing a zone used in automations may cause those automations to fail. Use ha_get_zone() to find the zone_id for the zone you want to remove. NOTE: Zones defined in YAML, and the home zone, cannot be removed here. If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_set_zoneA | Create or update a Home Assistant zone. Omit zone_id to create a new zone (name, latitude, longitude required). Provide zone_id to update an existing zone (only specified fields change). Zones defined in YAML, and the home zone, cannot be changed here. EXAMPLES:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_manage_backupA | Manage Home Assistant backups — both full HA snapshots AND per-edit auto-backups. Pick the scope first, then the action. Wrong scope routes through the wrong code path:
When to use which scope:
A snapshot backup is the user's call: before a change that cannot be undone, you may ask the user whether they want one first; make it only when they say so. A full backup is large, and an unrequested one can push an older backup out of retention.
Human-managed backup controls:
Flow-helper filters: Examples:
If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop. | |||||||||||||||||||||||||||||||||
| ha_get_skill_guideA | Get the bundled Home Assistant best-practices skill. The skill is currently not available on this server: the skills directory is missing or its SKILL.md failed to parse. Calls return an error; ask the operator to verify the skills-vendor submodule is initialized. Use BEFORE: creating or editing automations, scripts, scenes, helpers, or dashboards; writing triggers, conditions, actions, wait_template, or service calls; renaming entities or migrating device_id to entity_id; calling ha_config_set_automation, ha_config_set_script, ha_config_set_helper, ha_config_set_dashboard, or ha_set_entity. Replaces (and supersedes) the prior tools: ha_list_resources, ha_read_resource, and ha_get_skill_home_assistant_best_practices. If you were going to call any of those, call this instead. best practices skill skills guide guides reference references documentation docs help tutorial automation script scene helper dashboard ha_list_resources ha_read_resource list_resources read_resource ha_get_skill_home_assistant_best_practices ha_get_skill_home_assistant home_assistant_best_practices |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 77 tools
Most tools target a distinct resource/action, and descriptions cross-reference alternatives. However, several boundaries are still fuzzy in practice: state vs. registry vs. search, ha_bulk_control vs. ha_call_service, helper groups vs. service groups, and read vs. manage HACS all require careful reading to avoid misselection.
All names use snake_case with a consistent ha_ prefix and mostly verb_noun/resource_action structure. The main deviations are parallel families such as ha_config_set_* vs. ha_set_* for similar resources and ha_manage_* vs. ha_get_*/ha_set_*.
77 tools far exceeds a well-scoped surface (typically 3-15) and is an extreme mismatch even for a broad platform. Home Assistant is wide, but the surface is heavily fragmented into many specialized tools rather than consolidated around core operations.
Coverage spans entities, devices, areas/floors, automations, scripts, scenes, helpers, dashboards/resources, calendars, todo, zones, labels/categories, integrations, apps, HACS, backups, updates/repairs, logs, services, history, traces, radio, energy, and pipelines. No obvious dead ends remain, and ha_call_service fills service-level gaps.