Skip to main content
Glama
homeassistant-ai

Home Assistant MCP Server

Official

Search

ha_search
Read-onlyIdempotent

Search for Home Assistant entities by name, domain, or area, and simultaneously find references inside automations, scripts, scenes, helpers, and dashboards in a single call.

Instructions

Search for entities (lights, sensors, switches, climate, etc.) by name, domain, or area — AND inside automation/script/scene/helper/dashboard configurations — in one call.

Two surfaces run in parallel and return tagged results:

  • entities: entity-registry matches (entity_id, friendly name, area). Filter with domain_filter/area_filter/state_filter; omit query to enumerate a domain, area, or state.

  • automations / scripts / scenes / helpers / dashboards: matches inside config definitions — triggers, actions, sequences, scene entity-sets, helper bodies, dashboard cards. Driven by query; narrow with search_types.

Use this whenever you need to find something in HA without deciding entity-name vs config-body search up front.

When NOT to use:

  • To read a known entity_id's state: use ha_get_state (cheaper).

  • To inspect one automation/script/scene config by id: use the matching ha_config_get_*.

  • To list installed add-ons: use ha_get_addon.

Config-body search is skipped when domain_filter/area_filter/ state_filter signal entity-only intent (keeping name lookups off the expensive backend); a warnings[] entry names the skip. Pass search_types=[...] to force config search.

Caveats:

  • partial: True means results are NOT exhaustive — a surface raised, or the config-body branch lost data (per-id time budget exhausted, an individual fetch failed, or a helper-type list fetch failed). Empty buckets with partial: True mean "search failed", not "no results". The cause is in partial_reason, also mirrored into warnings[] with an "incomplete results: " prefix. Do not treat a partial response as complete.

  • count is items in this response (post-pagination), not corpus totals — use entity_total_matches + config_total_matches.

  • limit/offset apply per-surface. Flat has_more/next_offset page the next call (iterate offset = next_offset); per-surface entity_*/config_* variants show which surface still has results.

For parameters, schema, and worked examples, see ha_get_skill_guide.

Examples: - List sensors in an area: ha_search(domain_filter="sensor", area_filter="Living Room") - Find a light by name: ha_search("kitchen", domain_filter="light") - Which automations use an entity: ha_search("light.bed_light") - Scenes touching a light: ha_search("light.kitchen", search_types=["scene"]) - Narrow the response to the entity bucket: ha_search("kitchen", fields=["entities"]) - All unavailable entities: ha_search(state_filter="unavailable")

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

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum results per surface (entities, configs). Default: 10.
queryNoWhat to search for (entity name fragment, free-text config term, entity_id). Searches BOTH the entity registry (entity_ids, friendly names, areas) AND configuration bodies (automation triggers/actions, script sequences, scene contents, helper bodies, dashboard cards) in one call. Use this for any find-something-in-HA question — entity OR config. Omit `query` to enumerate by `domain_filter`, `area_filter`, and/or `state_filter` alone (registry-listing mode); configuration-body search is skipped in that mode because there is no term to match against.
fieldsNoProject the response to the named top-level keys (e.g. ["entities", "automations"]); None = full response. Diagnostic / pagination keys are always retained so projection cannot hide partial / error state. Distinct from `result_fields` (which projects each entity record's keys). Available keys: success, query, entities, automations, scripts, scenes, helpers, dashboards, search_types, search_type, entity_total_matches, config_total_matches, count, offset, limit, has_more, next_offset, entity_has_more, entity_next_offset, config_has_more, config_next_offset, by_domain, state_filter_note, area_names, domain_filter, area_filter, message, warnings, errors, partial, partial_reason.
offsetNoNumber of results to skip for pagination.
area_filterNoNarrow entity-registry results to an area (id or name). Does not affect configuration search.
exact_matchNoExact substring matching (default). Set False for fuzzy matching when the query may have typos.
search_typesNoConfiguration types to include in body search: 'automation', 'script', 'scene', 'helper', 'dashboard'. Default = automation+script+scene+helper. Pass as list or JSON-array string.
state_filterNoFilter entity-registry results to a specific state (e.g. "on", "off", "unavailable"). Case-insensitive. Can be used standalone (no query/domain/area) to enumerate every entity in that state; entity_total_matches reflects the filtered count.
domain_filterNoNarrow entity-registry results to a single domain (e.g. 'light', 'sensor'). Does not affect configuration search.
result_fieldsNoProject each entity-registry record to only the specified keys (e.g. ["entity_id", "state"]). None = full records. Base keys: entity_id, friendly_name, domain, state, score, match_type. Opt-in enrichment keys (joined on request): area, floor, labels, aliases. An unknown key is rejected.
include_configNoInclude full configuration bodies in body-search results. Default: False (summary only).
include_hiddenNoInclude hidden entities in registry results (with a score penalty so they sort below visible matches). Set False to exclude entirely.
group_by_domainNoGroup entity-registry results by domain (entity-side only). Adds a `by_domain` map to the response.
per_domain_limitNoWhen `group_by_domain=True`, cap entity-registry results per domain to this number. Ignored otherwise.
config_time_budgetNoPer-call override for the per-id config-fetch wall-clock budget (seconds). Replaces the per-type HAMCP_*_CONFIG_TIME_BUDGET defaults for the automation, script, AND scene branches when their bulk-fetch falls through to per-id Attempt-C. Use when a `partial: True` response names time-budget skipping. Stateless per-call: one caller raising the budget doesn't affect others. None = use the per-type env defaults.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate readOnly and idempotent. Description adds critical behavioral details: partial results meaning, count vs total_matches, pagination mechanics, and warnings about incomplete results. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but well-structured with headings and examples. Front-loaded with purpose. Some redundancy (keyword list at end) but overall efficient for the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (15 parameters, two search surfaces, output schema exists), the description is exhaustive. Covers caveats, pagination, partial results, and usage patterns, leaving no critical gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% but description adds rich context, examples for each parameter (e.g., query usage patterns, fields projection, result_fields enrichment keys). Goes well beyond the schema's basic descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it searches for entities and config definitions in one call. It distinguishes from sibling tools by listing specific alternatives (ha_get_state, ha_config_get_*, ha_get_addon) for different use cases.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly provides when to use ('whenever you need to find something in HA') and when not to use, referencing specific sibling tools. Also explains conditions for config-body search being skipped, aiding correct invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/homeassistant-ai/ha-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server