A Home Assistant Custom Component that provides an MCP (Model Context Protocol) server using HTTP transport, allowing AI assistants like Claude to interact with your Home Assistant instance over HTTP

MCP Server for Home Assistant (HTTP Transport)

A Home Assistant Custom Component that provides an MCP (Model Context Protocol) server using HTTP transport, allowing AI assistants like Claude to interact with your Home Assistant instance.

Why HTTP transport with OAuth? This project was built primarily to support MCP Streamable HTTP transport, enabling web-based clients like Claude that require OIDC and OAuth 2.0 Dynamic Client Registration (RFC 7591). Since Home Assistant already has an official MCP integration that supports SSE transport, there wasn't a need to duplicate that. For local or custom client setups, Long-Lived Access Token authentication can be enabled as an alternative.

Features

  • ๐ŸŒ HTTP transport (not SSE) - works remotely, not just locally
  • ๐Ÿ” OAuth 2.0 authentication with Dynamic Client Registration (via hass-oidc-server)
  • ๐Ÿ”‘ Long-Lived Access Token authentication (opt-in) for local and custom client setups
  • ๐Ÿ  Full Home Assistant API access (entities, services, areas, devices, history, statistics)
  • ๐Ÿ”ง Easy HACS installation
  • ๐Ÿ“ CRUD management of automations, scenes, scripts, and helper entities (input_boolean, counter, timer, schedule, and more)
  • ๐Ÿ“‹ Lovelace dashboard management (list, get/save/delete config, create/update/delete dashboards)
  • ๐Ÿฉบ System administration tools (error log, config validation, restart, system status)
  • ๐Ÿ“ YAML config file management โ€” read, write, delete files with automatic backup before every change and built-in config validation (opt-in)
  • ๐Ÿ“ท Camera & image access โ€” capture live camera frames and read saved image files for visual analysis (opt-in)
  • ๐Ÿ“Š Resources, prompts, and completions for richer AI interactions
  • ๐Ÿงน Optimization prompts for auditing automations, naming conventions, and scheduling

Prerequisites

The integration supports two authentication methods:

  • OAuth 2.0 (default): Required for browser-based clients like Claude. Requires hass-oidc-server to be installed and configured.
  • Long-Lived Access Tokens (opt-in): For local agents and custom MCP clients that can't run an OAuth browser flow. No extra dependencies. Must be enabled in the integration settings.

You can use both methods at the same time. When both are active, the server tries OAuth first and falls back to the Long-Lived Access Token.

Installation

HACS (Recommended)

  1. Open HACS in Home Assistant
  2. Search for "MCP Server"
  3. Click "Download"
  4. Restart Home Assistant
  5. Configure the integration (see Configuration section below)

Manual Installation

  1. Copy the custom_components/mcp_server_http_transport folder to your Home Assistant custom_components directory
  2. Restart Home Assistant
  3. Configure the integration (see Configuration section below)

Configuration

  1. Go to Settings > Devices & Services
  2. Click "Add Integration"
  3. Search for "MCP Server"
  4. Choose your authentication method:
    • Leave "Enable native Home Assistant authentication" unchecked for OAuth-only (requires hass-oidc-server)
    • Check it to allow Long-Lived Access Tokens (can be used alongside OAuth or on its own)

You can change this setting later via Settings > Devices & Services > MCP Server > Configure.

Usage with Claude in Browser (OAuth)

This requires the hass-oidc-server integration to be installed.

The MCP server uses OAuth 2.0 Dynamic Client Registration (DCR), which allows Claude to automatically register itself without manual client setup.

  1. In Claude (claude.ai):

    • Open Profile (bottom left corner)
    • Click Settings (gear icon)
    • Navigate to "Connectors"
    • Click "Add custom connector"
    • Enter your MCP server URL: https://your-home-assistant.com/api/mcp
    • Click "Connect"
  2. Claude will automatically:

    • Discover your Home Assistant's OAuth endpoints
    • Register itself as an OAuth client
    • Redirect you to Home Assistant for authentication
    • Request access to your Home Assistant data
  3. In Home Assistant:

    • Log in if not already authenticated
    • Review the permissions requested by Claude
    • Click "Authorize" to grant access

That's it! Claude will now be able to interact with your Home Assistant instance through the MCP server.

Usage with Long-Lived Access Tokens

