Skip to main content
Glama
hass-mcp

hass-mcp

by HiTechLabTN

hass-mcp — HiTech Lab Edition

Maintained and optimized by HiTech Lab Source: https://github.com/voska/hass-mcp

Hass-MCP

MCP Toplist

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

  1. Pull the Docker image:

    docker pull voska/hass-mcp:latest
  2. 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.json file:

    {
      "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_TOKEN with your actual Home Assistant long-lived access token e. Update the HA_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

  3. 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 host to the Docker args for the container to access Home Assistant. Alternatively, use the IP address of your machine instead of host.docker.internal.

uv/uvx

  1. Install uv on your system.

  2. 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.json file:

    {
      "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_TOKEN with your actual Home Assistant long-lived access token e. Update the HA_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

  3. The "Hass-MCP" tool should now appear in your Claude Desktop tools menu

Other MCP Clients

Cursor

  1. Go to Cursor Settings > MCP > Add New MCP Server

  2. Fill in the form:

    • Name: Hass-MCP

    • Type: command

    • Command:

      docker run -i --rm -e HA_URL=http://homeassistant.local:8123 -e HA_TOKEN=YOUR_LONG_LIVED_TOKEN voska/hass-mcp
    • Replace YOUR_LONG_LIVED_TOKEN with your actual Home Assistant token

    • Update the HA_URL to match your Home Assistant instance address

  3. 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-mcp

Replace 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.

CAUTION

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 --host only 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 8000

The 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-certificates on Linux). hass-mcp picks it up automatically via truststore.

  • In Docker (or any sandboxed runtime): bind-mount the CA file and point SSL_CERT_FILE at 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:latest

SSL_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 version

  • get_entity: Get the state of a specific entity with optional field filtering

  • entity_action: Perform actions on entities (turn on, off, toggle)

  • list_entities: Get a list of entities with optional domain filtering and search

  • search_entities_tool: Search for entities matching a query

  • domain_summary_tool: Get a summary of a domain's entities

  • list_automations: Get a list of all automations

  • call_service_tool: Call any Home Assistant service

  • restart_ha: Restart Home Assistant

  • get_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 window

  • get_statistics_range: Same, but for an explicit date/time range — useful for monthly / yearly trend queries

  • get_error_log: Get the Home Assistant error log, with optional level / integration / search_term / lines filters applied server-side so noisy logs don't blow Claude's context

  • get_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 its url_path and mode (storage / yaml)

  • get_dashboard_config: Get a dashboard's full config

  • set_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 its path / title)

  • list_view_sections: List the sections of a "sections"-type view

  • add_view / remove_view / update_view: Edit a dashboard's views

  • list_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 type

  • debug_automation: Troubleshooting help for automations that aren't working

  • troubleshoot_entity: Diagnose issues with entities

  • routine_optimizer: Analyze usage patterns and suggest optimized routines based on actual behavior

  • automation_health_check: Review all automations, find conflicts, redundancies, or improvement opportunities

  • entity_naming_consistency: Audit entity names and suggest standardization improvements

  • dashboard_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 entity

  • hass://entities/{entity_id}/detailed: Get detailed information about an entity with all attributes

  • hass://entities: List all Home Assistant entities grouped by domain

  • hass://entities/domain/{domain}: Get a list of entities for a specific domain

  • hass://search/{query}/{limit}: Search for entities matching a query with custom result limit

Development

Running Tests

uv run pytest tests/

License

MIT License

Available Tools

29 tools
add_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

    A3.7/5.0

    Scored across 29 tools

    Disambiguation3/5

    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 Consistency3/5

    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.

    Tool Count3/5

    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.

    Completeness4/5

    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

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      A 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.
      3
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      A 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.
      29
      351
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      A 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.
      9
      112 npm
      MIT