list_entities
Retrieve and filter Home Assistant entities by domain, search query, or specific fields to manage smart home devices and sensors.
Instructions
Get a list of Home Assistant entities with optional filtering
Args: domain: Optional domain to filter by (e.g., 'light', 'switch', 'sensor') search_query: Optional search term to filter entities by name, id, or attributes (Note: Does not support wildcards. To get all entities, leave this empty) limit: Maximum number of entities to return (default: 100) fields: Optional list of specific fields to include in each entity detailed: If True, returns all entity fields without filtering
Returns: A list of entity dictionaries with lean formatting by default
Examples: domain="light" - get all lights search_query="kitchen", limit=20 - search entities domain="sensor", detailed=True - full sensor details
Best Practices: - Use lean format (default) for most operations - Prefer domain filtering over no filtering - For domain overviews, use domain_summary_tool instead of list_entities - Only request detailed=True when necessary for full attribute inspection - To get all entity types/domains, use list_entities without a domain filter, then extract domains from entity_ids
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | ||
| search_query | No | ||
| limit | No | ||
| fields | No | ||
| detailed | No |
Implementation Reference
- app/server.py:229-294 (handler)Primary handler for the 'list_entities' MCP tool. Registered with @mcp.tool(). Handles input parameters, logging, special '*' handling, and delegates core logic to get_entities helper with lean/detailed formatting.@mcp.tool() @async_handler("list_entities") async def list_entities( domain: Optional[str] = None, search_query: Optional[str] = None, limit: int = 100, fields: Optional[List[str]] = None, detailed: bool = False ) -> List[Dict[str, Any]]: """ Get a list of Home Assistant entities with optional filtering Args: domain: Optional domain to filter by (e.g., 'light', 'switch', 'sensor') search_query: Optional search term to filter entities by name, id, or attributes (Note: Does not support wildcards. To get all entities, leave this empty) limit: Maximum number of entities to return (default: 100) fields: Optional list of specific fields to include in each entity detailed: If True, returns all entity fields without filtering Returns: A list of entity dictionaries with lean formatting by default Examples: domain="light" - get all lights search_query="kitchen", limit=20 - search entities domain="sensor", detailed=True - full sensor details Best Practices: - Use lean format (default) for most operations - Prefer domain filtering over no filtering - For domain overviews, use domain_summary_tool instead of list_entities - Only request detailed=True when necessary for full attribute inspection - To get all entity types/domains, use list_entities without a domain filter, then extract domains from entity_ids """ log_message = "Getting entities" if domain: log_message += f" for domain: {domain}" if search_query: log_message += f" matching: '{search_query}'" if limit != 100: log_message += f" (limit: {limit})" if detailed: log_message += " (detailed format)" elif fields: log_message += f" (custom fields: {fields})" else: log_message += " (lean format)" logger.info(log_message) # Handle special case where search_query is a wildcard/asterisk - just ignore it if search_query == "*": search_query = None logger.info("Converting '*' search query to None (retrieving all entities)") # Use the updated get_entities function with field filtering return await get_entities( domain=domain, search_query=search_query, limit=limit, fields=fields, lean=not detailed # Use lean format unless detailed is requested )
- app/hass.py:218-311 (helper)Core helper function implementing entity listing logic: fetches /api/states, filters by domain/search/limit, applies lean field selection with domain-specific attributes or custom fields.async def get_entities( domain: Optional[str] = None, search_query: Optional[str] = None, limit: int = 100, fields: Optional[List[str]] = None, lean: bool = True ) -> List[Dict[str, Any]]: """ Get a list of all entities from Home Assistant with optional filtering and search Args: domain: Optional domain to filter entities by (e.g., 'light', 'switch') search_query: Optional case-insensitive search term to filter by entity_id, friendly_name or other attributes limit: Maximum number of entities to return (default: 100) fields: Optional list of specific fields to include in each entity lean: If True (default), returns token-efficient versions with minimal fields Returns: List of entity dictionaries, optionally filtered by domain and search terms, and optionally limited to specific fields """ # Get all entities directly client = await get_client() response = await client.get(f"{HA_URL}/api/states", headers=get_ha_headers()) response.raise_for_status() entities = response.json() # Filter by domain if specified if domain: entities = [entity for entity in entities if entity["entity_id"].startswith(f"{domain}.")] # Search if query is provided if search_query and search_query.strip(): search_term = search_query.lower().strip() filtered_entities = [] for entity in entities: # Search in entity_id if search_term in entity["entity_id"].lower(): filtered_entities.append(entity) continue # Search in friendly_name friendly_name = entity.get("attributes", {}).get("friendly_name", "").lower() if friendly_name and search_term in friendly_name: filtered_entities.append(entity) continue # Search in other common attributes (state, area_id, etc.) if search_term in entity.get("state", "").lower(): filtered_entities.append(entity) continue # Search in other attributes for attr_name, attr_value in entity.get("attributes", {}).items(): # Check if attribute value can be converted to string if isinstance(attr_value, (str, int, float, bool)): if search_term in str(attr_value).lower(): filtered_entities.append(entity) break entities = filtered_entities # Apply the limit if limit > 0 and len(entities) > limit: entities = entities[:limit] # Apply field filtering if requested if fields: # Use explicit field list when provided return [filter_fields(entity, fields) for entity in entities] elif lean: # Apply domain-specific lean fields to each entity result = [] for entity in entities: # Get the entity's domain entity_domain = entity["entity_id"].split('.')[0] # Start with basic lean fields lean_fields = DEFAULT_LEAN_FIELDS.copy() # Add domain-specific important attributes if entity_domain in DOMAIN_IMPORTANT_ATTRIBUTES: for attr in DOMAIN_IMPORTANT_ATTRIBUTES[entity_domain]: lean_fields.append(f"attr.{attr}") # Filter and add to result result.append(filter_fields(entity, lean_fields)) return result else: # Return full entities return entities