For local agents or MCP clients that can't run an OAuth browser flow, you can authenticate with a Home Assistant Long-Lived Access Token. This must be enabled first.

  1. Enable native authentication: Settings > Devices & Services > MCP Server > Configure > check "Enable native Home Assistant authentication"
  2. Create a token: go to your Home Assistant user profile > Long-Lived Access Tokens > Create Token
  3. Configure your MCP client to send the token as a Bearer header to http://your-home-assistant:8123/api/mcp

MCP Capabilities

Tools

Entities & State

Tool Description
get_state Get the current state of any entity (optional fields to limit attributes)
batch_get_state Get state for multiple entities in one call (max 50)
list_entities List all entities, with optional domain, detailed, and fields parameters
search_entities Search entities by friendly name, device class, domain, or area
call_service Call any Home Assistant service
fire_event Fire a custom event on the Home Assistant event bus
get_history Get state history of an entity over a time range
get_logbook Fetch logbook entries for an entity or time range
get_statistics Fetch long-term statistics (energy, climate) with configurable period
render_template Evaluate a Jinja2 template

Automations, Scenes & Scripts

Tool Description
list_automations List all automations with full configuration
get_automation_config Get full configuration of a single automation
create_automation Create a new automation
update_automation Update an existing automation
delete_automation Delete an automation
list_scenes List all scenes with full configuration
get_scene_config Get full configuration of a single scene
create_scene Create a new scene
update_scene Update an existing scene
delete_scene Delete a scene
list_scripts List all scripts with full configuration
get_script_config Get full configuration of a single script
create_script Create a new script
update_script Update an existing script
delete_script Delete a script

Helpers

Tool Description
list_helpers List all helper entities, optionally filtered by domain
get_helper_config Get the raw stored configuration of a UI-managed helper (experimental)
create_helper Create a new helper (input_boolean, input_number, input_text, input_select, input_datetime, input_button, counter, timer, schedule) (experimental)
update_helper Update an existing UI-managed helper by entity ID (experimental)
delete_helper Delete a UI-managed helper by entity ID (experimental)

Config Files

Tool Description
list_config_files List all YAML files in the config directory (first level, secrets excluded)
get_config_file Read the contents of a YAML config file (max 1 MB)
save_config_file Write or replace a YAML config file; auto-backs up all files first, then validates config
delete_config_file Delete a YAML config file; auto-backs up all files first
batch_edit_config_files Write and/or delete multiple YAML files in one call; one backup and one config check for the whole batch
backup_config_files Manually snapshot all YAML files into mcp_backups/<timestamp>/
list_config_backups List all available backup snapshots, newest first
restore_config_backup Restore files from the latest or a specific backup; creates a pre-restore snapshot of the current state and runs config validation after restoring
cleanup_config_backups Delete backup snapshots older than N days (default 30); keeps the folder from growing indefinitely

Dashboards

Tool Description
list_dashboards List all Lovelace dashboards with metadata
get_dashboard_config Get full dashboard configuration (views/cards)
save_dashboard_config Save (replace) full dashboard configuration
delete_dashboard_config Reset a dashboard configuration to empty
create_dashboard Create a new Lovelace dashboard (experimental)
update_dashboard Update dashboard metadata (experimental)
delete_dashboard Delete a dashboard and its config (experimental)

System & Infrastructure

Tool Description
get_config Get Home Assistant configuration (version, location, units, timezone)
get_system_status System overview: version, domain counts, entity totals, problem entities
get_domain_stats Aggregate stats for a single domain (count, state breakdown, examples)
check_config Validate Home Assistant configuration without restarting
restart_ha Restart Home Assistant (requires explicit confirmation)
get_error_log Fetch the Home Assistant error log (last N lines)
list_areas List all areas
list_devices List devices, optionally filtered by area
list_services List available services, optionally filtered by domain
list_integrations List installed integrations and their status
list_labels List all labels for cross-domain grouping

Camera & Images

These tools are disabled by default; enable them per capability via Settings โ†’ Devices & Services โ†’ MCP Server โ†’ Configure. They return images directly to the model for visual analysis.

Tool Description
get_camera_image Capture the current frame from a camera entity (optional width/height to downscale); no snapshot file is written (requires "Enable camera image access")
get_image_file Read an image file (JPEG, PNG, GIF, WebP) from an allowed directory, e.g. a snapshot saved by camera.snapshot (requires "Enable image file access")

Resources

URI Description
hass://config Home Assistant configuration
hass://areas All areas
hass://devices All registered devices
hass://services All available services by domain
hass://floors All configured floors
hass://entities All entities organized by domain
hass://labels All labels
hass://integrations Installed integrations with status
hass://entity/{entity_id} State and attributes of a specific entity
hass://dashboard/{url_path} Full configuration of a specific dashboard
hass://entities/domain/{domain} Entities filtered by a specific domain

