A Home Assistant MCP server providing tools for entity state management, service calls, configuration editing, and MESA profile queries with token-scoped access control and approval workflows.
Phoenix MCP demonstrates solid tool design with complete JSON Schema definitions, clear descriptions (avg 180 chars), and proper parameter typing. All 12 tools have descriptions and input schemas. Tool names follow verb_noun convention (mesa_query, mesa_get, get_state, get_history). However, several tools lack output schema documentation, some parameter descriptions are generic, and error handling guidance is minimal. MESA tools show domain expertise but lack recovery hints for common failures.
List events from an accessible calendar entity within a time window (defaults to the next 7 days). Requires READ access to the calendar entity.
Retrieve one still image from an accessible Home Assistant camera. This is a privacy-sensitive read that requires the dedicated cap_camera_read capability plus READ or WRITE permission for the camera entity. Returns standard MCP image content; it never returns a camera stream URL.
Get a bounded, chronological page of Recorder history for one accessible entity. Defaults to state_changes, which returns compact attribute-free state transitions and supports arbitrary time ranges. significant_states returns scrubbed full state records that Home Assistant considers significant, not every sample, and is limited to 7 days. Follow has_more with next_cursor; there is intentionally no estimated total.
Get the current state of a Home Assistant entity. Returns a compact, domain-aware view by default (state plus that domain's key attributes); use projection kind full for the full state, or projection kind fields with fields=[...] to select exact fields (e.g. "state", "attr.brightness"). For everything about one entity, use describe_entity.
Output schemas not documented. Tools return data but LLMs cannot plan downstream calls without knowing response structure. get_history, get_statistics, mesa_query_profiles lack documented return types.
Error handling lacks recovery guidance. Tools return errors but do not tell LLMs what to do next. E.g., 'entity not found' should suggest search_entities() or list available entities.
Parameter descriptions for lease tools are vague. 'priority_level' and 'preemption_handling' lack enum values or valid range documentation. LLMs cannot infer valid inputs.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 71 | 2026-07-28+ | v2 |
Get the current state of every entity this token can access (may be a large response). To find specific entities or filter by domain, area, or state use search_entities; for a counts-only orientation use get_overview. Returns a compact, domain-aware view per entity when projection.kind is compact; choose full or fields for another projection.
Get a bounded page of Recorder statistics for one accessible entity. Five-minute data uses short-term retention; hour, day, week, month, and year use long-term statistics. Calendar periods align in Home Assistant's local timezone. Follow has_more with next_cursor; there is intentionally no estimated total. For individual state changes use get_history.
Explain the MESA inheritance chain for one accessible entity, showing how profiles are resolved across layers with optional conflict display.
Retrieve the caller context including authentication status, roles, and session information for the current request.
Retrieve the effective MESA profile for one accessible entity, with optional resolution diagnostics.
Query MESA profiles across the deployment with optional filtering by domains, tags, areas, intents, and origin authority. Returns paginated results with optional field selection and inference inclusion.
Release a previously requested advisory lease by lease ID.
Request an advisory lease on one or more entities to coordinate concurrent operations, with optional priority level and preemption handling.
mesa_get_caller_context has empty input schema (no properties). Description is minimal (47 chars). Purpose and use case unclear for LLM selection.
Pagination cursors documented but no guidance on when to use next_cursor vs limit. get_history and get_statistics both support pagination but lack clear examples of multi-page workflows.