Skip to main content
Glama
Home Assistant Admin MCP

Home Assistant Admin MCP

by lemanjo

Home Assistant Admin MCP

一个面向安全性的 Model Context Protocol (MCP) 服务器,用于检查、控制、诊断和选择性管理 Home Assistant 实例。它结合了 Home Assistant 的 REST 和 WebSocket API,以及一个可选的、受限的 Home Assistant 配置挂载。

该服务器不包含 LLM。MCP 客户端选择工具;此服务器验证输入、执行部署策略、与 Home Assistant 通信,并返回结构化结果。

[!NOTE] 本项目使用 AI 辅助开发工具构建。

[!WARNING] admin 模式可以更改设备、注册表、辅助元素、自动化、脚本、场景、集成和 YAML 配置,并且可以重启 Home Assistant。请以 read_only 模式启动,使用专用的 Home Assistant 账户,审查试运行,并且仅将 HTTP 端点暴露给受信任的客户端。

范围与边界

已实现的功能包括:

  • 运行时状态、服务/动作、事件、历史、日志、统计和当前会话日志检查,并提供精简的 system_log 回退。

  • 注册表与集成发现,包含相互关联的区域、设备、实体和配置条目。

  • 经过验证的服务调用,具有显式目标和实时的 Home Assistant 服务定义。

  • 编辑器管理的自动化、脚本和场景的读取与变更。

  • 通过 Home Assistant 内部 API 进行存储后端的辅助元素以及选定的注册表/配置条目变更。

  • 诊断、依赖分析、跨注册表/编辑器资源/允许列表 YAML 的搜索、跟踪、配置差异、检查点和有界 Git 历史。

  • 在显式文件系统允许列表下的结构化 YAML 补丁。

明确不包含的目标和限制:

  • 不提供 Home Assistant Supervisor API、附加组件管理、主机管理或 Home Assistant 备份 API。

  • 不提供 Docker API、Docker 套接字、容器生命周期、镜像管理或容器日志访问。部署不会挂载 /var/run/docker.sock。

  • 不提供任意 shell 执行或任意文件系统访问。

  • 不提供通用的 config-flow/options-flow 实现,也没有提交任意集成凭据的机制。集成工具仅读取配置条目、更改已实现的偏好设置、启用/禁用或请求重载。

  • 不假设每个 Home Assistant 用户都能调用每个端点。长期令牌继承其 Home Assistant 用户的权限和管理员状态。

Related MCP server: hass-mcp-server

架构

flowchart LR
    Client["MCP client"] -->|"Streamable HTTP + MCP bearer token"| HTTP["HTTP transport /mcp"]
    Client -->|"stdio"| Stdio["stdio transport"]
    HTTP --> Policy["MCP tools, schemas, mode, risk and confirmation policy"]
    Stdio --> Policy
    Policy --> REST["Home Assistant REST client"]
    Policy --> WS["Home Assistant WebSocket client"]
    REST --> HA["Home Assistant Core"]
    WS --> HA
    Policy --> TX["Filesystem transaction layer"]
    TX --> Mount["/ha-config allowlisted read-write mount"]
    TX --> Checkpoints[".ha-mcp/backups"]
    TX --> Git["Optional local Git commits"]
    TX -->|"check config, reload, health"| REST
    NoDocker["No Supervisor or Docker socket access"]

HTTP 传输在 MCP 处理器层是无状态的。应用程序进程仍然共享其 Home Assistant 连接/缓存,并串行化文件系统事务。

Home Assistant API 矩阵

于 2026-08-20 根据当前 Home Assistant 文档和 home-assistant/core dev 源码进行了审查。源码链接表明某个内部命令当前存在;这并不保证其稳定性。

访问类别

已实现的接口

稳定性与要求

参考

公共 REST

/api/、/api/config、/api/states、/api/services、/api/events、/api/history/period、/api/error_log、/api/config/core/check_config 和 /api/services/<domain>/<service>

Home Assistant 官方文档记载的 API。各个集成/服务以及记录器数据必须已加载。

REST API

公共 WebSocket 协议

/api/websocket 身份验证、命令、订阅、重连、subscribe_events 和 validate_config

传输层和列出的公共命令均有文档记载。此服务器对大多数公共状态/服务操作使用 REST。

WebSocket API

内部注册表 API