Prompts

Prompt Description
troubleshoot_device Diagnose issues with a specific entity
daily_summary Summarize recent activity across all entities
automation_review Review an automation's config for issues and improvements
energy_report Summarize energy consumption data over a time range
setup_guide Guided troubleshooting for an entity in a problem state
automation_builder Step-by-step guided automation creation
automation_debugger Debug why an automation is not firing or misbehaving
automation_audit Audit all automations for conflicts, redundancies, and anti-patterns
schedule_optimizer Analyze automation schedules and suggest timing improvements
naming_conventions Scan entity names for inconsistencies and suggest standardization
dashboard_builder Suggest a Lovelace dashboard layout for given entities or area
change_validator Pre-flight check after creating or modifying configurations
security_review Scan for security issues in entities, integrations, and configuration

Completions

Autocompletion is supported for entity_id, entity_ids, domain, service, area_id, url_path, automation_id, scene_id, script key, trigger_type, period, config_type, and helper domain arguments.

FAQ

How do I list all automations, scenes, or scripts?

Use the dedicated list tools to get full configurations:

list_automations()   // all automations with triggers, conditions, actions
list_scenes()        // all scenes with entity states
list_scripts()       // all scripts with sequences

To get the configuration of a single item:

get_automation_config(automation_id="abc-123")
get_scene_config(scene_id="def-456")
get_script_config(key="morning_routine")

You can also use list_entities(domain="automation") to get entity states, but the tools above return the full YAML configuration.

How do I create an automation?

Use create_automation with a standard HA automation config:

create_automation(config={
  "alias": "Turn on lights at sunset",
  "trigger": [{"platform": "sun", "event": "sunset"}],
  "action": [{"service": "light.turn_on", "target": {"entity_id": "light.living_room"}}]
})

The same pattern applies to scenes and scripts. Scripts use a key parameter instead of an auto-generated ID:

create_script(key="morning_routine", config={
  "alias": "Morning Routine",
  "sequence": [{"service": "light.turn_on", "target": {"entity_id": "light.bedroom"}}]
})
How do I call a service like turning on a light?

Use call_service with the domain, service, and optionally an entity and extra data:

call_service(domain="light", service="turn_on", entity_id="light.living_room", data={"brightness": 200})

To discover what services are available:

list_services()                    // all services
list_services(domain="light")      // just light services
How do I manage Lovelace dashboards?

Use list_dashboards to see all dashboards, then get_dashboard_config and save_dashboard_config to read and modify their content. Use url_path="default" for the main Overview dashboard:

get_dashboard_config(url_path="default")
save_dashboard_config(url_path="default", config={"views": [{"title": "Home", "cards": [...]}]})

To create or delete dashboards themselves, use the experimental create_dashboard and delete_dashboard tools. These use internal HA APIs and may break with future HA updates.

How do I manage helper entities (input_boolean, counter, timer, etc.)?

Use list_helpers to see all helpers, optionally filtered by type:

list_helpers()                          // all helper types
list_helpers(domain="input_boolean")    // only toggles

To create a helper, specify the domain and a config with at least a name:

create_helper(domain="input_boolean", config={"name": "Vacation Mode", "icon": "mdi:palm-tree"})
create_helper(domain="input_number", config={"name": "Target Temperature", "min": 15, "max": 30, "step": 0.5, "unit_of_measurement": "ยฐC"})
create_helper(domain="input_select", config={"name": "House Mode", "options": ["Home", "Away", "Sleep"]})
create_helper(domain="counter", config={"name": "Motion Events", "initial": 0, "step": 1})
create_helper(domain="timer", config={"name": "Cooking Timer", "duration": "00:30:00"})

To update or delete, use the entity ID:

update_helper(entity_id="input_boolean.vacation_mode", config={"name": "Vacation Mode", "icon": "mdi:airplane"})
delete_helper(entity_id="counter.motion_events")

Note: These tools only manage UI-created helpers stored in Home Assistant's .storage/ files. Helpers defined in YAML configuration are read-only from the perspective of these tools.

How do I read or edit YAML configuration files?

Use list_config_files to see all editable YAML files, then get_config_file and save_config_file to read and modify them:

list_config_files()
get_config_file(filename="automations.yaml")
save_config_file(filename="automations.yaml", content="...")

save_config_file automatically runs a full Home Assistant config validation after every save and reports any errors inline. Pass run_check: false to skip this.

To remove a custom file:

