Home Assistant MCP
Provides comprehensive tools for managing and interacting with Home Assistant, covering entities, devices, areas, automations, climate, lights, media, vacuums, energy, dashboards, schedules, to-do lists, backups, and system health.
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., "@Home Assistant MCPSet the thermostat to 72 degrees"
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.
Home Assistant MCP
An OAuth-protected Model Context Protocol (MCP) server for securely connecting ChatGPT, Codex, and other MCP clients to Home Assistant.
The project exposes 120 typed tools for discovery, dashboards, schedules, climate, energy, media, cleaning, irrigation, automations, diagnostics, and carefully bounded device control. It keeps Home Assistant's API private and deliberately avoids becoming a generic shell, log reader, network scanner, or unrestricted service proxy.
This is a security-sensitive reference implementation for a self-hosted Home Assistant installation. Read thesecurity model, replace every example value, and review the allowlists before connecting it to a real home.
Highlights
Typed Home Assistant access: entities, devices, areas, history, weather, calendars, schedules, statistics, integrations, dashboards, to-do lists, automations, backups, and system health.
Bounded writes: climate, lights, scenes, media players, vacuums, covers, locks, sirens, notifications, dashboards, schedules, calendars, to-do items, and automations use validated inputs and narrow service allowlists.
Sprinkler support: evidence-labelled controller and command status, advanced zone configuration, modeled moisture, rolling per-zone history, native schedule/upcoming-run reads, weather/skip decisions, exact-second zone or sequence starts, confirmed logical-run pause/resume/current-zone skip, and idempotent stop operations.
Energy and SolarEdge: production, module comparison, power flow, energy breakdowns, storage summaries, telemetry, alerts, and a versioned Home Assistant bridge with privacy-filtered scalar entities and durable export event history.
Persistent capability sync: compares Home Assistant's current service registry with the reviewed release baseline every five minutes and reports drift without dynamically exposing new writes.
Sanitized diagnostics: optional fixed-route, host/runtime, outage, and fixed-subnet LAN evidence with strict limits and no raw addresses, arbitrary targets, commands, or device control.
OAuth-native remote access: authorization code flow with S256 PKCE, dynamic client registration, scoped access tokens, and MCP resource metadata.
Version 2.7.12 currently advertises 120 tools. See CHANGELOG.md for release history.
Related MCP server: Home Assistant MCP Server
Architecture
flowchart LR
Client[ChatGPT, Codex, or MCP client]
Edge[HTTPS edge<br/>Cloudflare Worker, tunnel, or reverse proxy]
MCP[Home Assistant MCP<br/>OAuth + typed tools]
HA[Private Home Assistant API]
Data[(OAuth, audit, and<br/>capability-sync state)]
Collector[Optional root-owned<br/>diagnostics collector]
Export[Sanitized read-only export]
Client -->|HTTPS + OAuth/PKCE| Edge
Edge -->|loopback or shared-secret origin| MCP
MCP -->|long-lived service token| HA
MCP --> Data
Collector --> Export --> MCPThe reference deployment binds the MCP service to 127.0.0.1:8000. Only the
HTTPS edge is public. Home Assistant can remain local to the host or reachable
over a private network.
Tool surface
Area | Examples | Access |
Home model | Entities, devices, areas, registry, history, weather | Read |
Dashboards and statistics | List/read/create/update dashboards; long-term statistics | Read/write |
Climate and schedules | Targets, modes, fan modes, presets, weekly schedules, time helpers | Read/write |
Media and cleaning | Browse/play media, TTS, Cast dashboards, vacuum rooms and fan speed | Read/write |
Irrigation | Status, zones, history, schedules, exact runs, pause/resume/skip/stop | Read/write |
Organization | Calendars, to-do lists, automations, notifications | Read/write |
Energy | SolarEdge summaries, power flow, storage, telemetry, and alerts | Read; optional authorization write |
Operations | Backups, capability drift, fixed routes, host/runtime, outages, LAN nodes | Read; backup creation is confirmed write |
Higher-risk actions are annotated as destructive and require an explicit confirmation argument. The exact registry is authoritative; inspect it from an authenticated MCP client after deployment.
Requirements
Home Assistant reachable from the MCP host.
A dedicated Home Assistant long-lived access token. Use a separate service identity when possible.
Python 3.12 or newer and uv for development and tests.
Docker with Compose for the reference container deployment.
A public HTTPS URL for remote MCP clients.
An HTTPS edge that reaches the MCP over loopback or injects the configured origin shared secret. The included Caddy and Cloudflare examples demonstrate those two patterns.
Linux and systemd only if using the optional host diagnostics collector.
The bundled Compose file is a production reference, not a universal one-command
installer. It assumes host networking, an existing Home Assistant configuration
at /opt/homeassistant/config, and an installed diagnostics export at
/var/lib/ha-host-diagnostics/export. Adapt those mounts to your installation
without exposing the Home Assistant API or Docker socket.
Quick start for development
Clone the repository and install the locked dependencies:
git clone https://github.com/shogun301/ha-chatgpt-mcp.git
cd ha-chatgpt-mcp
uv sync --frozenThe test suite and public-source audit do not need production credentials:
uv run python scripts/release_integrity.py
uv run python scripts/public_release_audit.py --history
uv run --with pytest python -m pytest tests collector/tests home_assistant/testsTo run the service, copy .env.example to an ignored .env, replace every
example domain and entity ID, and provide the required runtime paths and secret
files described below. The application does not automatically load .env;
export the variables in your process manager, use uvicorn --env-file .env, or
let Docker Compose load it.
For a local process after configuring the environment:
uv run uvicorn app.server:app --host 127.0.0.1 --port 8000 --no-proxy-headersFor the reference container deployment after adapting its mounts and optional integrations:
docker compose build --pull
docker compose up -d
curl --fail http://127.0.0.1:8000/healthzDo not bind Uvicorn directly to a public interface.
Configuration
Core settings
Variable | Purpose |
| Public HTTPS base URL for the MCP service; clients connect to |
| Public Home Assistant frontend URL used only by fixed-route diagnostics. |
| Comma-separated public hostnames accepted by the transport. |
| Private Home Assistant origin, such as |
| Loopback MCP origin used by fixed-route comparisons. |
| Name shown in OAuth and MCP metadata. |
| Writable SQLite path for OAuth state. |
| Writable JSONL audit path. |
| Read-only Home Assistant configuration mount used for safe backups and reads. |
| Writable directory for pre-change configuration backups. |
| Read-only sanitized collector export; optional diagnostics report unavailable if absent. |
Entity-specific variables in .env.example map the generic tool surface to one
deployment's presence, notification, vacuum, sprinkler, thermostat, and schedule
entities. Keep real entity IDs in local configuration, not in Git.
Sprinkler controller entities and zone entities may use different prefixes;
configure SPRINKLER_ENTITY_PREFIX and SPRINKLER_ZONE_ENTITY_PREFIX
respectively. Forecast-adjusted irrigation automations may use only the
logical-run wyzeapi.run_sprinkler_sequence, pause_sprinkler,
resume_sprinkler, and stop_sprinkler services, targeted to the exact current
controller device with bounded literal zone and runtime inputs. Set
AUTOMATION_DAILY_FORECAST_ENTITY to one exact weather entity to allow a daily
weather.get_forecasts request with a bounded literal response variable.
Wyze's private sprinkler API has no stable official programming contract. The
bundled home_assistant/wyzeapi_overlay
adds four response-only services, seven bounded command services, and preserves exact native identifiers while
normalizing zones as zone-1 through zone-8. Every sprinkler output labels
its evidence as commanded, controller-reported, calculated, inferred, or
physically measured. Current state is never described as physical valve-open
feedback. Home Assistant owns every logical run timer and ordered queue: it
stops at the requested second, requires controller-reported idle before
advancing, and retains the current remainder and queue while paused. See the
capability matrix for confirmed
semantics and upstream limits.
MCP clients should read get_sprinkler_command_status.logical_run before a
pause, resume, or skip when eligibility is not already known. The dedicated
tools accept only confirmed; each requires explicit current-turn confirmation,
is non-idempotent, and must not be retried automatically. Read status once after
submission. skip_sprinkler_zone stops the current zone and advances only an
active dashboard-owned multi-zone Quick Run with a queued next zone. It does not
skip a native scheduled program and is excluded from generic service routing and
automation construction.
Required secret files
The server reads secrets from files rather than environment values:
Variable | File contents |
| Dedicated Home Assistant long-lived access token. |
| Argon2 hash for the human OAuth sign-in password. |
| Random secret used to sign access tokens. |
| Random secret shared only with the HTTPS edge. |
Generate random values with a cryptographically secure generator. An Argon2 password hash can be produced without placing the password in shell history:
uv run python -c "from argon2 import PasswordHasher; from getpass import getpass; print(PasswordHasher().hash(getpass('OAuth password: ')))"
uv run python -c "import secrets; print(secrets.token_urlsafe(48))"Store the outputs in separate files with owner-only permissions. Never commit
secrets/, .env, tokens, passwords, hashes, private domains, entity
inventories, schedules, or network topology.
Optional SolarEdge configuration
SolarEdge support uses optional client credentials, an encrypted token store,
bridge secret, redirect URI, and guarded portal fallback credentials. If you do
not use SolarEdge, omit the corresponding SOLAREDGE_*_FILE variables. The
reference Compose file sets those paths, so either provide the files or remove
those entries in your local override.
OAuth scopes
mcp:readpermits read tools.mcp:writepermits the reviewed write surface and also satisfies the current strongest compatibility grant.mcp:diagnostics, together withmcp:read, permits privileged read-only host and LAN diagnostics without granting device writes.
Connect clients to https://your-mcp-host.example/mcp. The server publishes
OAuth authorization-server, protected-resource, OpenID configuration, and
dynamic client-registration metadata under the same origin.
Edge options
The application requires non-loopback requests to carry the configured origin shared secret. Two examples are included:
cloudflare/contains a narrow Cloudflare Worker proxy. It forwards only the MCP, OAuth, health, and SolarEdge callback paths, enforces a 1 MiB request limit, adds the origin secret, and strips unnecessary headers.Caddyfileprovides a same-host HTTPS reverse proxy to the loopback MCP listener.
The included cloudflared service uses a token file and publishes metrics on
loopback only. Replace all example routes and keep the MCP origin, Home
Assistant API, and metrics listener off the public network.
Capability synchronization
Home Assistant integrations can add or remove services independently of this
project. The server therefore polls Home Assistant's service registry every five
minutes and persists a release-bound baseline in
/data/ha-capability-sync.json.
get_capability_sync_status reports added or removed services and field-schema
changes across restarts. The monitor is deliberately observational: it never
calls a service and never turns an unreviewed Home Assistant service into a new
MCP write tool. New functionality should be reviewed, implemented as typed
tools, tested, and released through Git.
The reviewed Hubitat integration services remain fail-closed. Lock-code
operations, arbitrary commands, alarm/security mode, delay configuration,
token-derived hub identifiers, and free-text hub mode are not exposed through
call_service; list_services reports the exclusion reason without returning
credentials or identifiers.
Optional host and LAN diagnostics
The systemd collector under collector/ has no listener and
accepts no caller-selected command, path, container, log expression, or URL. It
publishes bounded, sanitized snapshots and ledgers to a fixed directory. The MCP
container receives only that directory as a read-only mount—never the Docker
socket, host journal, procfs, sysfs, or systemd control.
The LAN tools operate only inside one configured /24, return opaque node IDs,
use a closed TCP-service allowlist, send no application payload, and omit raw
addresses. They cannot scan arbitrary networks or control devices.
See docs/operations.md and collector/README.md for the full data model, retention limits, deployment, verification, incident, and rollback procedures.
Security model
This server is intentionally narrower than the Home Assistant API:
No shell execution, arbitrary WebSocket passthrough, arbitrary files, raw logs, Docker administration, service restart, shutdown, credential retrieval, camera imagery, or alarm disarming.
Generic Home Assistant service calls are allowlisted by domain and service; dedicated typed tools are preferred.
Inputs are schema-validated, result sizes are bounded, and sensitive diagnostic fields are recursively redacted.
Destructive or physical operations use explicit annotations and confirmation gates.
Audit records contain tool names and bounded metadata, not credentials or returned diagnostic evidence.
The container runs as an unprivileged user with a read-only filesystem, all Linux capabilities dropped, and
no-new-privilegesenabled.The public-release audit scans both the current tree and Git history before publication.
Never use a thermostat, light, lock, vacuum, sprinkler, camera, speaker, television, backup, notification, or other physical side effect as a connectivity test.
For vulnerability reporting and handling of sensitive deployment information, read SECURITY.md.
Deployment and verification
The PowerShell deployment script in
scripts/deploy-production.ps1 is an
opinionated AWS Lightsail reference. It requires explicit AWS profile, region,
instance, frontend URL, and MCP URL parameters; requires a clean Git tree;
packages the exact reviewed commit with git archive; builds, hermetically
tests, and smoke-tests the immutable image; creates backups; deploys the
transactional Wyze overlay and MCP container; verifies source identity; and
supports rollback. The host collector is installed or restarted only when an
immutable three-file content hash changes, and the tunnel is recreated only
when its own configuration block or image ID changes. The overlay deployer takes a guarded backup, requires
the exact 0.1.39 base hashes, validates Python/YAML/Home Assistant configuration,
restarts only Home Assistant, calls only four response-only read services, and
restores the backup plus restarts Home Assistant on failure. The combined
deployer finishes all MCP build, image, hermetic test, and smoke-test gates
before applying the overlay immediately ahead of MCP cutover. Any later MCP
cutover or acceptance failure restores both the prior MCP image and the prior
overlay so incompatible halves are never accepted as the final state.
Read-only acceptance also reconciles all eight configured normalized MCP zones
and retained native IDs against the live integration snapshot so a successful
but truncated controller inventory cannot pass.
Review it carefully before adapting it to another host.
Before every public push or production release:
uv sync --frozen
uv run python scripts/release_integrity.py
uv run python scripts/public_release_audit.py --history
uv run --with pytest python -m pytest tests collector/tests home_assistant/testsThen verify, without changing device state:
/healthzsucceeds locally and through the public edge.Unauthenticated and invalid-token MCP requests are rejected.
Authenticated discovery reports the expected version and tool count.
Read-only overview, capability-sync, route, and integration checks succeed.
The public Git commit, deployed artifact, and reported service version are identical.
Production procedures and rollback gates are detailed in docs/operations.md.
Contributing
Issues and pull requests are welcome when they preserve the project's bounded security model.
For new tools:
Prefer a narrow typed operation over generic passthrough.
Define read-only, idempotent, write, or destructive annotations accurately.
Validate entity domains, enums, lengths, time windows, and result limits.
Require explicit confirmation for consequential physical or administrative actions.
Add authorization, negative-path, redaction, and regression tests.
Update capability documentation and run the public history audit.
Do not include real household configuration, private URLs, credentials, logs, tokens, schedules, topology, or provider responses in an issue, fixture, screenshot, commit, or pull request.
License
No open-source license is currently included. Public visibility does not grant permission to copy, modify, or redistribute the code. Repository owners should add an explicit license before accepting reuse or redistribution.
References
See HA per-zone sprinkler schedule editing for the read/preview/update workflow.
This server cannot be deployed
Maintenance
Related MCP Connectors
- mcpOAuthcom.vibgrate
Query your team's drift, vulnerability, and upgrade data from any AI assistant. OAuth 2.1, 51 tools.
- mytesla.ioOAuthio.mytesla
Control your Tesla from your AI assistant - climate, charging, access, and security.
- mcp-serverOAuthcom.make
Give your AI agents the tools to build, manage, and run automation workflows.
Zero-setup MCP gateway securely connecting AI to your tools with authentication and workflows
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.346 npm3MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Home Assistant smart home devices through natural language. Control devices, manage automations, query entity states, and retrieve historical data across your home automation system.1MIT
- 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 gradedqualityDmaintenanceEnables AI assistants to control Home Assistant via natural language, including device control, automation management, and system monitoring.MIT