HA Insights MCP
Provides analytics, diagnostics, and guarded actions for Home Assistant. Phase 1 supports read-only discovery: searching entities by text/domain/area, retrieving live entity state and area/device details, listing areas, and generating a home summary. Planned capabilities include history analytics, device health checks, automation audits, and guarded actions with allowlists, value bounds, dry-run, confirmation, and audit logging.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@HA Insights MCPsearch for kitchen entities and show their current states"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
HA Insights MCP
An MCP server that gives LLM agents analytics, diagnostics and guarded actions for Home Assistant.
Status: phase 1 of 4 — read-only discovery tools over stdio. See Roadmap.
Positioning: why another Home Assistant MCP server?
Home Assistant already ships a built-in
MCP Server integration, and
community servers (e.g. ha-mcp) expose broad control of HA. This project deliberately
does not compete with them on "turn on the kitchen light".
Built-in HA MCP Server | HA Insights MCP (this project) | |
Purpose | Voice/Assist-style control of exposed entities | Understanding and auditing the home |
Data | Current state of exposed entities | States joined with area/device/entity registries; history (phase 2) |
Analytics | — | Usage patterns, anomalies, energy (phase 2) |
Diagnostics | — | Unavailable/flapping devices, low batteries, automation audit (phase 2) |
Actions | Direct intents | Guarded: allowlist, value bounds, dry-run, confirmation, audit log (phase 3) |
Output | Assist API responses | Compact, typed, token-efficient structured output |
Use the built-in server to control your home. Use HA Insights to ask "what is going on in my home, what is broken, and is this change safe?". Both can run side by side.
Related MCP server: Home Assistant MCP Server (HA-mcp)
Features (phase 1)
Tools (all annotated readOnlyHint):
Tool | Purpose | Returns |
| Discover entities by text, domain, area |
|
| Live state of one entity | state, unit, area, device, |
| Rooms/zones of the home |
|
Resource: ha://home/summary — markdown overview: areas with entity counts, entities
per domain, number of unavailable entities.
Outputs are pydantic models (MCP structured content with an output schema). Raw HA JSON is
never returned: attributes are filtered per domain (no supported_features bitmasks, icons,
pictures or GPS coordinates).
Architecture
MCP client (Claude, Inspector)
│ JSON-RPC over stdio
┌───────▼──────────────────────────────────────────────┐
│ server.py MCPServer, lifespan, instructions │ MCP layer
│ tools.py search_entities / get_entity_state / │
│ list_areas → schemas.py (outputs) │
│ resources.py ha://home/summary │
│ context.py AppContext, HAError → ToolError │
├──────────────────────────────────────────────────────┤
│ snapshot.py states ⋈ registries, area resolution, │ domain layer
│ TTL cache, single-flight refresh │
├──────────────────────────────────────────────────────┤
│ ha/client.py REST (httpx): states, config │ HA client
│ WebSocket: area/device/entity registry │ (no MCP imports)
│ ha/errors.py HAAuthError, HAConnectionError, ... │
└───────┬──────────────────────────────────────────────┘
│ HTTP + WebSocket, Bearer token
Home AssistantKey decisions:
Separate HA client.
ha/knows nothing about MCP, so it is testable on its own and reusable for the HTTP transport (phase 4).REST + WebSocket. REST has no area/device/entity registries; without them you cannot answer "what is in the kitchen". Registries are fetched in one WebSocket session.
Area resolution like HA: the entity's own area wins, otherwise the device's area.
Snapshot cache (10 s default) shared by tools and the resource;
get_entity_statealways reads the state fresh.Errors are part of the conversation. HA failures become MCP tool errors with actionable text ("Unknown area 'attic'. Known areas: …"), so the model can self-correct.
Security from day one. Token only from env/
.env, held asSecretStr, never logged or included in errors.entity_idis validated before it reaches a URL. Phase 1 has no write methods at all — annotations are hints, not enforcement.stdio hygiene. stdout is the JSON-RPC channel; all logs go to stderr.
Setup
Requirements: Python 3.12, uv, Docker (for the dev HA), Node.js (only for MCP Inspector).
make install # uv sync
cp .env.example .env # then set HA_URL and HA_TOKENDev Home Assistant
make dev-ha-up # HA with the demo integration on http://localhost:8123Onboard, create a long-lived access token and seed areas — see
dev/README.md. Any real HA instance works too: set HA_URL and
HA_TOKEN (an admin user's token, required for the registries).
Configuration
Variable | Default | |
|
| Base URL of Home Assistant |
| — (required) | Long-lived access token |
|
| Per-request timeout |
|
| Snapshot cache TTL (0 disables) |
|
| Logs go to stderr |
Usage
MCP Inspector
make inspectOpens the Inspector in the browser, connected over stdio. Click Connect, then:
Tools → List Tools → list_areas → Run; Resources → ha://home/summary.
Check the output schema and the structured result of each tool.
Claude Code
claude mcp add ha-insights -- uv run --directory /path/to/ha_mcp ha-insights-mcp
claude mcp list # should show ha-insights: connected--directory makes uv run in the repo, so .env is found. In a session, ask
"What areas does my home have?" or reference the resource with @ha-insights:ha://home/summary.
Claude Desktop
~/.config/Claude/claude_desktop_config.json (Linux) or
~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"ha-insights": {
"command": "uv",
"args": ["run", "--directory", "/path/to/ha_mcp", "ha-insights-mcp"]
}
}
}Prefer keeping the token in the repo's .env (git-ignored) over an env block in this
file.
Development
make test # pytest, no real HA calls (respx + fake WebSocket + in-memory MCP client)
make lint # ruff
make fmtTool tests run the whole stack: in-memory MCP Client → server → real HAClient →
mocked HA. Conventions for contributors and AI agents: CLAUDE.md.
Roadmap
Skeleton + read-only tools over stdio, dev HA in Docker ← current
History analytics, device health (unavailable / flapping / battery), automation audit
Guarded actions: domain allowlist, value bounds, dry-run, confirmation for risky actions, SQLite audit log
Streamable HTTP transport with auth, Docker image, README demo GIF
License
MIT
Available Tools
3 toolsget_entity_stateGet entity stateARead-only
Get the live state of one entity with its area, device and relevant attributes.
The state is read fresh from Home Assistant. Attributes are filtered to the ones meaningful for the entity's domain (e.g. temperatures and modes for climate).
| Name | Required | Description | Default |
|---|---|---|---|
| entity_id | Yes | Exact entity_id, e.g. 'climate.hvac'. Find it with search_entities. |
Output Schema
| Name | Required | Description |
|---|---|---|
| area | Yes | |
| name | Yes | |
| unit | Yes | Unit of measurement of the state, if any |
| state | Yes | |
| device | Yes | Name of the device this entity belongs to |
| domain | Yes | |
| entity_id | Yes | |
| attributes | Yes | Relevant attributes for this domain; noisy/internal attributes are omitted |
| last_changed | Yes | When the state value last changed (UTC) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, and the description adds genuinely new behavior: values are fetched fresh from Home Assistant rather than cached, and attributes are a filtered subset rather than the raw attribute dict. It does not say what happens when an entity_id is unknown, which is the one remaining behavioral gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the core purpose and followed by meaningful qualifications about freshness and attribute filtering. Slightly padded by the parenthetical climate example, but nothing is genuinely wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return structure needn't be described; the description instead covers the two things the schema cannot express, data freshness and attribute filtering. Combined with readOnly annotations, that is sufficient for an agent to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter and schema coverage is 100%; the schema already carries the pattern, example ('climate.hvac') and the search_entities discovery hint. The description adds nothing parameter-specific, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Get'), resource ('live state of one entity') and the payload contents (area, device, relevant attributes). It is clearly narrower in scope than sibling tools like search_entities and list_areas, though it never names those siblings to contrast explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: it tells you the state is read fresh and attributes are domain-filtered, so an agent can infer it is for inspecting a known entity. There is no explicit 'use this instead of X when Y' guidance, and the pointer to search_entities lives only in the schema description, not here.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_areasList areasARead-only
List all areas (rooms/zones) of the home with how many entities each contains.
Use area_id or name from here to filter search_entities by area.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| areas | Yes | |
| unassigned_entity_count | Yes | Entities that belong to no area |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true and openWorldHint=false already declare this as a safe, closed-domain read, so the safety profile is covered. The description adds only that each area comes back with its entity count and that its identifiers are reusable downstream; it says nothing about empty homes, unnamed areas, or ordering.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, with the resource definition first and the follow-on usage hint second. Every clause carries information the agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters, an output schema, and read-only annotations, the description covers purpose and downstream usage adequately. Minor gap: it doesn't mention what happens when no areas exist or how the two identifier forms differ in practice.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so there is nothing to disambiguate and the baseline of 4 applies. The description correctly focuses on the return fields (`area_id`, `name`) that serve as inputs to other tools.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("List all areas") and disambiguates the term with "(rooms/zones) of the home." It also states what each result carries (entity counts), so the agent knows exactly what it gets without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent into the workflow: take `area_id` or `name` from here and pass it to search_entities. There are no exclusions or "don't use this when" cases, but for a zero-arg enumeration tool the intended context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_entitiesSearch entitiesARead-only
Find Home Assistant entities and their current states.
Use this first to discover entity_ids, then call get_entity_state for details.
Returns entity_id, name, state and area for each match, best matches first.
| Name | Required | Description | Default |
|---|---|---|---|
| area | No | Only this area, by area_id or name (see list_areas) | |
| limit | No | Maximum results | |
| query | Yes | Case-insensitive text matched against entity_id and friendly name, e.g. 'kitchen', 'temperature', 'light.bed'. All words must match. Use an empty string to list everything that matches the filters. | |
| domain | No | Only this domain, e.g. 'light', 'sensor', 'climate', 'switch' |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | Yes | Number of matching entities before applying the limit |
| entities | Yes | |
| truncated | Yes | True if more matches exist; narrow the query or filters |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds real value beyond that: the returned fields (entity_id, name, state, area) and the result ordering ('best matches first'). It does not mention limit/pagination behavior or what happens when nothing matches, which is why it stops short of 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short lines, front-loaded with purpose, followed by the workflow hint and the return shape. No filler sentences and nothing repeated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Annotations cover read-safety, an output schema covers return structure, and the schema fully documents all four parameters. The description supplies exactly the missing piece — the discovery-then-detail workflow with get_entity_state — so an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already documents query matching semantics, area, domain, and limit with a max of 100. The description adds no parameter-level detail (no note that an empty query lists everything, no guidance on combining filters), so this is the baseline for a fully documented schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Find Home Assistant entities and their current states') and immediately distinguishes itself from the sibling read tool by naming get_entity_state for details. An agent can tell what this does and how it differs from adjacent tools without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use this first to discover entity_ids, then call get_entity_state for details', which gives both the ordering rule and the named alternative. The condition that selects this tool versus get_entity_state is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
get_entity_state - First observed
list_areas - First observed
search_entities
TDQS
Scored across 3 tools
Each tool has a clearly distinct role: search_entities discovers entities, list_areas catalogs rooms/zones, and get_entity_state retrieves detail for a single entity. The descriptions explicitly guide sequencing from search to detail, leaving little room for misselection.
All tool names follow the same snake_case verb_noun pattern: search_entities, list_areas, get_entity_state. The convention is predictable and readable throughout.
Three tools is minimal but well-matched to this read-only Home Assistant insights server. Each tool serves a distinct discovery, area, or detail purpose, so none feels redundant or missing.
The surface covers the core read-only workflow: discover entities, understand areas, and inspect live entity state with relevant attributes. Minor gaps like a dedicated area-detail or history/statistics tool exist, but agents can work around them for the stated purpose.
Maintenance
Related MCP Connectors
Read-only Google Search Console and Google Analytics for AI agents.
Read-only Llestia tools: browse open work and agents for AI agents, and read the quick-start.
Read-only AI access to HAVN properties, leads, tasks, files, media, and analytics.
Read-only search of 2,189 AI agent tools (MCP servers, x402 APIs) with daily automated trust scores.
Related MCP Servers
- AlicenseBqualityDmaintenanceProvides tools for AI assistants to interact with smart home devices through Home Assistant, allowing operations like checking entity states and calling services.392 npm3MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to interact with Home Assistant to control smart home devices, query entity states, and manage automations using natural language. It provides over 90 tools for comprehensive system management, including dashboard configuration, service execution, and automation debugging.MIT
- AlicenseNot gradedqualityAmaintenanceGives AI agents scoped, least-privilege access to Home Assistant, with per-token permissions, auditing, and 131 tools for managing smart home devices.1MIT
- AlicenseNot gradedqualityAmaintenanceProvides secure, read-only semantic access to Home Assistant entities, areas, floors, and domain summaries for MCP clients like ChatGPT and Codex.MIT