Linux MCP Server
OFFICIAL SERVERDiagnose and troubleshoot Linux hosts, local or over SSH, with read-only system inspection tools
Control, configure and debug a Home Assistant smart home from any MCP client
By The Unofficial Home Assistant AI Toolkit Python Local · stdio DevOps and monitoringProductivity
93 popularity score ★ 5.5k ↓ 230k/mo
Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.
It needs HOMEASSISTANT_URL, HOMEASSISTANT_TOKEN. Replace each <NAME> with your value.
claude mcp add home-assistant-ha -e HOMEASSISTANT_URL=<HOMEASSISTANT_URL> -e HOMEASSISTANT_TOKEN=<HOMEASSISTANT_TOKEN> -- uvx ha-mcp@latest{
"mcpServers": {
"home-assistant-ha": {
"command": "uvx",
"args": [
"ha-mcp@latest"
],
"env": {
"HOMEASSISTANT_URL": "<HOMEASSISTANT_URL>",
"HOMEASSISTANT_TOKEN": "<HOMEASSISTANT_TOKEN>"
}
}
}
}{
"mcpServers": {
"home-assistant-ha": {
"command": "uvx",
"args": [
"ha-mcp@latest"
],
"env": {
"HOMEASSISTANT_URL": "<HOMEASSISTANT_URL>",
"HOMEASSISTANT_TOKEN": "<HOMEASSISTANT_TOKEN>"
}
}
}
}{
"servers": {
"home-assistant-ha": {
"type": "stdio",
"command": "uvx",
"args": [
"ha-mcp@latest"
],
"env": {
"HOMEASSISTANT_URL": "<HOMEASSISTANT_URL>",
"HOMEASSISTANT_TOKEN": "<HOMEASSISTANT_TOKEN>"
}
}
}
}[mcp_servers.home-assistant-ha]
command = "uvx"
args = ["ha-mcp@latest"]
[mcp_servers.home-assistant-ha.env]
HOMEASSISTANT_URL = "<HOMEASSISTANT_URL>"
HOMEASSISTANT_TOKEN = "<HOMEASSISTANT_TOKEN>"gemini mcp add --scope user -e HOMEASSISTANT_URL=<HOMEASSISTANT_URL> -e HOMEASSISTANT_TOKEN=<HOMEASSISTANT_TOKEN> home-assistant-ha uvx -- ha-mcp@latestOpens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.
It needs HOMEASSISTANT_URL, HOMEASSISTANT_TOKEN. Replace each <NAME> with your value.
claude mcp add home-assistant-ha -e HOMEASSISTANT_URL=<HOMEASSISTANT_URL> -e HOMEASSISTANT_TOKEN=<HOMEASSISTANT_TOKEN> -- docker run -i --rm -e HOMEASSISTANT_URL -e HOMEASSISTANT_TOKEN ghcr.io/homeassistant-ai/ha-mcp{
"mcpServers": {
"home-assistant-ha": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"HOMEASSISTANT_URL",
"-e",
"HOMEASSISTANT_TOKEN",
"ghcr.io/homeassistant-ai/ha-mcp"
],
"env": {
"HOMEASSISTANT_URL": "<HOMEASSISTANT_URL>",
"HOMEASSISTANT_TOKEN": "<HOMEASSISTANT_TOKEN>"
}
}
}
}{
"mcpServers": {
"home-assistant-ha": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"HOMEASSISTANT_URL",
"-e",
"HOMEASSISTANT_TOKEN",
"ghcr.io/homeassistant-ai/ha-mcp"
],
"env": {
"HOMEASSISTANT_URL": "<HOMEASSISTANT_URL>",
"HOMEASSISTANT_TOKEN": "<HOMEASSISTANT_TOKEN>"
}
}
}
}{
"servers": {
"home-assistant-ha": {
"type": "stdio",
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"HOMEASSISTANT_URL",
"-e",
"HOMEASSISTANT_TOKEN",
"ghcr.io/homeassistant-ai/ha-mcp"
],
"env": {
"HOMEASSISTANT_URL": "<HOMEASSISTANT_URL>",
"HOMEASSISTANT_TOKEN": "<HOMEASSISTANT_TOKEN>"
}
}
}
}[mcp_servers.home-assistant-ha]
command = "docker"
args = ["run", "-i", "--rm", "-e", "HOMEASSISTANT_URL", "-e", "HOMEASSISTANT_TOKEN", "ghcr.io/homeassistant-ai/ha-mcp"]
[mcp_servers.home-assistant-ha.env]
HOMEASSISTANT_URL = "<HOMEASSISTANT_URL>"
HOMEASSISTANT_TOKEN = "<HOMEASSISTANT_TOKEN>"gemini mcp add --scope user -e HOMEASSISTANT_URL=<HOMEASSISTANT_URL> -e HOMEASSISTANT_TOKEN=<HOMEASSISTANT_TOKEN> home-assistant-ha docker -- run -i --rm -e HOMEASSISTANT_URL -e HOMEASSISTANT_TOKEN ghcr.io/homeassistant-ai/ha-mcpHOMEASSISTANT_URL |
Required: Address of your Home Assistant instance, starting with http:// or https://. |
|---|---|
HOMEASSISTANT_TOKEN secret |
Required: Long-lived access token (an administrator's is recommended); demo uses the public demo token. |
READ_ONLY_MODE |
Optional: Hide tools that change anything and block writes. |
DISABLED_TOOLS |
Optional: Comma-separated tool names to turn off. |
ENABLE_TOOL_SECURITY_POLICIES |
Optional: Apply per-tool approval policies. |
REDACT_SECRETS |
Optional: Mask secrets in tool output. |
HA_VERIFY_SSL |
Optional: Verify Home Assistant's TLS certificate. |
| Set together: tool search | |
ENABLE_TOOL_SEARCH |
Optional: Replace the full tool list with search-based discovery. |
TOOL_SEARCH_MAX_RESULTS |
Optional: Results per tool search, 2 to 10. |
| Set together: beta | |
ENABLE_BETA_FEATURES |
Optional: Master switch for beta tools; each also needs its own flag. |
HAMCP_ENABLE_FILESYSTEM_TOOLS |
Optional: Turn on file read and write tools (with ENABLE_BETA_FEATURES and the custom component). |
ENABLE_YAML_CONFIG_EDITING |
Optional: Turn on configuration.yaml editing (with ENABLE_BETA_FEATURES and the custom component). |
In a container, a setting goes in with -e NAME=value after docker run.
ha-mcp is an unofficial MCP server for Home Assistant. Besides reading live states, calling any service and controlling many devices in one call, it builds and maintains the setup itself: automations, scripts, scenes, helpers, dashboards, areas, zones, groups, calendars, to-do lists, blueprints, backups, updates, apps (add-ons), HACS, radios and the device and entity registries. For debugging it reads history, long-term statistics, logs, camera snapshots and automation traces, and renders templates.
The tool data shipped with the current release counts 87 tools; 60 are listed here. A few are beta and stay hidden until switched on: file reading and writing, configuration.yaml editing, dashboard screenshots and a code mode that runs short Python snippets in a sandbox (capped at 30 seconds and 10 MB of memory by default).
The recommended install is the HA-MCP integration, named HA-MCP Custom Component in older releases. It runs the server inside Home Assistant 2026.8.0 or newer. On Home Assistant 2026.11 and newer it comes from the built-in Marketplace, whose default catalog holds it, so no GitHub connection or custom repository is needed. On 2026.8 to 2026.10 it comes from HACS, and it can also be copied in by hand. Setup asks for an administrator access token, or the user name and password of an admin account made for HA-MCP, and for how clients may connect: remote access through Home Assistant, the local network, or both. Both start off. On Home Assistant OS and Supervised it can also run as an app (add-on) that needs no token. Elsewhere it runs from the Docker image or PyPI package with your Home Assistant URL and a long-lived token. Its makers recommend streamable HTTP over the stdio mode of the client snippets here for real use.
Optional settings include Read Only Mode, which hides write tools, per-tool disabling, approval policies, secret redaction, automatic backups before edits, custom instructions and search-based tool discovery for smaller models.
| Runtime | Python 3.13+ |
|---|---|
| Runs on | macOS, Windows, Linux |
| Home Assistant | Your own instanceadmin long-lived access token, or a dedicated admin account for the custom component; the app needs none |
| Also |
|
For Docker or PyPI, create a token in Home Assistant under your profile, Security, Long-lived access tokens, and set HOMEASSISTANT_URL to your instance's address. Setting HOMEASSISTANT_TOKEN to demo with the public demo URL from the docs connects to a hosted demo instead. The custom component asks for an administrator token or the sign-in of an admin account made for it, then shows the connect URL on its Configure screen under Settings, Devices & Services. The app needs no token and prints its connect URL in its log.
Suits people running their own Home Assistant who want a client to set up and troubleshoot it, not just switch devices: it writes automations, dashboards and registry entries and reads logs and traces. Because it can change and restart the whole system, start with Read Only Mode or a dedicated account if you only want to look. For plain voice-style control of a chosen set of entities, Home Assistant's own Model Context Protocol Server integration works through Assist and its exposed entities with Home Assistant sign-in, without a separate install. It is a community project, not published by Home Assistant.
26 only read, 23 change things, 11 can delete or overwrite. A ? marks an optional parameter.
ha_searchquery?: stringdomain_filter?: stringarea_filter?: stringsearch_types?: anylimit?: integeroffset?: integerexact_match?: booleaninclude_hidden?: booleaninclude_config?: booleangroup_by_domain?: booleanper_domain_limit?: integerstate_filter?: stringresult_fields?: anyfields?: anyconfig_time_budget?: numberha_get_overviewdetail_level?: enumdomains?: anylimit?: integeroffset?: integermax_entities_per_domain?: integerinclude_state?: booleaninclude_entity_id?: booleaninclude_notifications?: booleaninclude_dismissed_repairs?: booleanfields?: anyha_get_stateentity_id: anyfields?: anyattribute_keys?: anyha_call_service changesdomain?: stringservice?: stringentity_id?: stringdata?: objectreturn_response?: booleanwait?: booleanverbose?: booleanresult_fields?: anyresult_attribute_keys?: anyws_command?: stringha_bulk_control changesoperations?: arrayparallel?: booleanselector?: anyaction?: stringparameters?: objecttimeout_seconds?: numbervalidate_first?: booleandry_run?: booleanha_call_event changesevent_type: stringdata?: objectha_list_servicesdomain?: stringquery?: stringlimit?: integeroffset?: integerdetail_level?: enumservice_fields?: anyfields?: anyha_config_get_automationentity_id: stringha_config_set_automation changesconfig?: objectentity_id?: stringpython_transform?: stringconfig_hash?: stringtake_control_of_blueprint?: booleancategory?: stringwait?: booleanenabled?: booleanrun_actions?: booleanMandatoryBPS?: booleanBestPracticeKey?: anyha_config_remove_automation deletesentity_id: stringwait?: booleanha_config_get_scriptscript_id: stringha_config_set_script changesscript_id: stringconfig?: objectpython_transform?: stringconfig_hash?: stringtake_control_of_blueprint?: booleancategory?: stringwait?: booleanrun?: enumvariables?: objectMandatoryBPS?: booleanBestPracticeKey?: anyha_config_remove_script deletesscript_id: stringwait?: booleanha_config_get_scenescene_id?: stringquery?: stringsearch_in_config?: booleanlimit?: integeroffset?: integerha_config_set_scene changesscene_id: stringconfig?: objectpython_transform?: stringconfig_hash?: stringcategory?: stringwait?: booleanactivate?: booleanMandatoryBPS?: booleanBestPracticeKey?: anyha_config_remove_scene deletesscene_id: stringwait?: booleanha_config_get_dashboardurl_path?: stringlist_only?: booleanforce_reload?: booleanentity_id?: stringcard_type?: stringheading?: stringinclude_config?: booleaninclude_screenshot?: booleanview_path?: stringquery?: stringdescribe?: booleanha_config_set_dashboard changesurl_path: stringconfig?: objectpython_transform?: stringconfig_hash?: stringtitle?: stringicon?: stringrequire_admin?: booleanshow_in_sidebar?: booleanMandatoryBPS?: booleanBestPracticeKey?: anyreturn_screenshot?: booleanview_path?: stringpatch?: arrayha_config_delete_dashboard deletesurl_path: stringha_get_dashboard_screenshotdashboard_path?: stringurl_path?: stringview_path?: stringwidth?: integerheight?: anyviewport_presets?: arrayorientation?: anyzoom?: numberwait_ms?: integerfull_page?: booleantheme?: stringdark_mode?: booleanlanguage?: stringimage_format?: anyrender_timeout_seconds?: numberha_config_list_helpershelper_type: anylimit?: integeroffset?: integerdescribe?: booleanmenu_choice?: stringhelper_id?: stringha_config_set_helper changeshelper_type: anyname?: stringhelper_id?: stringentry_id?: stringsubentry_type?: stringsubentry_id?: stringshow_advanced_options?: booleanicon?: stringarea_id?: stringlabels?: anymin_value?: numbermax_value?: numberstep?: numberunit_of_measurement?: stringoptions?: anyinitial?: anymode?: stringhas_date?: booleanhas_time?: booleanrestore?: booleanha_remove_helpers_integrations deletestarget: stringhelper_type?: anysubentry_id?: stringconfirm?: booleanwait?: booleanha_list_floors_areasfields?: anyarea_fields?: anyha_set_area_or_floor changeskind: enumname?: stringid?: stringfloor_id?: stringlevel?: integericon?: stringaliases?: anypicture?: stringlabels?: anytemperature_entity_id?: stringhumidity_entity_id?: stringha_remove_area_or_floor deleteskind: enumid: stringha_get_zonezone_id?: stringha_set_zone changesname?: stringlatitude?: numberlongitude?: numberzone_id?: stringradius?: numbericon?: stringpassive?: booleanwait?: booleanha_config_list_groupslimit?: integeroffset?: integerha_config_set_group changesobject_id: stringentities?: arrayname?: stringicon?: stringall_on?: booleanadd_entities?: arrayremove_entities?: arraywait?: booleanha_config_get_calendar_eventsentity_id: stringstart?: stringend?: stringmax_results?: integerha_config_set_calendar_event changesentity_id: stringsummary: stringstart: stringend: stringdescription?: stringlocation?: stringrrule?: stringuid?: stringrecurrence_id?: stringrecurrence_range?: enumha_get_todoentity_id?: stringstatus?: anyha_set_todo_item changesentity_id: stringsummary?: stringitem?: stringstatus?: enumdescription?: stringdue_date?: stringdue_datetime?: stringrename?: stringmove_after?: stringha_manage_blueprints changesaction: enumdomain?: stringpath?: stringurl?: stringyaml?: stringsource_url?: stringoverwrite?: booleaninput?: objectconfirm?: booleanha_get_devicedevice_id?: stringentity_id?: stringintegration?: stringarea_id?: stringmanufacturer?: stringlimit?: integeroffset?: integerdetail_level?: enumha_set_device changesdevice_id: stringname?: stringarea_id?: stringdisabled_by?: stringlabels?: anyha_remove_device deletesdevice_id: stringha_get_entityentity_id?: anyunique_id?: stringdomain?: stringplatform?: stringha_set_entity changesentity_id: anyarea_id?: stringname?: stringuse_device_name?: booleanicon?: stringdevice_class?: stringoptions?: objectenabled?: booleanhidden?: booleanaliases?: anyuse_entity_name_alias?: booleancategories?: objectlabels?: anylabel_operation?: enumexpose_to?: objectnew_entity_id?: stringnew_device_name?: stringha_remove_entity deletesentity_id: anyha_get_historyentity_ids: anysource?: enumstart_time?: stringend_time?: stringminimal_response?: booleansignificant_changes_only?: booleanlimit?: integeroffset?: integerperiod?: stringstatistic_types?: anyorder?: enumsummary?: booleanfields?: anyinclude_schema?: booleancore_options?: objectha_get_automation_tracesautomation_id: stringrun_id?: stringlimit?: integerdeduplicate?: booleandetailed?: booleansections?: stringoffset?: integerorder?: enumha_get_logssource?: enumlimit?: integersearch?: stringorder?: enumhours_back?: integerentity_id?: stringdevice_id?: stringcontext_id?: stringend_time?: stringoffset?: anycompact?: booleanlevel?: stringstructured?: booleantop_n?: integerslug?: stringha_get_camera_imageentity_id: stringwidth?: integerheight?: integerha_get_integrationentry_id?: stringquery?: stringdomain?: stringintegration_type?: stringinclude_options?: booleaninclude_schema?: booleaninclude_subentries?: booleaninclude_subentry_schema?: booleansubentry_type?: stringsubentry_id?: stringshow_advanced_options?: booleanexact_match?: booleanlimit?: integeroffset?: integerinclude_diagnostics?: booleaninclude_ws_commands?: booleandevice_id?: stringdiagnostics_fields?: anydiagnostics_truncate_at_bytes?: integerdiagnostics_data_path?: stringha_set_integration changesentry_id?: stringenabled?: booleandomain?: stringconfig?: objectreconfigure?: booleanexpected_device_id?: stringexpected_unique_id?: stringexpected_mac?: stringexpected_entity_ids?: arraylog_level?: enumlog_persistence?: stringmenu_choice?: stringsubentry_type?: stringsubentry_id?: stringflow_id?: stringabort?: booleanws_command?: stringws_data?: objectha_get_system_healthinclude?: stringinclude_dismissed_repairs?: booleanconfig_entry_id?: stringdevice_id?: stringdiagnostics_fields?: anydiagnostics_truncate_at_bytes?: integerdiagnostics_data_path?: stringdiagnostics_data_offset?: integerdiagnostics_data_limit?: integerha_manage_backup deletesscope: enumaction: enumname?: stringbackup_id?: stringrestore_database?: booleanrestore_addons?: arrayrestore_folders?: arrayinclude_homeassistant?: booleaninclude_database?: booleaninclude_addons?: arrayinclude_all_addons?: booleaninclude_folders?: arraysafety_backup?: booleanconfirm?: booleandomain?: stringentity_id?: stringbackup_name?: stringolder_than_days?: integerlimit?: integerha_manage_updates changesaction?: stringentity_ids?: anycategories?: anyinclude_skipped?: booleaninclude_release_notes?: booleanbackup?: booleanrepairs?: arrayha_get_appsource?: enumslug?: stringinclude_stats?: booleanrepository?: stringquery?: stringha_manage_app changesslug?: stringpath?: stringmethod?: stringbody?: anydebug?: booleanport?: integeroffset?: integerlimit?: integerwebsocket?: booleanwait_for_close?: booleanmessage_limit?: integermessage_offset?: integersummarize?: booleanpython_transform?: stringoptions?: objectnetwork?: objectboot?: stringauto_update?: booleanwatchdog?: booleanarray_patch?: objectha_manage_hacs changesaction: enumrepository_id?: stringversion?: stringrepository?: stringcategory?: stringconfirm_replace_built_in?: booleanconfirm?: booleanha_eval_templatetemplate?: stringcondition?: objectvariables?: objectstrict?: booleantimeout?: integerreport_errors?: booleanha_reload_core changestarget?: stringentry_id?: stringha_restart changesconfirm?: booleansafe_mode?: booleanha_manage_radio changesradio: enumaction: stringdevice_id?: stringentity_id?: stringparams?: objectconfirm?: booleanha_read_filepath: stringtail_lines?: integeryaml_path?: stringha_write_file deletespath: stringcontent: stringoverwrite?: booleancreate_dirs?: booleanha_config_set_yaml deletesyaml_path: stringaction: stringcontent?: stringfile?: stringconfirm_token?: stringMandatoryBPS?: booleanBestPracticeKey?: any