config/entity_registry/*、config/device_registry/* 和 config/area_registry/*

面向前端的 WebSocket 命令。变更操作需要 Home Assistant 管理员权限,且命令字段可能随版本变化。

实体注册表、设备注册表、区域注册表

内部配置条目 API

config_entries/get、get_single、update、disable,以及配置条目重载 REST

前端/配置面板实现,并非通用的集成身份验证或配置流 API。

配置条目源码

内部编辑器 API

/api/config/{automation,script,scene}/config/<id>

仅适用于由 Home Assistant 编辑器/YAML 文件管理的资源。读取、写入、删除及响应细节均对版本敏感。

automation、script、scene

内部辅助元素 API

<helper_type>/list、create、update 和 delete

针对九种已实现辅助元素类型的存储集合命令。YAML 后端和配置流后端的辅助元素不能通过此 API 进行编辑。

存储集合源码、input_boolean 示例

内部诊断 API

system_health/info、logbook/get_events、trace/list、trace/get 和记录器元数据命令

由 Home Assistant 前端/集成使用。可用性、权限和响应结构可能发生变化。

系统健康、日志、跟踪、记录器

文件系统回退

根 YAML 文件、允许列表中的 YAML 目录、本地检查点,以及 /ha-config 下可选的 Git 仓库

本地部署功能,并非 Home Assistant API。需要显式的读写挂载以及非 root 进程的主机权限。

路径策略、事务、备份

Home Assistant API 需要 Authorization: Bearer <HA token>。请参阅官方身份验证 API。MCP HTTP 端点有单独的 Bearer 令牌。

内部 API 兼容性

  • 内部端点可被重命名、限制访问或更改模式,且无需公开 API 弃用期。在生产环境启用 admin 之前,请针对确切的 Home Assistant 版本进行测试。

  • 注册表、辅助器、跟踪、系统健康、logbook WebSocket、记录器元数据、配置条目和编辑器操作在不兼容的版本上可能返回 HA_WS_UNSUPPORTED、HA_INTERNAL_API_UNAVAILABLE、HELPER_STORAGE_API_UNAVAILABLE、权限错误或响应验证错误。

  • 当前的 Home Assistant 核心将许多注册表变更和跟踪读取标记为仅限管理员操作。当需要这些工具时,请使用属于管理员的令牌;如果非管理员令牌的 Home Assistant 权限足够,则对于仅读取/控制的部署仍然适用。

  • 编辑器变更仅限于编辑器管理的 automations.yaml、scripts.yaml 和 scenes.yaml 资源。没有可用编辑器 ID 的运行中 YAML 资源会被报告为不可编辑。

  • 支持的辅助器包括 input_boolean、input_button、input_text、input_number、input_datetime、input_select、counter、timer 和 schedule。它们接受的字段由已安装的 Home Assistant 版本决定。

  • 配置条目操作不会启动配置流程、选项流程、重新认证、修复、OAuth 或凭据输入。请使用 Home Assistant 界面进行这些操作。

  • 对辅助器、注册表、区域、设备、实体和配置条目的试运行预览不会调用 Home Assistant 的变更验证器。其结果包含描述这一事实的限制说明。

生产部署

前提条件

  • 带 Compose v2 和 BuildKit 的 Docker Engine。

  • 一个可访问的、已启用 API 的 Home Assistant Core 实例。Home Assistant 的前端通常提供该 API;仅 API 安装需要 api 集成。

  • 一个 Home Assistant 长期访问令牌。

  • 如果需要文件系统、检查点、编辑器变更安全或 Git 功能,则需要一个包含 Home Assistant 配置的主机路径。

  • 允许配置的非 root UID/GID 读写该路径的主机所有权/权限。

GitHub 发布版将多架构镜像发布到 docker.io/lemanjo/hac-mcp。为获得可复现的部署,请使用确切的发布标签而非 latest。本地构建仍然受支持。

创建 Home Assistant 令牌

  1. 以该服务应代表的用户身份登录 Home Assistant。

  2. 打开用户资料,然后打开安全选项卡。

  3. 在长期访问令牌中,选择创建令牌并为此部署命名。

  4. 在显示时记录令牌;Home Assistant 不会保留令牌字符串供以后显示。

  5. 仅在需要内部管理工具时使用管理员账户。

Home Assistant 在此处记录了资料管理,并在此处记录了长期令牌。长期令牌是高价值凭据,不应提交、放入 config.example.yaml 或暴露给 MCP 客户端。

Compose 设置

cp .env.example .env
cp config.example.yaml config.yaml
install -d -m 700 secrets
openssl rand -hex 32 > secrets/mcp_auth_token
read -rsp "Home Assistant token: " HA_TOKEN
printf '%s' "$HA_TOKEN" > secrets/home_assistant_token
unset HA_TOKEN
chmod 600 secrets/home_assistant_token secrets/mcp_auth_token

在 .env 中设置以下值:

  • HOME_ASSISTANT_URL:可从容器访问。http://host.docker.internal:8123 可访问 Linux Docker 主机发布的 Home Assistant 端口,因为 Compose 会安装 host-gateway 条目。Home Assistant 的局域网 URL 也可以。

  • HA_CONFIG_PATH:现有的主机 Home Assistant 配置目录。它以读写方式挂载到 /ha-config;Compose 拒绝创建不存在的源路径。

  • MCP_SETTINGS_FILE:在进行部署特定更改后使用 ./config.yaml。

  • PUID 和 PGID:可访问 HA_CONFIG_PATH 的非 root ID。

  • MCP_ALLOWED_HOSTS:客户端放入 HTTP Host 头的每个 DNS 名称或 IP。

  • MCP_BIND_IP:对于本地反向代理/客户端,保持 127.0.0.1;仅在有意暴露到局域网时使用 0.0.0.0。

验证、构建并启动:

docker compose config
docker compose build --pull
docker compose up -d
docker compose ps
docker compose logs -f hac-mcp

要使用已发布的版本而不是本地构建,请设置确切的镜像标签并禁用构建:

MCP_IMAGE=docker.io/lemanjo/hac-mcp:0.1.0 docker compose pull hac-mcp
MCP_IMAGE=docker.io/lemanjo/hac-mcp:0.1.0 docker compose up -d --no-build hac-mcp

健康端点:

curl --fail http://127.0.0.1:3000/livez
curl --fail http://127.0.0.1:3000/readyz

/livez 报告 HTTP 进程正在提供服务。/readyz 执行经过身份验证的 Home Assistant /api/ 请求,并在 Home Assistant 不可用时返回 503。两个端点都不需要 MCP 承载令牌。镜像和 Compose 健康检查使用 /livez,因此临时的 Home Assistant 中断不会导致重启循环。

运行时文件系统是只读的,除了 /tmp、Docker 密钥挂载和 /ha-config。镜像以非 root 用户运行,并使用 tini 作为 PID 1;SIGTERM/SIGINT 可到达 Node,Node 会关闭 HTTP 处理器和 Home Assistant WebSocket 连接。已安装 Git 和 CA 证书,但未实现 shell 执行 MCP 工具。

网络放置

提供的 Compose 网络是一个隔离的桥接网络,带有一个已发布的 MCP 端口。它从不使用主机网络,也从不挂载 Docker 套接字。

对于 Home Assistant 连接:

  • 在 Docker 主机上运行且已发布端口的 Home Assistant:使用 http://host.docker.internal:8123。

  • 在局域网或 macvlan/ipvlan 网络上运行的 Home Assistant:使用其局域网 DNS 名称或 IP。

  • 在另一个用户定义的桥接网络上运行的 Home Assistant:将 hac-mcp 附加到该外部网络,并使用 Home Assistant 的容器 DNS 名称。将底部的网络声明替换为 external: true 网络,或向服务添加第二个外部网络。

对于 MCP 客户端连接:

  • 对于同主机客户端或同主机反向代理,保持 MCP_BIND_IP=127.0.0.1。

  • 对于受信任的局域网客户端,设置 MCP_BIND_IP=0.0.0.0,将服务器的局域网 IP/DNS 名称添加到 MCP_ALLOWED_HOSTS,并使用主机防火墙规则限制端口。

  • 此服务器不终止 TLS。对于跨越不受信任网络的流量,请使用受信任的反向代理,保留 Authorization 头,如果浏览器客户端发送 Origin,请配置允许的来源主机名。

允许的主机和来源主机名可缓解 DNS 重新绑定/跨源访问;它们不能替代承载认证或网络控制。MCP 的 Streamable HTTP 安全指南位于传输规范中。

Unraid

Unraid 在 /mnt/user 下暴露用户共享;请参阅官方共享文档。典型布局是 /mnt/user/appdata/hac-mcp 用于此检出/密钥,实际的 Home Assistant appdata 目录用于 HA_CONFIG_PATH。

  1. 将项目和密钥文件放在私有 appdata 位置。在可行的情况下,将密钥文件模式保持为 0600,目录模式保持为 0700。

  2. 将 HA_CONFIG_PATH 设置为确切的 Home Assistant 配置目录,例如 /mnt/user/appdata/home-assistant。不要挂载整个 /mnt/user。

  3. 仅当 Home Assistant 文件归 Unraid 通常的 nobody:users 账户所有时,才设置 PUID=99 和 PGID=100;否则使用实际的非 root 所有者。确认该身份可以创建 /ha-config/.ha-mcp/backups 并原子替换允许的 YAML 文件。

  4. 如果安装了 Docker Compose Manager 社区插件或 Compose v2 CLI,请从项目目录运行上述 Compose 设置。Compose 密钥以 /run/secrets 下的文件形式出现;Docker 在此处记录了该行为。

  5. 如果没有 Compose,请构建 home-assistant-admin-mcp:local 并使用高级视图在 Unraid 的 Docker 界面中创建容器。镜像 docker-compose.yml 中的环境、端口和路径设置。将两个令牌文件以只读方式绑定到 /run/secrets/home_assistant_token 和 /run/secrets/mcp_auth_token;这些界面绑定挂载提供了应用期望的文件接口,但不是 Compose 密钥对象。

  6. 默认使用桥接网络。如果 Home Assistant 使用主机网络,请将 HOME_ASSISTANT_URL 指向 Unraid 局域网 IP 和 Home Assistant 端口,或添加 host.docker.internal:host-gateway。如果 Home Assistant 有自己的 br0 局域网 IP,请使用该 IP。如果两个容器共享自定义 Docker 网络,请使用 Home Assistant 的网络别名。

  7. 对于局域网 MCP 访问,发布容器端口 3000,有意绑定它,并将 Unraid IP/DNS 名称包含在 MCP_ALLOWED_HOSTS 中。即使在受信任的局域网上,也要保持承载令牌和防火墙限制。

  8. 不要添加 Docker 套接字路径。不需要也不支持 Supervisor/容器管理。

Unraid 的 Mover 或共享设置可以更改用户共享文件的物理存储位置,而不会更改 /mnt/user/...;请使用一个稳定的用户共享路径,不要混合使用等效的 /mnt/user 和 /mnt/diskX 路径。

MCP 客户端

Streamable HTTP

以下示例假设 MCP 客户端与 Docker 运行在同一主机上,并且 Compose 默认值未更改。将客户端指向:

http://127.0.0.1:3000/mcp

对 /mcp 的每个请求都必须携带单独的 MCP 令牌:

Authorization: Bearer <contents of secrets/mcp_auth_token>

将 MCP 令牌加载到客户端进程环境中,不要将其放入客户端配置文件中。此令牌仅对 MCP 客户端进行身份验证;切勿在此处使用 Home Assistant 令牌。

export HAC_MCP_TOKEN="$(tr -d '\r\n' < /absolute/path/to/secrets/mcp_auth_token)"

对于另一主机上的客户端,将 127.0.0.1 替换为 MCP 主机的地址,并按网络放置中的说明配置 MCP_BIND_IP、MCP_ALLOWED_HOSTS、防火墙规则和 TLS。从另一个容器中,127.0.0.1 表示该客户端容器;请改用共享网络别名或主机地址。

Codex

将此添加到用户级 ~/.codex/config.toml 或受信任项目的 .codex/config.toml 中:

[mcp_servers.home-assistant-admin]
url = "http://127.0.0.1:3000/mcp"
bearer_token_env_var = "HAC_MCP_TOKEN"
enabled = true
default_tools_approval_mode = "writes"
tool_timeout_sec = 150

设置 HAC_MCP_TOKEN 后重启 Codex,然后使用 codex mcp list 或 Codex TUI 中的 /mcp 验证连接。writes 批准模式会为未标记为只读的工具添加客户端提示;服务器端模式、风险和确认策略仍然独立适用。请参阅 Codex MCP 文档。

OpenCode

将此合并到项目级 opencode.json 或全局 OpenCode 配置中:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "home-assistant-admin": {
      "type": "remote",
      "url": "http://127.0.0.1:3000/mcp",
      "enabled": true,
      "oauth": false,
      "headers": {
        "Authorization": "Bearer {env:HAC_MCP_TOKEN}"
      },
      "timeout": 150000
    }
  }
}

设置 HAC_MCP_TOKEN 后重启 OpenCode。运行 opencode mcp list 检查状态,或运行 opencode mcp debug home-assistant-admin 诊断连接。在提示中,需要时按名称引用服务器,例如 Use home-assistant-admin to list unavailable entities. 请参阅 OpenCode MCP 文档。

Claude Code

在运行 Claude Code 的项目中创建或合并此 .mcp.json:

{
  "mcpServers": {
    "home-assistant-admin": {
      "type": "http",
      "url": "http://127.0.0.1:3000/mcp",
      "headers": {
        "Authorization": "Bearer ${HAC_MCP_TOKEN}"
      },
      "timeout": 150000
    }
  }
}

环境变量引用可以安全共享;不要将其替换为已提交文件中的字面令牌。设置 HAC_MCP_TOKEN 后,运行 claude mcp list,启动 claude,在提示时批准项目范围的服务器,并使用 /mcp 检查其状态。请参阅 Claude Code MCP 文档。

验证和使用

低级初始化探测对于独立于客户端诊断端点、代理和身份验证失败非常有用:

curl --fail-with-body http://127.0.0.1:3000/mcp \
  -H "Authorization: Bearer ${HAC_MCP_TOKEN}" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  --data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl-probe","version":"1.0.0"}}}'

对于正常操作,请使用真正的 MCP 客户端;它会正确执行初始化、协议版本协商、通知和工具调用。服务器在 auto 响应模式下接受 JSON 或 SSE 响应,并使用无状态 HTTP 处理器。有用的初始提示包括:

  • Use home-assistant-admin to summarize the Home Assistant instance and list unavailable entities. Do not make changes.

  • Use home-assistant-admin to diagnose why <entity> is unavailable. Read configuration and recent logs only.

  • 在 control 模式下:Turn on <explicit entity_id>. Do not target an area or device.

  • 在 admin 模式下:Dry-run the requested configuration change, show the diff and validation result, and wait for confirmation before applying it.

客户端无法提升服务器配置的模式。以 read_only 启动;在审查权限和部署暴露面之后,再修改 .env 中的 MCP_MODE 并重新创建 Compose 服务。

stdio

先用 pnpm build 构建,然后配置本地 MCP 客户端来启动服务器。stdio 不使用 HTTP 认证,因为 MCP 客户端拥有子进程和管道。

{
  "mcpServers": {
    "home-assistant-admin": {
      "command": "node",
      "args": ["/workspaces/hac-mcp/dist/index.js"],
      "env": {
        "MCP_CONFIG_FILE": "/workspaces/hac-mcp/config.example.yaml",
        "MCP_TRANSPORT": "stdio",
        "MCP_MODE": "read_only",
        "HOME_ASSISTANT_URL": "http://homeassistant.local:8123",
        "HOME_ASSISTANT_TOKEN_FILE": "/absolute/private/path/home_assistant_token",
        "HA_CONFIG_PATH": "/absolute/path/to/home-assistant/config"
      }
    }
  }
}

在 stdio 模式下,服务器仅将日志写入 stderr。Docker 健康检查是 HTTP 特有的,因此如果故意将镜像作为 stdio 子进程运行,请勿使用默认的 Docker 健康检查。

认证与配置

有两组相互独立的凭据:

凭据

使用者

用途

Home Assistant 长期令牌

本服务器

以该用户的权限向 Home Assistant 认证 REST 和 WebSocket 请求。

MCP 认证令牌,至少 16 个字符

MCP HTTP 客户端

认证对 /mcp 的每个请求。不会发送给 Home Assistant。

对于两个令牌,*_FILE 变量优先于直接的环境变量,并且会去除首尾空白:

  • HOME_ASSISTANT_TOKEN_FILE 优先于 HOME_ASSISTANT_TOKEN。

  • MCP_AUTH_TOKEN_FILE 优先于 MCP_AUTH_TOKEN。

MCP_AUTH_TOKEN 或其文件在 HTTP 模式下为必填,在 stdio 模式下不需要。Bearer 比较使用 SHA-256 摘要和恒定时间比较。当网络不可信时仍需要 TLS,因为 bearer 令牌可被重放。

配置从 MCP_CONFIG_FILE 加载,然后环境变量覆盖文件中的值。支持的环境变量覆盖项为:

区域

环境变量

Home Assistant

HOME_ASSISTANT_URL、HOME_ASSISTANT_TOKEN、HOME_ASSISTANT_TOKEN_FILE、HA_REQUEST_TIMEOUT_MS、HA_WEBSOCKET_TIMEOUT_MS、HA_VERIFY_TLS

MCP

MCP_MODE、MCP_TRANSPORT、MCP_HOST、MCP_PORT、MCP_AUTH_TOKEN、MCP_AUTH_TOKEN_FILE、MCP_ALLOWED_HOSTS、MCP_ALLOWED_ORIGINS

文件系统

HA_CONFIG_PATH、HA_FILESYSTEM_ENABLED、HA_ALLOW_SECRET_VALUES、HA_ALLOW_CUSTOM_COMPONENTS、HA_ALLOWED_CONFIG_DIRECTORIES

Git

HA_GIT_ENABLED

逗号分隔的变量会去除空白。只有存在的环境变量才会覆盖 YAML 值。限制、权限、缓存 TTL、秘密元数据策略、备份目录和 Git 作者身份否则来自 YAML 默认值或配置文件。

模式、风险与确认

每个工具都注册了风险级别,并且对客户端保持可见。策略在调用时再次强制执行。

call_service 的基线为 CONTROL,但在授权之前会将已知的管理参数升级:重启/停止、备份和 recorder 清除操作变为 HIGH_IMPACT;reload、logger 和 config 操作变为 CONFIG。有效风险会在每个结果中返回,自定义 MCP 元数据将该工具标记为动态分类。

模式

允许的风险级别

预期用途

read_only

READ

清单、状态、诊断、日志、历史、跟踪、配置读取、差异和验证。

control

READ、CONTROL

增加有针对性的服务调用、场景/脚本执行,以及自动化启用/禁用/触发。

admin

READ、CONTROL、CONFIG、HIGH_IMPACT

增加持久化的注册表/资源/文件系统更改、重载、回滚、删除和重启。

permissions.requireConfirmationFor 默认为 HIGH_IMPACT。匹配的工具必须收到 confirm: true;否则返回带有重试元数据的 CONFIRMATION_REQUIRED。添加 CONTROL 和/或 CONFIG 可更广泛地要求确认。

敏感域策略独立于模式:

  • allow:适用正常的模式/风险策略。

  • confirm:需要显式的 confirm: true。

  • deny:即使在 admin 模式下也拒绝该操作。

默认情况下,lock、alarm_control_panel 和 siren 需要确认。包含 garage 或 gate 的显式 cover 实体 ID 也需要确认。策略会评估多实体目标中的每个显式实体。区域/设备目标无法在授权时安全展开,因此当这种区别很重要时,请对整个服务域拒绝或要求确认。

试运行

dry_run: true 在持久化资源、helper、注册表、区域、设备、实体、配置条目、YAML 补丁、管理生命周期、回滚和通用服务调用工具上实现。便捷的物理控制工具不模拟操作。

  • YAML 补丁会解析并验证生成的 YAML,返回经过脱敏的结构化差异,而不写入、不创建检查点、不重载、不检查完整的 Home Assistant 配置,也不提交。

  • 本地 YAML 解析会拒绝语法错误、重复的映射键、未解析的别名和过度的别名展开。非试运行的后续应用会运行 Home Assistant 的完整配置检查,并在被拒绝时尝试回滚;本地验证不能替代 Home Assistant 的域验证。

  • 自动化/脚本/场景试运行会读取当前编辑器资源,创建 JSON 差异,并在可用时调用已实现的片段验证,但不写入也不创建检查点。

  • Helper、注册表、区域、设备、实体和配置条目试运行会读取当前数据并构建预览。它们不会调用内部变更端点,也不会执行 Home Assistant 的服务端变更验证。

  • 配置条目重载试运行会报告拟议的重载,但无法预测运行时影响。

  • 重载、重启、检查点回滚和服务拥有的 Git 回滚试运行会验证可用的标识符/当前元数据,并描述拟议的高影响操作,而不实际应用。

  • 通用 call_service 支持针对实时服务定义的试运行验证;不会调用该服务。便捷的物理控制工具有意不模拟操作。

  • 成功的试运行仅证明其结果中描述的验证。它不保证状态、权限、内部 API、文件或集成行为在应用时保持不变。

文件系统安全

文件系统访问通过 HA_FILESYSTEM_ENABLED=false 整体禁用。启用后,请求会在 filesystem.root 下进行规范化,检查每个路径段,并拒绝符号链接。

允许的路径:

  • 配置根目录下直接放置的任何 .yaml 或 .yml 文件。

  • 配置的 allowedDirectories 下的 YAML,默认为 packages 和 themes,递归扫描深度为 32。

  • 仅在启用自定义组件策略时,custom_components/<integration>/... 下选定的 .json、.py、.pyi、.yaml 和 .yml 文件。专用工具提供有界源代码读取;不暴露源代码写入工具或 Python 执行/验证路径。

始终受保护或拒绝:

  • .storage、.git、Home Assistant 数据库格式、私钥格式/名称,以及与已实现的 auth、credential、token 或 backup-key 模式匹配的路径名称。

  • 根目录之外的路径、无效的路径段、缺少写入父目录、非普通文件以及所有符号链接。

  • 默认情况下,secrets.yaml 和 secrets.yml 的值。启用 allowSecretsMetadata: true 后,工具可以返回排序后的顶级秘密键名、字节数和时间戳,而不包含值。

当 allowSecretValues: false 时,敏感的 snake_case、camelCase 和连字符键(如 password、clientSecret、token、apiKey、private-key、credential、authorization 和 cookie)会被规范化并递归脱敏。!secret/!env_var 值以及匹配的差异行也会被脱敏。

这些检查基于模式而非内容扫描,因此不常见的秘密名称可能无法匹配每个防护。将实际值保留在受保护根目录的 secrets.yaml 中,不要将凭据存储在其他允许列表中的 YAML 中,并在将脱敏输出交给不可信模型之前检查输出。设置 HA_ALLOW_SECRET_VALUES=true 会显式允许读取和修补包含秘密的 YAML,包括根目录的 secrets.yaml;仅在完全可信的客户端下使用此特殊恢复选项。

写入使用临时文件、O_NOFOLLOW、fsync、原子重命名、保留模式、SHA-256 乐观并发检查,并在支持的情况下同步父目录。

检查点、事务与回滚

patch_yaml_file 非试运行工作流:

  1. 解析允许列表中的路径,读取当前哈希,应用结构化 YAML 操作,并验证语法。

  2. 默认在 /ha-config/.ha-mcp/backups 下创建保留模式的检查点。

  3. 重新检查哈希并原子写入每个文件。每个服务器进程只运行一个配置事务。

  4. 请求 Home Assistant 检查其完整配置。

  5. 重载受影响的自动化/脚本/场景域,或对其他/多个路径调用 homeassistant.reload_all,除非 reload: false。

  6. 读取 Home Assistant 配置作为健康检查。

  7. 在写入开始后失败时,仅当文件的哈希仍与事务输出匹配时才恢复已应用的文件,然后尝试重载和健康检查。

  8. 可选地仅将更改的路径提交到 Git。在 Home Assistant 更改成功后,Git 失败会变成警告;它不会回滚该更改。

编辑器管理的自动化/脚本/场景变更在调用内部编辑器端点之前创建文件系统检查点,非试运行更改需要配置挂载,使用有界重试验证编辑器配置和运行时存在/不存在,运行 Home Assistant 配置验证,并在应用或验证失败时尝试编辑器级回滚。

rollback_change 首先创建当前文件的安全检查点,使用当前哈希冲突检查恢复选定的检查点,验证 Home Assistant 配置,然后重载。如果验证/重载失败,它会尝试恢复安全检查点并报告任何恢复失败。检查点是本地文件快照,不是 Home Assistant Supervisor 备份,并且不会自动进行保留清理。

Git 行为与限制

Git 是可选的,仅在 /ha-config 位于检测到的仓库内时运行。镜像中包含 Git CLI。

  • 状态、历史记录和差异仅限于配置路径策略所接受的路径。

  • 提交仅暂存并提交所选允许路径。钩子被禁用,签名被禁用,作者/提交者身份来自配置。

  • 服务器不会初始化、克隆、获取、推送、拉取、合并、变基、管理远程仓库、凭据、分支、标签或子模块。

  • 目标路径在变更前进行检查。如果受影响的文件已有暂存或工作树更改,Home Assistant 操作可以继续执行其检查点,但自动 Git 提交会被跳过,以免预先存在的人工编辑被卷入 MCP 提交。无关路径保持不动。

  • rollback_to_commit 仅接受当前 HEAD,仅接受作者邮箱与配置的服务邮箱匹配的提交,不接受初始提交,并且仅当受影响路径没有未提交更改时。

  • Git 回滚会写入一个新的补偿提交,而不是重置历史记录。如果 Home Assistant 验证失败,将尝试另一次服务拥有的回滚以恢复先前状态。

  • Git 命令在 30 秒后超时。正常输出限制为 4 MiB;差异限制为 maxReadBytes 的四倍,上限为 16 MiB。

工具

以下名称源自 src/mcp/tools。客户端可见的架构、描述、注解、风险、来源和稳定性元数据由 MCP 发现返回。

发现

  • 实例:get_home_assistant_info、get_system_health、get_config。

  • 集成:list_integrations、get_integration。

  • 区域:list_areas、get_area。

  • 设备:list_devices、get_device、search_devices。

  • 实体:list_entities、get_entity、search_entities。

  • 跨注册表搜索:search_home_assistant_registry。

运行时与历史记录

  • 服务/事件:list_services、list_event_types、get_events、subscribe_events。

  • 状态:get_state、get_states、get_states_by_area、get_states_by_device。

  • 记录器数据:get_history、get_logbook、get_statistics、get_recorder_statistics。

控制

  • 通用/标准控制:call_service、turn_on、turn_off、toggle、set_value、set_temperature。

  • 执行:activate_scene、run_script。

自动化、脚本、场景与跟踪

  • 自动化:list_automations、get_automation、create_automation、update_automation、delete_automation、enable_automation、disable_automation、trigger_automation、reload_automations、validate_automation。

  • 脚本:list_scripts、get_script、create_script、update_script、delete_script、run_script_by_id、reload_scripts、validate_script。

  • 场景:list_scenes、get_scene、create_scene、update_scene、delete_scene、activate_scene_resource、reload_scenes。

  • 自动化跟踪:get_automation_traces、get_automation_trace、explain_automation_failure、get_last_automation_run。

  • 通用跟踪:get_trace、list_traces、explain_trace、get_last_trace。

辅助工具与注册表

  • 辅助工具:list_helpers、get_helper、create_helper、update_helper、delete_helper。

  • 实体注册表:update_entity_registry、disable_entity、enable_entity、rename_entity、move_entity_to_area。

  • 设备注册表:update_device、rename_device、move_device_to_area、disable_device、enable_device。

  • 区域注册表:create_area、update_area、delete_area、assign_device_to_area、assign_entity_to_area。

  • 配置条目:get_config_entries、get_config_entry、reload_config_entry、update_integration、enable_integration、disable_integration。

配置与恢复

  • 读取/列出:read_configuration、list_configuration_files、read_yaml_file、list_custom_component_files、read_custom_component_source。

  • 修补/验证:patch_yaml_file、validate_configuration、validate_home_assistant_configuration。

  • 重新加载/重启:reload_configuration、reload_yaml_configuration、restart_home_assistant。

  • 历史记录/差异:get_config_history、get_config_diff、get_recent_changes。

  • 回滚:rollback_change、rollback_to_commit。

日志、诊断、依赖与搜索

  • 日志:get_home_assistant_logs、search_logs、get_errors、get_warnings、get_recent_errors、get_integration_errors。

  • 实体/设备发现:find_unavailable_entities、find_disabled_entities、find_orphaned_entities、find_orphaned_devices、find_duplicate_entities、find_entities_without_area、find_devices_without_area、find_stale_sensors。

  • 自动化/辅助工具发现:find_unused_helpers、find_broken_automations、find_automation_errors、find_automations_referencing_missing_entities。

  • 依赖/搜索:get_entity_dependencies、get_automation_dependencies、search_home_assistant。

示例用户请求

  • "列出厨房中不可用的实体,并包含其设备和集成关系。"

  • "显示过去一小时内 zha 集成的 ERROR 和 CRITICAL 日志条目。"

  • "解释自动化 ID garage_arrival 最近一次失败的运行。"

  • "查找引用缺失实体的自动化,然后显示每个自动化的依赖关系。"

  • "对更改 packages/lighting.yaml 的结构性 YAML 修补进行试运行;仅显示脱敏后的差异。"

  • "关闭 light.office,但不要针对任何其他实体。"

  • "以试运行方式为访客模式创建一个 input_boolean 辅助工具,并报告验证限制。"

  • "在明确确认后删除场景 ID old_evening,然后报告检查点、配置验证、验证、回滚和 Git 结果。"

模型/客户端必须将请求转换为精确的工具架构。自然语言请求不会绕过模式、风险、确认、路径或 Home Assistant 授权检查。

性能与限制

默认值和硬性边界旨在防止 MCP 调用变成无界的 Home Assistant 或文件系统查询。

资源

已实现的限制

MCP HTTP JSON 请求体

默认 1 MiB;可在 YAML 中配置为 1 KiB 到 10 MiB。

Home Assistant REST 响应 / WebSocket 负载

10 MiB。

REST 和 WebSocket 命令超时

默认 30 秒;可配置为 1 到 120 秒。

注册表/服务缓存

默认 30 秒;可配置为 1 秒到 1 小时;并发加载会被合并。

分页

通常默认 100,最大 500。

允许的配置文件

默认 2 MiB;可配置为 1 KiB 到 20 MiB。

配置列表

5,000 个扫描条目,1,000 个文件,目录深度 32。

YAML 修补 / 本地验证

每个修补 100 个操作;每次验证/回滚选择 50 个文件。

服务调用

每种目标类型 100 个 ID 和 100 个服务数据字段;服务数据会根据实时定义进行检查。

历史记录/统计

每次调用 100 个实体 ID 或统计 ID。

日志簿

100 个实体/设备过滤器 ID 和 5,000 条返回条目。

事件收集工具

250 个事件和最长 120 秒。底层客户端最多允许 1,000 个收集事件、100 个订阅和 1,000 个待处理命令。

解析的日志

源/输出 2 MiB,10,000 行,最多 2,000 个条目;默认值较低。

诊断资源

每个域前 500 个可编辑资源,并发数为 10,外加 200 个脱敏的允许列表 YAML 文件;部分快照会报告源错误。

配置事务

每个进程一个活动文件系统事务。

长时间的历史记录/日志簿窗口和完整诊断在 Home Assistant 的记录器内部仍然可能代价高昂。尽可能按实体、设备、集成、时间范围和页面进行过滤。

开发

需要 Node.js 22.23.1 和 pnpm 11.21.0。

corepack enable
pnpm --version
pnpm install --frozen-lockfile
pnpm build

依赖供应链

  • 直接依赖使用精确版本;锁文件通过注册表完整性哈希固定完整依赖图。

  • pnpm 拒绝发布时间不足 10,080 分钟(七天)的版本、没有发布时间的包、发布者信任降级、异常的传递来源以及未经批准的依赖构建脚本。它还会在每次安装时根据固定的 npm 注册表重新验证锁文件解析数据。

  • 默认使用冻结锁文件进行安装。依赖更改需要显式的、经过审查的 pnpm install --no-frozen-lockfile,随后执行 pnpm supply-chain:check、常规验证套件,并提交锁文件差异。

  • 传递覆盖将符合条件的 content-type 和 hono 版本固定,而较新版本仍处于隔离窗口内,并将 undici-types 固定为不降低发布者信任的已认证版本。在审查过的依赖更新期间重新评估这些覆盖,但不要自动移除。

  • CI 操作和容器基础镜像使用不可变的提交或内容摘要。运行时 Debian 软件包来自带日期的快照,因此重新构建不会静默升级它们。

  • 不要添加 minimumReleaseAgeExclude 例外。对于紧急安全版本,请等待其满七天,或获得明确批准以在审查过的更改中修改此策略。

发布版本

使用 SemVer 标签(如 v0.1.0)发布 GitHub 版本会运行 .github/workflows/release-docker.yml。它会构建 linux/amd64 和 linux/arm64 镜像,将版本标签推送到 docker.io/lemanjo/hac-mcp,并附加 SBOM 和来源证明。稳定版本还会更新 latest;预发布版本不会。

仓库需要以下 GitHub Actions 密钥:

  • DOCKERHUB_USERNAME:Docker Hub 账户名称,当前为 lemanjo。

  • DOCKERHUB_TOKEN:具有 lemanjo/hac-mcp 读写权限的 Docker Hub 个人访问令牌。不要使用账户密码。

在 GitHub 仓库 > Settings > Secrets and variables > Actions > New repository secret 下添加它们,或使用 GitHub CLI:

gh secret set DOCKERHUB_USERNAME --repo lemanjo/hac-mcp --body lemanjo
gh secret set DOCKERHUB_TOKEN --repo lemanjo/hac-mcp

第二条命令会安全地提示输入令牌值。不要将令牌存储在 .env、工作流 YAML、shell 历史记录或仓库中。

Every push to main, including a merged pull request, runs .github/workflows/nightly-docker.yml. It uses the separate DOCKERHUB_NIGHTLY_TOKEN secret and publishes nightly plus an immutable nightly-<full-commit-sha> tag. The workflow can also be started manually from GitHub Actions. Use the full-SHA tag when reproducibility matters.

gh secret set DOCKERHUB_NIGHTLY_TOKEN --repo lemanjo/hac-mcp

HTTP 开发:

HOME_ASSISTANT_URL=http://homeassistant.local:8123 \
HOME_ASSISTANT_TOKEN_FILE=/absolute/private/path/home_assistant_token \
MCP_AUTH_TOKEN_FILE=/absolute/private/path/mcp_auth_token \
MCP_CONFIG_FILE=./config.example.yaml \
MCP_TRANSPORT=http \
MCP_HOST=127.0.0.1 \
MCP_ALLOWED_HOSTS=localhost,127.0.0.1 \
HA_CONFIG_PATH=/absolute/path/to/home-assistant/config \
pnpm dev

对于仅 API 开发,设置 HA_FILESYSTEM_ENABLED=false 和 HA_GIT_ENABLED=false;需要检查点的编辑器资源变更将按设计不可用。

测试与验证

运行仓库检查:

pnpm supply-chain:check
pnpm audit --prod --audit-level high
pnpm typecheck
pnpm lint
pnpm format:check
pnpm test
pnpm build

在 Docker 可用的环境中,验证部署文件:

docker compose config
docker build --check -t home-assistant-admin-mcp:check .
docker build -t home-assistant-admin-mcp:local .

然后针对非生产 Home Assistant 实例测试 /livez、/readyz、MCP 初始化请求以及具有代表性的只读工具。在启用 admin 之前,针对生产中使用的确切 Home Assistant 版本和文件系统测试内部 API 读取、试运行、一次性变更、检查点回滚和 Git 行为。

故障排查

服务器无法启动

  • INVALID_CONFIGURATION:解析 config.yaml,检查精确的 camelCase 键、数值范围、URL、电子邮件格式以及 stderr 中扁平化的验证详细信息。

  • MCP_AUTH_REQUIRED:HTTP 模式需要 MCP_AUTH_TOKEN 或 MCP_AUTH_TOKEN_FILE,且去除首尾空白后至少 16 个字符。

  • 针对 secret 的 ENOENT:Compose secret 源路径是相对于 Compose 项目的主机路径。请确认 .env 和文件权限。

  • Docker 健康检查在 stdio 模式下失败:/livez 仅在 HTTP 模式下存在;对于特意采用 stdio 模式的容器,请移除或覆盖健康检查。

MCP HTTP 401、403 或 413

  • 401:MCP bearer token 缺失、格式错误或不正确。身份验证方案不区分大小写,且必须为 Bearer。

  • 403(在工具调用之前):将请求的实际主机名添加到 MCP_ALLOWED_HOSTS;对于浏览器客户端,还要将其不带协议和端口的主机名添加到 MCP_ALLOWED_ORIGINS。不要添加任意通配符。

  • 413 或 JSON 解析被拒绝:减小请求体,或在 10 MiB 限制内增大 mcp.maxRequestBytes。

  • 反向代理失败:请保留 Authorization、Host、Origin、Accept、Content-Type、MCP-Protocol-Version、HTTP 流式传输以及 SSE 行为。

/readyz 返回 503 或 Home Assistant 调用失败

  • 在 bridge 容器内部,localhost 指向 MCP 容器,而不是 Home Assistant。请使用 host.docker.internal、局域网地址或共享网络别名。

  • HA_AUTH_FAILED/HA_WS_AUTH_FAILED:替换或重新创建 Home Assistant 长期访问令牌。

  • HA_PERMISSION_DENIED:token 对应的用户缺少执行所请求内部命令所需的权限或管理员状态。

  • HA_TLS_ERROR/HA_WS_TLS_ERROR:安装受信任的证书链;或者,仅在受控的私有网络上,设置 HA_VERIFY_TLS=false,同时充分意识到服务器身份将不再被验证。

  • 历史记录、日志簿或统计信息错误:确认 recorder/logbook 集成已加载,并且请求的 ID/时间范围存在。

文件系统或 Git 失败

  • CONFIG_ROOT_UNAVAILABLE/权限被拒绝:确保 HA_CONFIG_PATH 正确且对 PUID:PGID 可写;容器有意不以 root 身份运行。

  • CONFIG_PATH_NOT_ALLOWED:使用根 YAML 或允许的目录;受保护的路径、符号链接、任意扩展名和缺失的父目录都会被拒绝。

  • CONFIG_CONCURRENT_MODIFICATION/ROLLBACK_CONFLICT:另一个进程修改了该文件。请重新读取、检查并重试,而不是强制覆盖。

  • Git is enabled but no repository was detected:在 MCP 外部初始化/管理仓库,或设置 HA_GIT_ENABLED=false。

  • Git 报告 dubious ownership(可疑所有权):使容器 UID/GID 与仓库所有权保持一致。不要通过以 root 身份运行容器来解决此问题。

  • 检查点会占用空间:检查并为 .ha-mcp/backups 应用操作员定义的保留策略;没有自动删除工具。

Home Assistant 升级后内部工具失败

  • 确认该命令在链接的当前核心源代码中仍然存在,并比较请求/响应字段。

  • 先重试只读操作。当验证或回滚状态不确定时,不要反复重试变更操作。

  • 对于内部端点已更改的 helper、集成或资源,请使用 Home Assistant 的 UI。

  • 在兼容性经过测试和审查之前,保持 MCP_MODE=read_only。

许可证

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    MCP server for controlling and querying Home Assistant via its REST API, exposing tools to get entity states, list all states, and call services.
    16
    134 npm
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    MCP server for full Home Assistant control, enabling AI agents to manage dashboards, automations, files, apps, entities, and more via REST API, WebSocket, and SSH.
    66
    189 npm
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    MCP server for controlling HomeSeer HS4 with safe, auditable, and guarded write operations.
    63
    1
    MIT