delete_config_file(filename="my_custom.yaml")

When editing multiple files in one session use batch_edit_config_files instead โ€” it creates one backup snapshot before all changes and runs one config check at the end:

batch_edit_config_files(
    saves=[
        {"filename": "templates.yaml", "content": "..."},
        {"filename": "sensors.yaml",   "content": "..."},
    ],
    deletes=["binary_sensor.yaml", "old_lights.yaml"],
)

Both saves and deletes are optional โ€” you can use either or both in the same call.

Note: Only first-level .yaml/.yml files in the config directory are accessible. Subdirectories and non-YAML files are blocked. The following files are also blocked from direct edits โ€” use the dedicated tools instead:

  • secrets.yaml โ€” never readable, contains credentials
  • automations.yaml, scenes.yaml, scripts.yaml โ€” owned by Home Assistant's storage layer; use create_automation / update_automation / delete_automation (and the equivalents for scenes and scripts) so UI-managed entries stay consistent. These files are still included in backups, so a restore never drops them.
How do I let the AI see a camera or analyze an image?

Camera and image access are disabled by default. Enable them per capability via Settings โ†’ Devices & Services โ†’ MCP Server โ†’ Configure: "Enable camera image access" for live camera frames, and "Enable image file access" for reading saved image files.

To analyze what a camera sees right now, capture the current frame directly โ€” no snapshot file is needed:

get_camera_image(entity_id="camera.front_door")
get_camera_image(entity_id="camera.front_door", width=1024)

To analyze a snapshot already saved to disk (for example by the camera.snapshot service), read it back by path:

get_image_file(path="www/snapshots/front_door.jpg")
get_image_file(path="/config/www/snapshots/front_door.jpg")

The image is returned directly to the model for analysis. get_image_file supports JPEG, PNG, GIF, and WebP, and can only read from directories Home Assistant is allowed to access (the config directory and configured media dirs) โ€” the same allowlist that governs where camera.snapshot can write.

How does the automatic backup work?

Every call to save_config_file and delete_config_file automatically creates a full snapshot of all first-level YAML files (excluding secrets.yaml) before making any change. When using batch_edit_config_files, only one backup is created for the entire batch โ€” regardless of how many files are saved or deleted. Snapshots are stored in:

config/mcp_backups/2026-04-26_14-30-00-123456/

The backup path is included in the tool response so you always know where to look. You never need to remember to back up manually before an edit โ€” it happens every time.

To create an additional manual snapshot before a larger operation:

backup_config_files()

To see all available snapshots:

list_config_backups()

To restore the latest snapshot (or a specific one by timestamp):

restore_config_backup()
restore_config_backup(timestamp="2026-04-26_14-30-00-123456")

restore_config_backup only overwrites files present in the backup โ€” files created after the snapshot are left untouched. Before any files are overwritten it creates a pre-restore snapshot of the current state, so you can always roll back from a restore (the snapshot path is included in the response). A config check runs automatically after restoring.

If Home Assistant fails to start after a bad edit: backup files are always accessible at config/mcp_backups/<timestamp>/ and can be copied back manually via the filesystem or SSH.

Restoring a single file: restore_config_backup always restores all files from a snapshot at once โ€” there is no tool to restore a single file. If you only need one file back, either restore the full snapshot and re-apply your other changes, or copy the file manually from config/mcp_backups/<timestamp>/<filename> via SSH, Samba, or the File Editor add-on.

Cleaning up old backups: Snapshots accumulate with every edit. Use cleanup_config_backups to remove old ones:

cleanup_config_backups()                    // delete backups older than 30 days (default)
cleanup_config_backups(older_than_days=7)   // delete backups older than 7 days

You can also delete entries from config/mcp_backups/ manually via SSH, the Samba share, or the File Editor add-on.

What does "experimental" mean for some tools?

Some tools use internal Home Assistant APIs that are not publicly exposed and may break with future HA updates.

Dashboard tools: create_dashboard, update_dashboard, and delete_dashboard use DashboardsCollection and replicate side effects (panel registration, dashboards dict updates) that HA normally handles internally. The config-level tools (list_dashboards, get/save/delete_dashboard_config) use stable public APIs and are not experimental.

Helper tools: get_helper_config, create_helper, update_helper, and delete_helper use StorageCollection internals to manage UI-created helpers. They only affect helpers stored in .storage/ โ€” helpers defined in YAML are read-only from the perspective of these tools. list_helpers uses public APIs and is not experimental.

License

MIT

MCP Server ยท Populars

MCP Server ยท New