hass-mcp
Allows AI assistants to interact with a Home Assistant instance, providing tools for querying entity states, controlling devices, searching entities, managing automations, editing Lovelace dashboards, and retrieving logs.
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., "@hass-mcp turn on the kitchen lights"
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.
hass-mcp — HiTech Lab Edition
Maintained and optimized by HiTech Lab Source: https://github.com/voska/hass-mcp
Hass-MCP
A Model Context Protocol (MCP) server for Home Assistant integration with Claude and other LLMs.
Overview
Hass-MCP enables AI assistants like Claude to interact directly with your Home Assistant instance, allowing them to:
Query the state of devices and sensors
Control lights, switches, and other entities
Get summaries of your smart home
Troubleshoot automations and entities
Search for specific entities
Create guided conversations for common tasks
Related MCP server: Hass-MCP
Screenshots
Features
Entity Management: Get states, control devices, and search for entities
Domain Summaries: Get high-level information about entity types
Automation Support: List and control automations
Guided Conversations: Use prompts for common tasks like creating automations
Smart Search: Find entities by name, type, or state
Live Dashboard Editing: Read and edit Lovelace dashboards (cards and views) over Home Assistant's WebSocket API — changes appear instantly in open browsers, with automatic backups and a dry-run preview
Token Efficiency: Lean JSON responses to minimize token usage
Installation
Prerequisites
Home Assistant instance with Long-Lived Access Token
One of the following:
Docker (recommended)
Python 3.13+ and uv
Setting Up With Claude Desktop
Docker Installation (Recommended)
Pull the Docker image:
docker pull voska/hass-mcp:latestAdd the MCP server to Claude Desktop:
a. Open Claude Desktop and go to Settings b. Navigate to Developer > Edit Config c. Add the following configuration to your
claude_desktop_config.jsonfile:{ "mcpServers": { "hass-mcp": { "command": "docker", "args": [ "run", "-i", "--rm", "-e", "HA_URL", "-e", "HA_TOKEN", "voska/hass-mcp" ], "env": { "HA_URL": "http://homeassistant.local:8123", "HA_TOKEN": "YOUR_LONG_LIVED_TOKEN" } } } }d. Replace
YOUR_LONG_LIVED_TOKENwith your actual Home Assistant long-lived access token e. Update theHA_URL:If running Home Assistant on the same machine: use
http://host.docker.internal:8123(Docker Desktop on Mac/Windows)If running Home Assistant on another machine: use the actual IP or hostname
f. Save the file and restart Claude Desktop
The "Hass-MCP" tool should now appear in your Claude Desktop tools menu
Note: If you're running Home Assistant in Docker on the same machine, you may need to add
--network hostto the Docker args for the container to access Home Assistant. Alternatively, use the IP address of your machine instead ofhost.docker.internal.
uv/uvx
Install uv on your system.
Add the MCP server to Claude Desktop:
a. Open Claude Desktop and go to Settings b. Navigate to Developer > Edit Config c. Add the following configuration to your
claude_desktop_config.jsonfile:{ "mcpServers": { "hass-mcp": { "command": "uvx", "args": ["hass-mcp"], "env": { "HA_URL": "http://homeassistant.local:8123", "HA_TOKEN": "YOUR_LONG_LIVED_TOKEN" } } } }d. Replace
YOUR_LONG_LIVED_TOKENwith your actual Home Assistant long-lived access token e. Update theHA_URL:If running Home Assistant on the same machine: use
http://host.docker.internal:8123(Docker Desktop on Mac/Windows)If running Home Assistant on another machine: use the actual IP or hostname
f. Save the file and restart Claude Desktop
The "Hass-MCP" tool should now appear in your Claude Desktop tools menu
Other MCP Clients
Cursor
Go to Cursor Settings > MCP > Add New MCP Server
Fill in the form:
Name:
Hass-MCPType:
commandCommand:
docker run -i --rm -e HA_URL=http://homeassistant.local:8123 -e HA_TOKEN=YOUR_LONG_LIVED_TOKEN voska/hass-mcpReplace
YOUR_LONG_LIVED_TOKENwith your actual Home Assistant tokenUpdate the HA_URL to match your Home Assistant instance address
Click "Add" to save
Claude Code (CLI)
To use with Claude Code CLI, you can add the MCP server directly using the mcp add command:
Using Docker (recommended):
claude mcp add hass-mcp -e HA_URL=http://homeassistant.local:8123 -e HA_TOKEN=YOUR_LONG_LIVED_TOKEN -- docker run -i --rm -e HA_URL -e HA_TOKEN voska/hass-mcpReplace YOUR_LONG_LIVED_TOKEN with your actual Home Assistant token and update the HA_URL to match your Home Assistant instance address.
HTTP Transport (Streamable)
For deployments that can't use stdio — running behind an MCP gateway, hosting on Smithery, sharing one server across multiple clients, or connecting from network-based tools like LibreChat or OpenWebUI — Hass-MCP supports the MCP streamable HTTP transport. The server runs in stateless mode (no Mcp-Session-Id, JSON responses), suitable for horizontally-scaled hosts.
HTTP mode exposes full Home Assistant control over the network. Anyone who can reach the port can call any tool — turn off lights, unlock doors, trigger automations, restart HA. The MCP spec does not yet ship a built-in auth layer in this server. Until it does, you must put it behind one of:
A reverse proxy (nginx, Caddy, Traefik) doing basic-auth or bearer-token validation
A VPN or zero-trust network (Tailscale, WireGuard, Cloudflare Access)
Localhost binding only (the default — change
--hostonly if you know what you're doing)
Do not expose :8000 to the open internet without auth.
Running locally
Using uvx:
HA_URL=http://homeassistant.local:8123 \
HA_TOKEN=YOUR_LONG_LIVED_TOKEN \
uvx hass-mcp --http --port 8000The server binds 127.0.0.1 by default. Override with --host 0.0.0.0 only when you've also configured auth in front of it.
Running in Docker
docker run --rm -p 8000:8000 \
-e HA_URL=http://homeassistant.local:8123 \
-e HA_TOKEN=YOUR_LONG_LIVED_TOKEN \
voska/hass-mcp:latest --http --host 0.0.0.0 --port 8000--host 0.0.0.0 is required inside Docker so the port is reachable through the bridge. Bind the publish (-p) to 127.0.0.1:8000:8000 if you only want it reachable from the host, or put a reverse proxy in front.
Endpoint
The MCP endpoint is at /mcp. Point your client at http://<host>:<port>/mcp.
Smithery / PaaS
The server honors the PORT environment variable (Smithery's convention) in addition to MCP_PORT. Smithery deployment requires --http mode and reads PORT automatically.
Custom / private CA
If your Home Assistant instance serves a certificate signed by your own CA (step-ca, smallstep, homelab OpenSSL), hass-mcp can verify it without disabling TLS:
Locally: install the CA root in your OS trust store (macOS Keychain, Windows Cert Store, or
update-ca-certificateson Linux). hass-mcp picks it up automatically via truststore.In Docker (or any sandboxed runtime): bind-mount the CA file and point
SSL_CERT_FILEat it.
docker run --rm \
-v /path/to/your-ca.crt:/etc/ssl/certs/your-ca.crt:ro \
-e SSL_CERT_FILE=/etc/ssl/certs/your-ca.crt \
-e HA_URL=https://homeassistant.example.internal:8123 \
-e HA_TOKEN=YOUR_LONG_LIVED_TOKEN \
voska/hass-mcp:latestSSL_CERT_FILE always takes precedence over the OS store when set. verify=False is intentionally not supported — use HA_URL=http://... if you genuinely want unencrypted local LAN traffic.
Usage Examples
Here are some examples of prompts you can use with Claude once Hass-MCP is set up:
"What's the current state of my living room lights?"
"Turn off all the lights in the kitchen"
"What's the temperature in the master bedroom?"
"List everything in the guest room"
"List all my sensors that contain temperature data"
"Give me a summary of my climate entities"
"Create an automation that turns on the lights at sunset"
"Help me troubleshoot why my bedroom motion sensor automation isn't working"
"Search for entities related to my living room"
"Show me the last 50 ERROR lines from the Home Assistant log"
"What's been failing on the mqtt integration today?"
"Show me power usage by day for the last month"
"What happened with the front door sensor last Tuesday?"
Available Tools
Hass-MCP provides several tools for interacting with Home Assistant:
get_version: Get the Home Assistant versionget_entity: Get the state of a specific entity with optional field filteringentity_action: Perform actions on entities (turn on, off, toggle)list_entities: Get a list of entities with optional domain filtering and searchsearch_entities_tool: Search for entities matching a querydomain_summary_tool: Get a summary of a domain's entitieslist_automations: Get a list of all automationscall_service_tool: Call any Home Assistant servicerestart_ha: Restart Home Assistantget_history: Get the state history of an entity (last N hours)get_history_range: Get state-change history for an entity over an explicit date/time range (start_time/end_time, ISO-8601)get_statistics: Get long-term aggregated statistics (mean / min / max per bucket) for an entity over the last N hours — works for data older than the recorder's short-term retention windowget_statistics_range: Same, but for an explicit date/time range — useful for monthly / yearly trend queriesget_error_log: Get the Home Assistant error log, with optionallevel/integration/search_term/linesfilters applied server-side so noisy logs don't blow Claude's contextget_entities_by_area: List entities in a specific area / room
Dashboard (Lovelace) Editing
Read and live-edit dashboards over Home Assistant's WebSocket API. Saving pushes the change to every open browser instantly — no restart.
list_dashboards: List dashboards (the default plus any user dashboards), each with itsurl_pathandmode(storage/yaml)get_dashboard_config: Get a dashboard's full configset_dashboard_config: Replace a dashboard's full config (low-level)add_card/update_card/remove_card/move_card: Edit cards within a view (the view is selected by index, or by itspath/title)list_view_sections: List the sections of a "sections"-type viewadd_view/remove_view/update_view: Edit a dashboard's viewslist_dashboard_backups/restore_dashboard: List and roll back to the automatic pre-save backups
Sections views: Home Assistant's modern view type (type: sections) stores
its cards inside sections rather than a single top-level list. For those views,
call list_view_sections and pass the section argument (index, title, or
heading) to the card tools. Card edits on a sections view without a section
are rejected with the list of available sections — rather than silently saving
a card where it would never render.
Every editing tool accepts dry_run=true to preview the resulting config and
a change summary without saving.
Important notes:
Admin token required. Saving Lovelace config requires the long-lived token to belong to an admin user.
Storage-mode only. Only UI-managed ("storage") dashboards can be edited. YAML-mode dashboards are detected and rejected with a clear message — edit their YAML files directly instead.
Whole-config writes. Home Assistant has no partial-edit API; every change is a read-modify-write of the entire dashboard. The high-level card/view tools handle this for you.
Automatic backups. Before each write, the current config is saved to
HASS_MCP_BACKUP_DIR(default~/.hass-mcp/dashboard-backups/). When running in Docker, mount a volume at this path or backups are lost when the container is recreated.
Prompts for Guided Conversations
Hass-MCP includes several prompts for guided conversations:
create_automation: Guide for creating Home Assistant automations based on trigger typedebug_automation: Troubleshooting help for automations that aren't workingtroubleshoot_entity: Diagnose issues with entitiesroutine_optimizer: Analyze usage patterns and suggest optimized routines based on actual behaviorautomation_health_check: Review all automations, find conflicts, redundancies, or improvement opportunitiesentity_naming_consistency: Audit entity names and suggest standardization improvementsdashboard_layout_generator: Create optimized dashboards based on user preferences and usage patterns
Available Resources
Hass-MCP provides the following resource endpoints:
hass://entities/{entity_id}: Get the state of a specific entityhass://entities/{entity_id}/detailed: Get detailed information about an entity with all attributeshass://entities: List all Home Assistant entities grouped by domainhass://entities/domain/{domain}: Get a list of entities for a specific domainhass://search/{query}/{limit}: Search for entities matching a query with custom result limit
Development
Running Tests
uv run pytest tests/License
Available Tools
29 toolsadd_cardA
Add a card to a dashboard view (live)
Args:
url_path: Dashboard URL path, or None for the default dashboard.
view: Target view — an integer index, or a string matching the view's
path or title.
card: The card config dict (must include a string type), e.g.
{"type": "markdown", "content": "Hello"}.
position: Insert index within the target card list (default: append).
section: For a "sections"-type view, which section to add into — an
index, section title, or heading text. REQUIRED for sections
views (use list_view_sections to see them); omit for classic
views.
dry_run: Preview without saving.
Returns:
Save result with a backup_id, or a dry-run preview.
Inputs: card, view, dry_run, section, +2 more. Returns: result
add_viewA
Add a new view to a dashboard (live)
Args: url_path: Dashboard URL path, or None for the default dashboard. view_config: The view config dict, e.g. {"title": "Garage", "path": "garage"}. position: Insert index among views (default: append). dry_run: Preview without saving.
Returns:
Save result with a backup_id, or a dry-run preview.
Inputs: dry_run, position, url_path, view_config. Returns: result
call_service_toolA
Call any Home Assistant service (low-level API access)
Args: domain: The domain of the service (e.g., 'light', 'switch', 'automation') service: The service to call (e.g., 'turn_on', 'turn_off', 'toggle') data: Optional data to pass to the service (e.g., {'entity_id': 'light.living_room'})
Returns: A dictionary with success status, the domain/service called, and the list of affected entity states returned by Home Assistant.
Examples: domain='light', service='turn_on', data={'entity_id': 'light.x', 'brightness': 255} domain='automation', service='reload' domain='fan', service='set_percentage', data={'entity_id': 'fan.x', 'percentage': 50}
Inputs: domain (required), service (required), data. Returns: result
domain_summary_toolA
Get a summary of entities in a specific domain
Args: domain: The domain to summarize (e.g., 'light', 'switch', 'sensor') example_limit: Maximum number of examples to include for each state
Returns: A dictionary containing: - total_count: Number of entities in the domain - state_distribution: Count of entities in each state - examples: Sample entities for each state - common_attributes: Most frequently occurring attributes
Examples: domain="light" - get light summary domain="climate", example_limit=5 - climate summary with more examples Best Practices: - Use this before retrieving all entities in a domain to understand what's available
Inputs: domain (required), example_limit. Returns: result
entity_actionA
Perform an action on a Home Assistant entity (on, off, toggle)
Args: entity_id: The entity ID to control (e.g. 'light.living_room') action: The action to perform ('on', 'off', 'toggle') params: Optional dictionary of additional parameters for the service call
Returns: The response from Home Assistant
Examples: entity_id="light.living_room", action="on", params={"brightness": 255} entity_id="switch.garden_lights", action="off" entity_id="climate.living_room", action="on", params={"temperature": 22.5}
Domain-Specific Parameters: - Lights: brightness (0-255), color_temp, rgb_color, transition, effect - Covers: position (0-100), tilt_position - Climate: temperature, target_temp_high, target_temp_low, hvac_mode - Media players: source, volume_level (0-1)
Inputs: action (required), entity_id (required), params.
get_dashboard_configA
Get a dashboard's full configuration
Args: url_path: The dashboard's URL path (e.g. "my-dash"). Omit or pass None for the default "Overview" dashboard.
Returns:
The dashboard config dict (a top-level views list of cards). If the
dashboard has no stored config yet, returns an empty {"views": []}
scaffold with a note.
Inputs: url_path. Returns: result
get_entities_by_areaA
Get all entities assigned to a specific Home Assistant area (room).
Area lookup is case-insensitive and matches the area's name as configured in Home Assistant (e.g., "Kitchen", "Living Room"). Entities inherit their area from their parent device when no area is set directly, matching HA's own resolution behavior.
Args: area: Name of the area to filter by (case-insensitive) domain: Optional domain to further filter results (e.g., 'light') lean: If True (default), returns token-efficient entity records
Returns: A dictionary containing: - area: The matched area name (as canonicalized by HA) - count: Number of matching entities - entities: List of entity records with their state and area
Examples: get_entities_by_area(area="Kitchen") - everything in the kitchen get_entities_by_area(area="Living Room", domain="light") - lights only
Inputs: area (required), lean, domain. Returns: result
get_entityA
Get the state of a Home Assistant entity with optional field filtering
Args: entity_id: The entity ID to get (e.g. 'light.living_room') fields: Optional list of fields to include (e.g. ['state', 'attr.brightness']) detailed: If True, returns all entity fields without filtering
Examples: entity_id="light.living_room" - basic state check entity_id="light.living_room", fields=["state", "attr.brightness"] - specific fields entity_id="light.living_room", detailed=True - all details
Inputs: entity_id (required), fields, detailed.
get_error_logA
Get the Home Assistant error log for troubleshooting.
All filters are optional and combine (AND semantics). Stats (error_count, warning_count, integration_mentions, total_lines) are computed over the filtered output so they match what's returned.
Args:
level: Filter to lines containing this log level — ERROR, WARNING,
INFO, or DEBUG. Case-insensitive.
integration: Filter to lines mentioning this integration. Matches
[name] or [homeassistant.components.name].
Case-insensitive.
search_term: Case-insensitive substring filter applied per line.
Useful for entity IDs, exception names, etc.
lines: Return only the most recent N lines (applied after other
filters). Useful when you only care about the tail.
Returns: A dictionary containing: - log_text: The (possibly filtered) error log text - error_count: Number of ERROR entries in the filtered output - warning_count: Number of WARNING entries in the filtered output - integration_mentions: Map of integration names to mention counts - total_lines: Number of lines in the filtered output - filters_applied: Map of which filter args were supplied - error: Error message if retrieval failed
Examples: get_error_log() # full log get_error_log(level="ERROR") # errors only get_error_log(integration="zwave_js") # one integration get_error_log(search_term="light.kitchen") # specific entity get_error_log(level="ERROR", lines=50) # last 50 errors
Best Practices:
- Filter on the server side (here) rather than pulling the full
log into Claude's context — saves tokens on noisy logs.
- Combine integration + level="ERROR" to triage a single
integration that's misbehaving.
- Use lines to bound output when scanning a long-running HA.
Inputs: level, lines, integration, search_term. Returns: result
get_historyA
Get the history of an entity's state changes
Args: entity_id: The entity ID to get history for hours: Number of hours of history to retrieve (default: 24)
Returns: A dictionary containing: - entity_id: The entity ID requested - states: List of state objects with timestamps - count: Number of state changes found - first_changed: Timestamp of earliest state change - last_changed: Timestamp of most recent state change
Examples: entity_id="light.living_room" - get 24h history entity_id="sensor.temperature", hours=168 - get 7 day history Best Practices: - Keep hours reasonable (24-72) for token efficiency - Use for entities with discrete state changes rather than continuously changing sensors - Consider the state distribution rather than every individual state
Inputs: entity_id (required), hours. Returns: result
get_history_rangeA
Get raw state-change history for an entity over a date/time range.
Like get_history, but takes an explicit window instead of "N hours
from now". Useful for inspecting what happened on a specific day or
correlating with an external event.
Args:
entity_id: The entity to fetch history for.
start_time: ISO-8601 start (e.g. 2026-05-15 or
2026-05-15T08:00:00Z). Treated as UTC if no offset.
end_time: ISO-8601 end. Defaults to now (UTC).
Returns:
Same shape as get_history: entity_id, states, count,
first_changed, last_changed.
Examples: get_history_range("light.kitchen", "2026-05-15") get_history_range("sensor.power", "2026-05-15T00:00:00Z", "2026-05-16T00:00:00Z")
Best Practices:
- Bound the window — wider ranges return more data and more tokens.
- For aggregated long-term data, prefer get_statistics_range.
Inputs: entity_id (required), start_time (required), end_time. Returns: result
get_statisticsA
Get long-term aggregated statistics for an entity over the last N hours.
Uses HA's recorder statistics (over WebSocket) — aggregated buckets
(mean / min / max per period) that survive the short-term retention
window. Use this instead of get_history when:
- You want data older than the recorder's default 10-day window.
- You want aggregated values rather than every individual change.
- The entity is a high-frequency sensor (temperature, power) and
raw history would be too many tokens.
Args:
entity_id: The entity (must have a state_class HA records as
statistics — measurement, total, total_increasing).
hours: How far back from now. Defaults to 24.
period: Bucket size — 5minute, hour, day, week, month.
Defaults to hour.
Returns:
entity_id, period, start_time, end_time, statistics
(list of {start, end, mean, min, max, ...} points).
Examples: get_statistics("sensor.power_usage", hours=168, period="day") get_statistics("sensor.temperature", hours=24)
Inputs: entity_id (required), hours, period. Returns: result
get_statistics_rangeA
Get long-term aggregated statistics for an entity over a date/time range.
Same data source as get_statistics, but with an explicit window —
useful for "what was my power usage from Jan 1 to Jan 31?" type
questions. Aggregated bucket data survives the short-term retention
window, so this works for data months/years old.
Args:
entity_id: The entity (must be statistics-tracked).
start_time: ISO-8601 start (2026-01-01 or
2026-01-01T00:00:00Z). UTC if no offset.
end_time: ISO-8601 end. Defaults to now.
period: 5minute, hour, day, week, or month.
Returns:
entity_id, period, start_time, end_time, statistics.
Examples: get_statistics_range("sensor.energy", "2026-01-01", "2026-02-01", period="day") get_statistics_range("sensor.temperature", "2026-05-01", period="hour")
Inputs: entity_id (required), start_time (required), period, end_time. Returns: result
get_versionA
Get the Home Assistant version
Returns: A string with the Home Assistant version (e.g., "2025.3.0")
Inputs: no named parameters. Returns: result
list_automationsA
Get a list of all automations from Home Assistant
This function retrieves all automations configured in Home Assistant, including their IDs, entity IDs, state, and display names.
Returns: A list of automation dictionaries, each containing id, entity_id, state, and alias (friendly name) fields.
Examples: Returns all automation objects with state and friendly names
Inputs: no named parameters. Returns: result
list_dashboard_backupsA
List on-disk backups of a dashboard's config
Backups are written automatically before every dashboard write. NOTE: in Docker, backups persist only if HASS_MCP_BACKUP_DIR is volume-mounted.
Args: url_path: Dashboard URL path, or None for the default dashboard.
Returns: A list of {backup_id, path}, oldest first.
Inputs: url_path. Returns: result
list_dashboardsA
List Home Assistant dashboards (Lovelace)
Returns:
A list of dashboards. Each entry has url_path (None for the default
"Overview" dashboard), title, and mode ("storage" or "yaml"). Only
"storage"-mode dashboards can be edited via these tools.
Inputs: no named parameters. Returns: result
list_entitiesA
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
Inputs: limit, domain, fields, detailed, +1 more. Returns: result
list_view_sectionsA
List the sections of a "sections"-type dashboard view
Modern Home Assistant views of type: sections hold their cards inside
sections (not a top-level card list). Use this to discover which section
to target with the card tools' section argument.
Args:
url_path: Dashboard URL path, or None for the default dashboard.
view: Target view (index, or matching path/title).
Returns: A list of {index, title, heading, card_count}, one per section. Errors if the view is not a sections view.
Inputs: view, url_path. Returns: result
move_cardB
Reorder a card within a dashboard view (live)
Args:
url_path: Dashboard URL path, or None for the default dashboard.
view: Target view (index, or matching path/title).
card_index: Current index of the card.
new_index: Destination index within the same card list.
section: For a "sections"-type view, which section the card is in
(index/title/heading). Required for sections views.
dry_run: Preview without saving.
Returns:
Save result with a backup_id, or a dry-run preview.
Inputs: view, dry_run, section, url_path, +2 more. Returns: result
remove_cardA
Remove a card from a dashboard view (live)
Args:
url_path: Dashboard URL path, or None for the default dashboard.
view: Target view (index, or matching path/title).
card_index: Index of the card to remove within the target card list.
section: For a "sections"-type view, which section the card is in
(index/title/heading). Required for sections views.
dry_run: Preview without saving.
Returns:
Save result with a backup_id, or a dry-run preview.
Inputs: view, dry_run, section, url_path, +1 more. Returns: result
remove_viewA
Remove a view from a dashboard (live)
⚠️ Removes the view and all its cards.
Args:
url_path: Dashboard URL path, or None for the default dashboard.
view: Target view (index, or matching path/title).
dry_run: Preview without saving.
Returns:
Save result with a backup_id, or a dry-run preview.
Inputs: view, dry_run, url_path. Returns: result
restart_haA
Restart Home Assistant
⚠️ WARNING: Temporarily disrupts all Home Assistant operations
Returns: Result of restart operation
Inputs: no named parameters. Returns: result
restore_dashboardA
Restore a dashboard from a backup (live)
Restores the most recent backup unless backup_id is given. The current
config is itself backed up first, so a restore can be undone.
Args: url_path: Dashboard URL path, or None for the default dashboard. backup_id: A specific backup id from list_dashboard_backups (default: newest). dry_run: Preview without saving.
Returns:
Save result plus restored_from, or a dry-run preview.
Inputs: dry_run, url_path, backup_id. Returns: result
search_entities_toolA
Search for entities matching a query string
Args: query: The search query to match against entity IDs, names, and attributes. (Note: Does not support wildcards. To get all entities, leave this blank or use list_entities tool) limit: Maximum number of results to return (default: 20)
Returns: A dictionary containing search results and metadata: - count: Total number of matching entities found - results: List of matching entities with essential information - domains: Map of domains with counts (e.g. {"light": 3, "sensor": 2})
Examples: query="temperature" - find temperature entities query="living room", limit=10 - find living room entities query="", limit=500 - list all entity types
Inputs: query (required), limit. Returns: result
set_dashboard_configA
Replace a dashboard's full configuration (low-level write)
⚠️ WARNING: Overwrites the ENTIRE dashboard and updates every open browser live. The prior config is backed up first (use restore_dashboard to undo). Requires an admin token; only storage-mode dashboards can be saved.
Args:
url_path: Dashboard URL path, or None for the default dashboard.
config: The complete new config dict (must contain a views list).
dry_run: If True, validate and return the resulting config + a change
summary WITHOUT saving.
Returns: On save: {success, url_path, backup_id, summary}. On dry_run: {dry_run: True, url_path, summary, config}.
Inputs: config, dry_run, url_path. Returns: result
system_overviewA
Get a comprehensive overview of the entire Home Assistant system
Returns: A dictionary containing: - total_entities: Total count of all entities - domains: Dictionary of domains with their entity counts and state distributions - domain_samples: Representative sample entities for each domain (2-3 per domain) - domain_attributes: Common attributes for each domain - area_distribution: Entities grouped by area (if available)
Examples: Returns domain counts, sample entities, and common attributes Best Practices: - Use this as the first call when exploring an unfamiliar Home Assistant instance - Perfect for building context about the structure of the smart home - After getting an overview, use domain_summary_tool to dig deeper into specific domains
Inputs: no named parameters. Returns: result
update_cardB
Replace a card in a dashboard view (live)
Args:
url_path: Dashboard URL path, or None for the default dashboard.
view: Target view (index, or matching path/title).
card_index: Index of the card to replace within the target card list.
card: The new card config dict (must include a string type).
section: For a "sections"-type view, which section the card is in
(index/title/heading). Required for sections views.
dry_run: Preview without saving.
Returns:
Save result with a backup_id, or a dry-run preview.
Inputs: card, view, dry_run, section, +2 more. Returns: result
update_viewA
Update a view's properties — title, path, icon, etc. (live)
Cards in the view are preserved unless changes includes a cards key.
Args:
url_path: Dashboard URL path, or None for the default dashboard.
view: Target view (index, or matching path/title).
changes: Dict of view properties to merge in, e.g. {"title": "New Title"}.
dry_run: Preview without saving.
Returns:
Save result with a backup_id, or a dry-run preview.
Inputs: view, changes, dry_run, url_path. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 29 tools
There are several overlapping tools for entity queries (list_entities, search_entities_tool, get_entities_by_area, domain_summary_tool, system_overview) and history (get_history, get_history_range, get_statistics, get_statistics_range). While each has a distinct primary purpose, the entity discovery/query tools especially overlap in what an agent might use to 'find entities,' requiring careful reading of descriptions to pick correctly. Dashboard tools and service/entity_action tools are more clearly distinct.
Naming is inconsistent: many use snake_case verbs (list_entities, get_entity, add_card, remove_view) but several use different patterns: call_service_tool, entity_action, search_entities_tool, domain_summary_tool, system_overview, restore_dashboard, list_dashboard_backups. Mixed conventions like search_entities_tool/suffix '_tool' and camelCase-less words like 'system_overview' create inconsistency, though most are readable.
29 tools is on the heavy side. The dashboard CRUD cluster (add_card, update_card, remove_card, move_card, add_view, remove_view, update_view, list_view_sections, restore_dashboard, set_dashboard_config, get_dashboard_config) plus history/statistics tools and system overview tools make the surface feel broad. While each tool serves a real purpose, the count is approaching the upper bound where agents may struggle to select among many options.
Core coverage is strong: entity reads, writes, service calls, dashboard CRUD with backups and restore, history and statistics queries, plus system diagnostics. Minor gaps: no explicit entity create/delete (though call_service_tool can cover some), no persistent state management, and no dashboard section mutation beyond listing. But the lifecycle for the stated domain (entity control, dashboard editing, history) is well covered.
Maintenance
Related MCP Connectors
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
A TypeScript MCP server for Home Assistant, enabling programmatic management of entities, automati…
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
An MCP server that provides an API to LLMs to manage their JumpCloud resources.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that integrates with Home Assistant to provide smart home control capabilities through natural language, supporting devices like lights, climate systems, locks, alarms, and humidifiers.3MIT
- AlicenseAqualityBmaintenanceA Model Context Protocol server that enables AI assistants like Claude to interact directly with Home Assistant, allowing them to query device states, control smart home entities, and perform automation tasks.29351MIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that allows large language models to control and query Home Assistant smart home systems through natural language interactions.34 npm5MIT
- AlicenseAqualityCmaintenanceA self-hosted MCP server for Home Assistant that exposes full control over entity states, service calls, history, templates, and areas via local stdio, enabling AI assistants to manage your smart home.9112 npmMIT