关于 ccu-mcp
ccu-mcp 将 HomeMatic CCU 接入 MCP 客户端,提供设备、房间、程序和系统变量的操作。它通过本地 JSON-RPC API 连接,可查询和控制智能家居设备。
主要功能
- 01浏览设备、房间和程序
- 02读取并设置设备数值
- 03查看系统变量
- 04发现设备并解析类型
- 05直接连接 CCU API
适用场景
- 01查看房间温度和窗户状态
- 02调整暖气设定温度
- 03查找电量不足的设备
- 04查看燃气表读数
MCP 相关
将 HomeMatic 设备、房间、程序和系统变量作为 MCP 工具提供。MCP 客户端可通过 stdio 运行它,也可连接独立的 HTTP 服务。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y ccu-mcpCCU_HOSTHostname or IP of your HomeMatic CCU (debmatic, CCU3, or OpenCCU/RaspberryMatic)CCU_PASSWORD密钥CCU admin password (same as the WebUI login). Must be set; the value may be empty for a CCU with no passwordCCU_USERCCU usernameCCU_HTTPSConnect to the CCU via HTTPS (self-signed certificates supported)CCU_PORTCCU API port (80 for HTTP, 443 for HTTPS)CACHE_DIRDirectory for the device type cache and session persistenceMCP_ALLOWED_ORIGINSComma-separated allowlist of browser origins. Unset = no cross-origin browser access (default-deny). An allowlisted origin is reflected exactly in Access-Control-Allow-Origin (never '*'); the list also drives DNS-rebinding origin checksMCP_ALLOWED_HOSTSExtra Host header values accepted by DNS-rebinding protection (comma-separated host:port); add your hostname when behind a proxy or container DNS nameCCU_PROFILESComma-separated names of multiple CCU targets (e.g. 'prod,dev'). Each profile takes the flat CCU_* settings prefixed CCU_<NAME>_ (CCU_PROD_HOST, ...), plus policy flags CCU_<NAME>_PROTECTED (writes need confirm:true) and CCU_<NAME>_READONLY. Unset = single default profile from the flat CCU_* varsCCU_DEFAULT_PROFILEWhich profile from CCU_PROFILES is active at startup (default: the first listed)CCU_TLS_VERIFYVerify the CCU's TLS certificate against the system trust store. Only meaningful with CCU_HTTPS=true. Default false, because a CCU ships a self-signed certificate — prefer CCU_TLS_FINGERPRINT or CCU_CA_CERT to verify one of thoseCCU_TLS_FINGERPRINTPin the CCU's self-signed leaf certificate by its SHA-256 fingerprint (hex, colons optional). The strongest option for an appliance: the connection is rejected unless the presented certificate matches. Takes precedence over CCU_CA_CERTCCU_CA_CERTPath to a PEM file holding the CCU's CA or self-signed certificate. The connection is then validated against it with standard chain verificationCCU_TIMEOUTTimeout for a CCU JSON-RPC call, in MILLISECONDSCCU_SCRIPT_TIMEOUTTimeout for HomeMatic Script execution (ReGa), in MILLISECONDS — scripts are slower than plain API callsCACHE_TTLLifetime of the on-disk device-type schema cache, in SECONDSCCU_RATE_LIMIT_BURSTToken-bucket burst size for CCU requests — how many may be issued back to backCCU_RATE_LIMIT_RATESustained CCU request rate, in requests per secondRESOURCE_POLL_INTERVALHow often MCP resources are polled for change notifications, in SECONDSLOG_LEVELerror | warn | info | debug. Logs are structured JSON on stderr本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
28收录的工具列表 · 更新于 3 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 否 | 按设备/通道名称筛选(子字符串,不区分大小写) |
| room | string | 否 | 按房间名称筛选(完全匹配) |
| type | string | 否 | 按设备类型筛选(完全匹配,例如 'HmIP-eTRV-2') |
| target | string | 否 | 要从中读取的 CCU 目标(默认:当前活动目标)。请参阅 list_ccu_targets。 |
| function | string | 否 | 按功能组名称筛选(完全匹配) |
详细介绍
ccu-mcp
通过 Claude、Cursor 或任何 MCP 客户端与你的 HomeMatic 智能家居对话。
ccu-mcp 连接到 CCU 内置的 JSON-RPC API,并将你的设备、房间、程序和系统变量作为 MCP 工具提供。无需附加组件,无需 XML-API,也无需云服务——只需直接连接到本地网络中的 CCU。
兼容任何 HomeMatic CCU:debmatic(运行于 Debian 上的 HomeMatic)、CCU3 或 OpenCCU(原 RaspberryMatic)——只要支持标准的 /api/homematic.cgi 端点即可。
它能做什么?
你可以向 AI 助手提出这样的问题:
- “浴室的温度是多少?”
- “有窗户开着吗?”
- “把客厅暖气设为 21 度”
- “显示所有电量低的设备”
- “燃气表读数是多少?”
- “哪些设备电量低,或者已经很久没有被发现?”
- “找出所有名称与设备名称不匹配的通道”
- “将所有设备重命名为统一的命名规范,并标注楼层(UG/OG/EG)”
- “窗户传感器在哪个房间?”
MCP 服务负责设备发现、类型解析、会话管理和值转换——AI 只需调用工具。
前提条件
- 网络中可访问且正在运行的 HomeMatic CCU(debmatic、CCU3 或 OpenCCU——原 RaspberryMatic)
- CCU 管理员用户名和密码(与登录 WebUI 时使用的凭据相同)
- Node.js 24+(用于从源代码运行或以 stdio 模式运行)或 Docker
快速开始
export CCU_HOST=your-ccu-hostname-or-ip
export CCU_PASSWORD=your-ccu-admin-password
npx ccu-mcp --stdio
如果它在 stderr 中输出 server_ready,就表示运行正常。按 Ctrl+C 停止。现在在你的 MCP 客户端中进行设置——请参见下文。
如果旁边出现 cache_save_failed … mkdir '/data',在这里可以忽略,但在实际使用中建议修复:CACHE_DIR 默认值为 /data(Docker 布局),因此在容器外部运行时,设备类型缓存和 CCU 会话不会在运行之间持久保存。将它指向一个可写位置:
export CACHE_DIR="$HOME/.cache/ccu-mcp"(或在 .env / env 配置块中设置相同的键)。
希望获得引导式设置?npx ccu-mcp init 会探测你的 CCU、固定其 TLS 证书、测试登录、写入一个可直接使用的 .env 文件,并输出对应的 MCP 客户端配置——请参见命令行标志。
安装
有两种运行方式:stdio(服务作为 MCP 客户端的子进程运行)或 HTTP(服务在 Docker 中独立运行,客户端通过网络连接)。请选择一种。
选项 A:stdio(直接运行,最简单)
这是最简单的设置方式。你的 MCP 客户端(Claude Code、Cursor 等)会将服务作为子进程启动——无需 Docker、无需网络配置,也无需身份验证令牌。
对于 Claude Code,请在项目目录(或你会使用 Claude Code 的任何目录)中创建一个 .mcp.json 文件:
{
"mcpServers": {
"ccu-mcp": {
"command": "npx",
"args": ["ccu-mcp", "--stdio"],
"env": {
"CCU_HOST": "your-ccu-hostname-or-ip",
"CCU_PASSWORD": "your-ccu-admin-password"
}
}
}
}
将 your-ccu-hostname-or-ip 替换为你的 CCU 主机名(例如 homematic-ccu3)或 IP(例如 192.168.1.50),并将 your-ccu-admin-password 替换为你登录 CCU WebUI 时使用的密码。
重启 Claude Code。运行 /mcp 检查连接状态。你应该会在列表中看到 ccu-mcp。
或者,使用 Claude Code CLI:
claude mcp add ccu-mcp -- npx ccu-mcp --stdio
选项 B:Docker(独立 HTTP 服务)
如果你希望服务独立运行,例如运行在家用服务器上、供多个客户端访问,或者 MCP 客户端支持 HTTP 远程连接,请使用此选项。
1. 启动容器。 镜像已发布到 GHCR,支持 linux/amd64 和
linux/arm64(因此也可在 CCU 旁的 Raspberry Pi 上运行),在每种
架构上原生构建并经过证明——gh attestation verify oci://ghcr.io/claymore666/ccu-mcp:latest --repo claymore666/ccu-mcp
可证明该镜像来自此仓库的发布工作流。
docker pull ghcr.io/claymore666/ccu-mcp:latest
每次发布也会发布对应的 X.Y.Z 标签——如果你希望自行决定升级时机,可以固定使用该标签,而不是 latest。
如需从源代码构建:
git clone https://github.com/claymore666/ccu-mcp.git && cd ccu-mcp
docker build -t ghcr.io/claymore666/ccu-mcp .
然后运行:
docker run -d \
--name ccu-mcp \
-e CCU_HOST=your-ccu-hostname-or-ip \
-e CCU_PASSWORD=your-ccu-admin-password \
-e MCP_ALLOWED_HOSTS=your-server-ip:3000 \
-v ccu-data:/data \
-p 3000:3000 \
ghcr.io/claymore666/ccu-mcp:latest
远程客户端必须设置
MCP_ALLOWED_HOSTS。 服务的 DNS 重绑定防护会拒绝任何Host标头不在允许列表中的请求——默认情况下,仅允许 MCP 端口上的localhost/127.0.0.1/[::1]。请将客户端用于访问服务的所有名称/IP 添加到列表中(以逗号分隔,格式为host:port)。如果未设置,本地健康检查可以正常运行, 但所有远程 MCP 请求都会收到 403 Invalid Host header。
2. 获取身份验证令牌。 服务首次启动时会生成一个随机的 bearer 令牌,并将其保存在容器的数据卷中。你需要使用此令牌对 MCP 客户端进行身份验证。使用以下命令获取:
docker exec ccu-mcp grep MCP_AUTH_TOKEN /data/.env
命令会输出类似 MCP_AUTH_TOKEN=e96suzi1iG0H-GPif6K2... 的内容。= 后面的部分就是你的令牌。
3. 配置 MCP 客户端。 如果客户端使用 .mcp.json,请添加 HTTP 服务:
{
"mcpServers": {
"ccu-mcp": {
"url": "http://your-server-ip:3000",
"headers": {
"Authorization": "Bearer PASTE-YOUR-TOKEN-HERE"
}
}
}
}
如需自动注入令牌(需要 jq):
TOKEN=$(docker exec ccu-mcp grep MCP_AUTH_TOKEN /data/.env | cut -d= -f2)
jq --arg t "$TOKEN" '.mcpServers["ccu-mcp"].headers.Authorization = "Bearer " + $t' .mcp.json > .mcp.json.tmp && mv .mcp.json.tmp .mcp.json
此操作只会更新 ccu-mcp 条目,不会更改 .mcp.json 中的其他服务。
4. 检查服务是否正常运行:
curl http://localhost:3000/health
基于浏览器的客户端(CORS)
默认情况下,HTTP 服务不会发送任何 CORS 标头,因此随机网页无法控制本地实例。如需让 MCP Inspector 等基于浏览器的 MCP 客户端直接连接,请将 MCP_ALLOWED_ORIGINS 设置为可信来源的逗号分隔允许列表(例如 https://app.example,http://localhost:6274)。对于 Origin 在列表中的请求,服务会将该来源的原值写入 Access-Control-Allow-Origin,绝不会使用通配符 *,因为那会让任何网站都能控制管理真实 CCU 硬件的本地实例。来自其他来源的请求不会获得 CORS 标头(浏览器会阻止该请求),并且会被服务端的 DNS 重绑定防护拒绝。无论如何都会强制执行身份验证:每个 MCP 请求都需要 bearer 令牌。
默认情况下,HTTP 传输也会启用 DNS 重绑定防护:它会拒绝 Host 标头不是配置端口上的 localhost/127.0.0.1/[::1] 的请求。如果你通过其他主机名或 IP 访问服务(反向代理、容器 DNS 名称、服务所在的局域网地址),请将这些主机添加到 MCP_ALLOWED_HOSTS,否则合法请求会收到 403。
TLS。 bearer 令牌会随请求传输,因此除回环地址以外的连接都应加密。你有两种选择:在前置反向代理(Caddy/nginx)处终止 TLS,并将服务绑定到回环地址(MCP_HOST=127.0.0.1);或者设置 MCP_TLS_CERT 和 MCP_TLS_KEY 为 PEM 证书/密钥对,由服务自行提供 HTTPS。仍然完全支持普通 HTTP,并且它依旧是零配置默认选项;但如果服务通过非回环地址绑定并以未加密的 HTTP 传输令牌,启动时会记录警告。设置 MCP_ALLOW_PLAINTEXT=true 即表示确认知悉这一点,并可关闭该警告。
令牌轮换与过期。 默认情况下,bearer 令牌永不过期。你可以组合使用两项可选控制措施,在不让客户端断开连接的情况下轮换令牌:
- 自动生成的令牌 — 设置
MCP_AUTH_TOKEN_TTL_DAYS(允许小数天)为生成的令牌指定有效期。服务会在令牌即将过期前在运行时自动轮换(无需重启;如果服务停机期间令牌已过期,也会在启动时轮换),并将新令牌打印到 stderr,同时让刚被替换的令牌在MCP_AUTH_TOKEN_GRACE_HOURS指定的时长内(默认为 24 小时)仍可通过验证,以便正在进行请求的客户端平稳切换。若要提前轮换,请删除$CACHE_DIR/.env(或只删除其中的MCP_AUTH_TOKEN行)并重启。 - 显式设置的令牌 — 如果你自行设置
MCP_AUTH_TOKEN,令牌有效期由你负责(TTL 不适用)。若要轮换,请将新令牌写入MCP_AUTH_TOKEN,将旧令牌移至MCP_AUTH_TOKEN_PREVIOUS,然后重启;重叠期间两个令牌都可使用。等所有客户端都使用新令牌后,删除MCP_AUTH_TOKEN_PREVIOUS并重启。对所有当前有效的令牌,比较过程始终采用时序安全方式。
暴力破解防护(fail2ban)。 自动生成的令牌具有 256 位随机性,因此无法通过猜测破解。如果你自行设置 MCP_AUTH_TOKEN,请确保令牌足够长且随机(例如 openssl rand -base64 32)——短或容易猜测的令牌才需要担心暴力破解。服务不会在进程内对失败的登录尝试进行速率限制或锁定;这项工作应交给防火墙级别的工具,例如 fail2ban,由它在请求到达服务之前封禁来源 IP。为方便实现这一点,每个被拒绝的请求都会向 stderr 输出一行结构化日志:
{"ts":"2026-06-18T17:28:00.370Z","level":"warn","msg":"auth_failed","client":"203.0.113.7","hadToken":true}
fail2ban/ 中附带了可直接使用的 fail2ban 配置:将 filter.d/ccu-mcp.conf 复制到 /etc/fail2ban/filter.d/,并将 jail.d/ccu-mcp.local 中的 jail 复制到 /etc/fail2ban/jail.d/(默认设置为 10 分钟内失败 5 次 → 封禁 1 小时)。服务将日志写入 stderr,因此请将 fail2ban 指向你收集日志的位置——作为 unit 运行时指向 journal(backend = systemd),或在重定向 stderr/使用 docker logs 时指向文件;jail 文件中对两种方式都有说明。需要设置 LOG_LEVEL=warn 或更低级别(默认为 info,可以使用;error 会屏蔽该日志行)。如果服务位于反向代理之后,记录的 IP 将是代理的 IP,因此请改为对代理的访问日志运行 fail2ban。
CORS 支持最初由 @marcinn2 在其分支 marcinn2/debmatic-mcp 中实现——感谢!
HTTPS
如果你的 CCU 使用 HTTPS(自签名证书也可以),请添加以下环境变量:
CCU_HTTPS=true
CCU_PORT=443
服务会自动接受自签名证书——由于 CCU 出厂时附带自签名证书,因此默认关闭证书验证(未验证连接运行时,服务会记录警告)。若要实际验证连接并消除 MITM 风险,有以下三种选择:
- 固定证书指纹(适用于自签名设备证书,且最简单):将证书的 SHA-256 值(十六进制,可带或不带冒号)设置为
CCU_TLS_FINGERPRINT。除非 CCU 提供的证书与该值完全一致,否则连接会被拒绝。使用以下命令读取:echo | openssl s_client -connect "$CCU_HOST:443" 2>/dev/null | openssl x509 -noout -fingerprint -sha256 - 信任 CA/自签名 PEM:将
CCU_CA_CERT指向证书文件,以进行标准链验证。 - 系统信任存储:如果你的 CCU 使用公开受信任的证书,请设置
CCU_TLS_VERIFY=true。
CCU_TLS_FINGERPRINT 的优先级高于 CCU_CA_CERT,而 CCU_CA_CERT 的优先级高于 CCU_TLS_VERIFY。
ccu-mcp init 会为你完成证书固定:它会显示 CCU 提供的证书,并在你确认后将指纹写入 env 文件;ccu-mcp doctor 会在之后重新检查固定的指纹(如果证书合法轮换,还会提供更新选项)。
配置
所有配置都通过环境变量完成:
| 变量 | 默认值 | 描述 |
|---|---|---|
CCU_HOST | 必填 | CCU 的主机名或 IP |
CCU_PASSWORD | 必填 | CCU 管理员密码。必须设置;如果设备没有密码(全新安装的 OpenCCU),可以为空 |
CCU_USER | Admin | CCU 用户名 |
CCU_PORT | 80 | API 端口(使用 HTTPS 时为 443) |
CCU_HTTPS | false | 通过 HTTPS 连接(支持自签名证书) |
CCU_TLS_VERIFY | false | 根据系统信任存储验证 CCU 的 TLS 证书(适用于受公共机构信任的证书) |
CCU_TLS_FINGERPRINT | 未设置 | 通过 SHA-256 指纹(十六进制,可带冒号)固定 CCU 的自签名叶证书。优先于其他 TLS 选项 |
CCU_CA_CERT | 未设置 | 用于验证证书链的 CCU CA/自签名 PEM 文件路径 |
CCU_TIMEOUT | 10000 | CCU 请求超时时间,单位为毫秒 |
CCU_SCRIPT_TIMEOUT | 30000 | HM Script 执行超时时间,单位为毫秒 |
LOG_LEVEL | info | error、warn、info 或 debug |
CACHE_DIR | /data | 设备类型缓存和会话的存储位置 |
CACHE_TTL | 86400 | 缓存有效期,单位为秒(24 小时) |
MCP_TRANSPORT | http | http 或 stdio(--stdio CLI 标志会覆盖此设置) |
MCP_PORT | 3000 | HTTP 服务端口(仅适用于 HTTP 模式) |
MCP_AUTH_TOKEN | 自动生成 | HTTP 模式的 Bearer 令牌;首次启动时生成并保存到 $CACHE_DIR/.env |
MCP_AUTH_TOKEN_PREVIOUS | 未设置 | 先前的 Bearer 令牌,在轮换重叠期间与 MCP_AUTH_TOKEN 一同接受;移除此项并重启即可结束重叠期。仅适用于显式令牌配置 |
MCP_AUTH_TOKEN_TTL_DAYS | 未设置(永不过期) | 自动生成的令牌有效期,单位为天(允许小数)。服务端会在令牌到期前不久于运行时自动轮换(新令牌会通过 stderr 通知);设置 MCP_AUTH_TOKEN 时忽略此项 |
MCP_AUTH_TOKEN_GRACE_HOURS | 24 | 自动轮换后的重叠期,单位为小时;在此期间,刚被替换的令牌仍可使用 |
MCP_ALLOWED_ORIGINS | 未设置 | 以逗号分隔的浏览器来源允许列表。未设置 = 不允许跨源浏览器访问(默认拒绝)。允许列表中的来源会原样反映在 Access-Control-Allow-Origin 中(绝不会是 *);该列表也用于 DNS 重绑定来源检查 |
MCP_ALLOWED_HOSTS | MCP 端口上的 localhost/127.0.0.1/[::1] | DNS 重绑定保护允许的额外 Host 值(以逗号分隔的 host:port);请添加客户端用于访问服务端的每个名称/IP(代理、容器 DNS 名称、普通服务端 IP) |
MCP_HOST | 未设置(所有接口) | HTTP 监听器的绑定地址;设置为 127.0.0.1 可限制为回环地址(例如部署在 TLS 终止代理后),同时也会关闭明文传输警告 |
MCP_TLS_CERT / MCP_TLS_KEY | 未设置 | PEM 证书/密钥路径。设置两者即可通过原生 HTTPS 提供 MCP;不设置则使用普通 HTTP。只设置其中一项会导致配置错误 |
MCP_ALLOW_PLAINTEXT | false | 设置为 true,表示确认通过普通 HTTP 传输 Bearer 令牌,并关闭非回环地址的明文传输警告 |
CCU_RATE_LIMIT_BURST | 20 | 发送到 CCU 的最大突发请求数 |
CCU_RATE_LIMIT_RATE | 10 | CCU 持续请求速率,单位为每秒 |
RESOURCE_POLL_INTERVAL | 60 | MCP 资源变更通知的轮询间隔,单位为秒 |
如需通过一台服务端驱动多个 CCU,请用命名配置替换这些扁平的 CCU_* 变量——详见下文的多个 CCU 目标。
命令行标志
ccu-mcp init # interactive setup: probe the CCU, pin its TLS cert,
# test the login, write an env file (default ./.env)
ccu-mcp doctor # validate an env file end-to-end: reachability,
# certificate pin, login, privilege level
ccu-mcp secret [prof] # store ONE CCU password into an env file via a local
# hidden prompt — name the target when the file
# defines profiles, omit it for a single CCU (used by
# the LLM-guided setup below; also the rotation path)
ccu-mcp --stdio # serve over stdin/stdout (overrides MCP_TRANSPORT)
ccu-mcp --http # serve over HTTP (default)
ccu-mcp --env <path> # load configuration from a dotenv file (already-set
# environment variables win); also accepted by
# init/doctor/secret to pick the file they
# write/check/update (default ./.env)
ccu-mcp --version # print the installed version and exit
ccu-mcp --help # print usage and exit
ccu-mcp init 会引导你配置一个或多个 CCU 目标(多个 CCU 目标)——它会先询问你是否需要配置多个目标,然后逐一询问每个目标的名称、端点、证书固定值、凭据和两个策略标志,并询问要将哪个目标设为启用状态。它会检测每个已配置用户的权限级别是 ADMIN 还是 USER(基于脚本的工具需要 ADMIN),最后提供一段可直接粘贴的 MCP 客户端配置片段。无需预先存在配置。任何检查失败时,ccu-mcp doctor 都会以非零状态码退出,因此也适用于脚本;如果 CCU 的证书确实已轮换,请在交互模式下运行,以便选择刷新固定值。操作示例:设置多个目标。
LLM 引导式设置(设置模式)
该向导还有一个对话版:先在 MCP 客户端中注册服务,再进行配置。使用 --stdio --env <path> 启动,且配置缺失或不完整时,服务会以设置模式启动——这是一个精简的 MCP 服务,仅公开四个 setup_* 工具(setup_status、setup_probe、setup_write_profile、setup_test)以及相关说明,让 LLM 通过普通聊天引导你完成相同的探测 → 固定证书 → 测试登录 → 写入流程。
{
"mcpServers": {
"ccu-mcp": {
"command": "npx",
"args": ["ccu-mcp", "--stdio", "--env", "/path/to/.env"]
}
}
}
然后只需提出请求:“设置我的 CCU 连接”。有一个刻意设计的例外:密码绝不会经过模型或聊天记录。setup_write_profile 没有密码参数;助手会给你一条命令,让你在终端中运行——npx ccu-mcp secret <profile> --env /path/to/.env,或者根据你的安装方式使用等效命令——它会在本地提示输入密码(关闭回显),并且只将密码写入文件(权限模式为 0600)。请复制工具输出的命令,而不是这里的命令:该命令会指定输出它的构建版本,因此不会误用缺少此子命令的旧版安装。setup_test 报告成功后,重新连接 MCP 服务,同一条客户端配置就会以完整配置启动服务。
这里也支持多个 CCU——说明这一点(“我有一个生产环境 CCU 和一个开发环境 CCU”),助手就会针对每个目标重复执行探测 → 写入 → 密钥流程:setup_write_profile 接受一个 name(以及 protected、readonly 和 makeDefault),并更新该目标,同时保留其他目标及其已存储的密码。每个目标都需要单独运行一次 ccu-mcp secret <name>;在所有已配置目标都设置好密码之前,服务会保持在设置模式:如果中途重新连接,会再次进入设置模式,并指出仍缺少密码的目标以及完成设置所需的确切 secret 命令。真正没有密码的 CCU 不属于缺少密码——将键写入空值(CCU_<NAME>_PASSWORD=)即可明确表示这一点。
设置模式仅支持 stdio(可写入配置文件的未配置 HTTP 端点会造成不可接受的攻击面);不带 --env 直接启动仍会明确报错,而不会静默地提供设置工具。
--version 和 --help 无需配置——可用它们检查已安装的副本究竟是什么版本,例如更新后:
$ npx ccu-mcp@latest --version
1.10.0
请注意,直接运行 npx ccu-mcp 会复用缓存于 ~/.npm/_npx 的副本,而不会重新从注册表解析;如果想获取最新版本,请指定 @latest(或清除该缓存)。
如何提供这些变量(内联、.env 或 export)
必需的 CCU_HOST / CCU_PASSWORD(以及其他所有变量)都是环境变量。任选以下一种方式提供即可,只需选一种:
-
在
.mcp.json中内联——使用上方 选项 A 中所示的env块。最简单,配置齐全。 -
Shell
export——如上方快速开始所示。 -
.env文件——将密钥保留在.mcp.json之外。使用服务自身的--env标志传入(ccu-mcp init也会写入此配置并打印相应代码片段):{ "mcpServers": { "ccu-mcp": { "command": "npx", "args": ["ccu-mcp", "--stdio", "--env", "/path/to/.env"] } } }(也可以在脚本路径前使用 Node 自身的
--env-file=标志,但如果文件尚不存在,Node 会拒绝启动,而且该标志需要dist/index.js的完整路径。)将
.env.example复制为.env并填写内容(其中说明了每个变量)。Docker 用户可以通过docker run --env-file .env或 compose 的env_file:传入同一文件。确保.env已加入 gitignore。
多个 CCU 目标(配置档)
默认情况下,上方的 CCU_* 变量用于配置单个 CCU。如需通过一个服务访问多个 CCU(例如 生产环境 + 开发环境),请改为定义命名配置档。与其他配置一样,可通过内联、.env 或 export 设置这些变量——参见上文:
CCU_PROFILES=prod,dev
CCU_DEFAULT_PROFILE=prod # active at startup (defaults to the first listed)
CCU_PROD_HOST=ccu.example
CCU_PROD_USER=ai
CCU_PROD_PASSWORD=...
CCU_PROD_HTTPS=true
CCU_PROD_PROTECTED=true # writes need confirm:true
CCU_DEV_HOST=127.0.0.1
CCU_DEV_PORT=18080
CCU_DEV_USER=Admin
CCU_DEV_PASSWORD= # may be empty (e.g. an OpenCCU dev box)
每个配置档使用与扁平变量相同的设置,变量名前缀为 CCU_<NAME>_(名称需大写,非字母数字字符替换为 _):HOST(必需)、PASSWORD(可以为空;与扁平变量 CCU_PASSWORD 不同,也可以完全省略,此时会按空值处理)、USER、PORT、HTTPS、TIMEOUT、SCRIPT_TIMEOUT、TLS_FINGERPRINT、CA_CERT、TLS_VERIFY,以及两个策略标志:
CCU_<NAME>_PROTECTED=true——除非调用时传入confirm: true,否则写入工具会拒绝执行;传入后,本次会话期间对该目标的写入操作将获准。例外:每次调用run_script和delete_system_variable时都必须传入confirm: true,它们不会因会话解锁而获准(脚本会绕过所有类型化工具的防护;删除操作无法恢复),且确认这两项操作不会解锁会话中的其他写入操作。CCU_<NAME>_READONLY=true——写入工具将直接被拒绝。
如果未设置 CCU_PROFILES,则会将扁平的 CCU_* 变量作为单个 default 配置档使用(行为不变)。运行时,list_ccu_targets 会显示各个目标,get_connection_info 会报告当前活动目标,而 use_ccu 可用于切换目标。读取工具也接受可选的 target 参数,可在单次调用中从另一个 CCU 读取数据,而无需切换目标。
配置多个目标
使用向导。 ccu-mcp init 会先询问,然后针对每个目标依次收集名称 →
端点 → 证书固定值 → 凭据 → 策略标志,最后询问哪个目标作为当前活动目标启动:
$ npx ccu-mcp init --env ~/.config/ccu-mcp/.env
ccu-mcp setup — probes your CCU, pins its TLS certificate, tests the
login, and writes the result to /home/you/.config/ccu-mcp/.env.
Set up multiple CCU targets (e.g. prod/dev)? [y/N]: y
Profile name [prod]: prod
CCU hostname or IP: ccu.example
Probing ccu.example ...
Found the CCU API on port 443 (HTTPS).
Use HTTPS? [Y/n]: y
Port [443]: 443
The CCU presents this TLS certificate:
Subject: ccu.example
Issuer: ccu.example
Valid: Jun 19 21:37:09 2026 GMT — Jun 16 21:37:09 2036 GMT
SHA-256: 90:0C:4C:F2:53:22:E7:78:...:40:ED:16:95:6E:BB:B1:53
Pin this certificate's fingerprint (recommended)? [Y/n]: y
CCU user [Admin]: ai
CCU password (input hidden):
Testing login ...
Login OK (CCU 3.87.6.20260614) — privilege level ADMIN: all tools available.
Protect this target (write tools then require confirm:true)? [y/N]: y
Make this target read-only (write tools refused entirely)? [y/N]: n
Add another CCU target? [y/N]: y
Profile name: dev
CCU hostname or IP: 192.168.1.50
Probing 192.168.1.50 ...
Found the CCU API on port 80 (HTTP).
Use HTTPS? [Y/n]: n
Port [80]: 80
CCU user [Admin]: Admin
CCU password (input hidden):
Testing login ...
Login OK (CCU 3.87.6.20260614) — privilege level ADMIN: all tools available.
Protect this target (write tools then require confirm:true)? [y/N]: n
Make this target read-only (write tools refused entirely)? [y/N]: n
Add another CCU target? [y/N]: n
Default target (prod/dev) [prod]: prod
Wrote /home/you/.config/ccu-mcp/.env (mode 0600).
它写入的文件采用配置文件格式,每个目标对应一个带注释的区块;向导只会重写这些键,因此文件中的其他内容(LOG_LEVEL、
CACHE_DIR、MCP_*)都会保留:
# Written by ccu-mcp setup — https://github.com/claymore666/ccu-mcp#configuration
CCU_PROFILES=prod,dev
CCU_DEFAULT_PROFILE=prod
# --- target: prod ---
CCU_PROD_HOST=ccu.example
CCU_PROD_PORT=443
CCU_PROD_HTTPS=true
CCU_PROD_USER=ai
CCU_PROD_PASSWORD="..."
CCU_PROD_TLS_FINGERPRINT=90:0C:4C:F2:53:22:E7:78:...:40:ED:16:95:6E:BB:B1:53
CCU_PROD_PROTECTED=true
# --- target: dev ---
CCU_DEV_HOST=192.168.1.50
CCU_DEV_PORT=80
CCU_DEV_HTTPS=false
CCU_DEV_USER=Admin
CCU_DEV_PASSWORD=""
在已有文件上重新运行 init 时,向导会询问是否替换这些设置;添加第三个目标意味着要重新遍历整个列表,因此若只是临时添加目标,请编辑文件(或使用 setup_write_profile,它会更新或插入单个目标),然后运行
doctor。
每个目标一个密码。 ccu-mcp secret 只会写入一个键,因此需要提供目标名称——init 会在流程中提示输入密码,但
LLM 引导的流程和之后的每次轮换都要通过 secret 完成。在配置文件上不提供名称时,它会列出所需的运行命令:
$ ccu-mcp secret --env ~/.config/ccu-mcp/.env
This file configures named targets (prod, dev) — one password each:
node /home/you/.local/bin/ccu-mcp secret prod --env /home/you/.config/ccu-mcp/.env
node /home/you/.local/bin/ccu-mcp secret dev --env /home/you/.config/ccu-mcp/.env
$ ccu-mcp secret prod --env ~/.config/ccu-mcp/.env
CCU password for [email protected] (input hidden):
Wrote CCU_PROD_PASSWORD to /home/you/.config/ccu-mcp/.env (mode 0600).
这些提示有意显示为 node <path>,而不是 ccu-mcp:该路径对应打印提示的构建版本,因此复制命令不会误用缺少此子命令的旧版本。secret 在扁平的单 CCU 文件中会拒绝目标名称,在配置文件中会拒绝未知目标,因此绝不会写入错误的键。
一次性验证所有内容。 doctor 会检查每个目标的配置、连通性、证书固定值、登录状态和权限级别;任一检查失败都会以非零状态码退出:
$ ccu-mcp doctor --env ~/.config/ccu-mcp/.env
ccu-mcp doctor — checking /home/you/.config/ccu-mcp/.env
✓ configuration loads: 2 target(s), default "prod"
Target "prod" — ccu.example:443 (HTTPS)
✓ CCU API reachable
✓ pinned TLS fingerprint matches the presented certificate
✓ login OK as "ai" (CCU 3.87.6.20260614) — privilege level ADMIN
Target "dev" — 192.168.1.50:80 (HTTP)
✓ CCU API reachable
✓ login OK as "Admin" (CCU 3.87.6.20260614) — privilege level ADMIN
All checks passed.
在客户端中。 一个 MCP 服务条目即可服务所有目标——目标列表由 --env 文件提供,因此添加 CCU 时无需更改客户端配置:
{
"mcpServers": {
"ccu-mcp": {
"command": "npx",
"args": ["ccu-mcp", "--stdio", "--env", "/home/you/.config/ccu-mcp/.env"]
}
}
}
然后在聊天中询问:“配置了哪些 CCU?”(list_ccu_targets)、“读取 dev 上客厅的温度”(单次调用时指定 target: "dev")、“切换到 dev”(use_ccu)。如上所示,设置 CCU_PROD_PROTECTED=true 后,首次对 prod 执行写入操作时会要求提供 confirm: true;确认后,该目标在本次会话的剩余时间内会解除锁定——但 run_script 和 delete_system_variable 除外,这两项每次都会询问。
配置错误
有些错误会导致服务器在启动时停止,而不是忽略它们。否则,这些错误会一直被静默忽略,直到很久以后才导致失败,因此退出是有意为之的。ccu-mcp doctor 会在不启动服务器的情况下,针对 env 文件报告同样的错误,同时执行实时检查(可达性、证书固定、登录)。有一个例外:使用 --stdio --env <path> 启动时,如果配置有误,服务器会进入设置模式(并在服务器的说明中显示错误),而不是退出,这样就可以通过对话修复配置:
| 消息 | 原因及其致命性 |
|---|---|
CCU_HOST environment variable is required | 未配置 CCU(且未设置 CCU_PROFILES)。 |
CCU_PASSWORD environment variable is required | 该变量不存在。空值是可接受的——全新的 OpenCCU 设备没有 Admin 密码——因此这表示“尚未设置”。这会让单 CCU 设置模式服务器一直处于设置模式,直到 ccu-mcp secret 保存密码。 |
no password stored yet for target <name> | 配置文件形式的对应错误,仅限设置模式:CCU_<NAME>_PASSWORD 不存在。已加载的配置仍会将缺失的键读取为空值(保持不变,因此 OpenCCU 开发目标仍可正常工作)——但在判断设置是否完成时,不存在表示“尚未输入”,因此服务器会继续处于设置模式,并打印用于完成设置的 ccu-mcp secret <name> 命令。写入 CCU_<NAME>_PASSWORD= 可明确声明密码为空是有意为之。 |
CCU_DEFAULT_PROFILE is set but CCU_PROFILES is not | 配置文件设置遗留的内容。忽略它会让写入操作指向扁平配置中的 CCU_HOST 设备,而 env 文件却显示存在一个命名目标。 |
CCU_PROFILES is set but lists no profile names | 值为空,或仅包含逗号。 |
CCU_PROFILES lists "<name>" more than once | 配置文件名称重复。 |
... both map to the same env prefix CCU_<P>_* — rename one | 不同名称经过规范化后可能发生冲突:prod-a 和 prod.a 都会读取 CCU_PROD_A_*,因此它们会被静默地视为同一个目标。 |
CCU_DEFAULT_PROFILE="x" is not one of CCU_PROFILES (...) | 启动配置文件名称拼写错误。 |
profile "<name>" is missing CCU_<P>_HOST | 每个配置文件都必须指定主机;密码可以为空。 |
TLS_FINGERPRINT/CA_CERT/TLS_VERIFY is set but HTTPS is disabled | 验证代码路径仅适用于 HTTPS。忽略这些设置会让你误以为连接已通过验证,而凭据实际上是明文传输的。请设置 CCU_HTTPS=true(或 CCU_<NAME>_HTTPS=true),或者移除这些设置。 |
MCP_TLS_CERT and MCP_TLS_KEY must both be set (or both unset) | 只设置部分 TLS 配置无法提供 HTTPS 服务。 |
MCP_TRANSPORT must be "http" or "stdio" | 大小写敏感。像 STDIO 这样的拼写错误不得静默地选择 HTTP,导致启动 stdio 的客户端永远等待。 |
<VAR> must be a positive integer | 端口、超时、CACHE_TTL、速率限制、RESOURCE_POLL_INTERVAL。整个值必须由数字组成——CCU_TIMEOUT=30s 会被拒绝,而不是被读取为 30 毫秒;30.5 或 1e4 也会被拒绝,而不是截断处理。 |
<VAR> must be a positive number | 两项时长设置:MCP_AUTH_TOKEN_TTL_DAYS 和 MCP_AUTH_TOKEN_GRACE_HOURS,这两项设置允许使用小数值。 |
<VAR> must be "true" or "false" | 任意布尔设置(CCU_HTTPS、CCU_TLS_VERIFY、CCU_<NAME>_PROTECTED、CCU_<NAME>_READONLY、MCP_ALLOW_PLAINTEXT)。首尾空格和大小写均可;不接受 yes、1 和 on,因为将它们视为false会悄然关闭保护。 |
CCU_CA_CERT could not be read | 路径错误,或服务器用户无权读取该文件。 |
无需任何配置即可使用 ccu-mcp --version 和 --help,因此在排查这些问题时仍可使用它们。
工具
28 个工具,按实际用途分类:
查找 — list_devices、list_rooms、list_functions、list_interfaces、list_programs、list_system_variables、list_links、describe_device_type
读取状态 — get_value、get_values(批量)、get_paramset
更改设置 — set_value、put_paramset、set_system_variable、create_system_variable、delete_system_variable、assign_channel、unassign_channel、execute_program
检查运行状况 — get_service_messages、acknowledge_service_messages、get_rssi、get_system_info
切换目标 — list_ccu_targets、get_connection_info、use_ccu(多 CCU 配置;见上文)
其他 — help(上下文感知)、run_script(原始 HomeMatic Script,用于批量操作、重命名设备/通道、查询房间成员关系,或处理其他工具未涵盖的任何事项)
大多数工具会根据设备地址自动解析接口和值类型——你无需了解设备使用的是 BidCos-RF 还是 HmIP-RF。
资源和提示词
除了工具外,服务还会提供 MCP 资源——可浏览的 JSON 快照,客户端可以将其附加为上下文:
homematic://devices、homematic://rooms、homematic://functions、homematic://programs、homematic://sysvars、homematic://interfaces、homematic://device-types、homematic://system
服务会在后台轮询 CCU(每隔 RESOURCE_POLL_INTERVAL 秒一次),并向通过 resources/subscribe 订阅了资源的客户端发送这些资源内容发生变化时的 notifications/resources/updated 通知。
服务还附带 MCP 提示词——可从支持提示词的客户端调用的现成工作流(例如,在 Claude Code 中作为斜杠命令使用):
check-windows— 是否有窗户或门处于打开状态?room-status— 指定房间的完整状态报告set-heating— 设置房间的目标温度good-night— 为夜晚做好准备diagnostics— 检查设备问题device-info— 设备功能和参数的详细信息
room 和 device 参数支持自动补全:支持
completion/complete 的客户端会提供此 CCU 实际拥有的房间和设备名称,
因此无需记住房间在 WebUI 中的拼写方式。
MCP 协议修订版本
服务实现了修订版本 2025-11-25,并会为较旧的客户端协商降级(2025-06-18、2025-03-26、2024-11-05 均可接受)——你
无需使用特定版本的客户端。服务会声明 tools、resources
(含 subscribe)、prompts、completions 和 logging。
修订版本 2026-07-28——每个请求的协议版本、server/discover——
尚未实现:编写本文时,此服务所基于的 TypeScript SDK 尚不支持该版本,而此服务遵循该 SDK。
工作原理
服务通过 CCU 的 JSON-RPC API(与 WebUI 使用的相同 API)进行通信。启动时,它会:
- 登录并缓存会话(重启后会复用)
- 从磁盘加载设备类型缓存(或在后台预热缓存)
- 通过 stdio 或 HTTP 启动 MCP 服务
设备类型架构会缓存在本地,因此 AI 无需每次都访问 CCU,即可查询有效参数、类型和值范围。
返回的值使用原生类型——21.5 而不是 "21.500000",true 而不是 "true"。
已测试的设备
此服务已在生产环境中的 debmatic 安装上进行测试,涉及以下设备:
- HmIP-eTRV-2 / eTRV-2 I9F(散热器恒温器)
- HmIP-STHD(带湿度功能的墙面恒温器)
- HmIP-WTH-2(墙面恒温器)
- HmIP-SWDO-I(门窗触点)
- HmIP-STHO(室外温度/湿度传感器)
- HmIP-ESI(电能/燃气表)
- HmIP-FALMOT-C12(地暖控制器)
- HmIP-HEATING(虚拟供暖组)
- HmIP-WRCC2(墙面遥控器)
- HM-PB-6-WM55(BidCos 六键遥控器)
- RPI-RF-MOD(无线模块)
其他设备类型也应该可以使用——服务会向 CCU 查询参数说明,而不是维护静态设备数据库。
更新日志
发行说明——包括升级前需检查的行为变更
(更严格的配置验证、/health 响应结构、按会话确认写入、
重试语义)——请参阅 CHANGELOG.md。
获取帮助与参与贡献
- 遇到故障,或有功能建议? 请提交议题: github.com/claymore666/ccu-mcp/issues
- 有问题、需要设置帮助,或想讨论 HomeMatic? 请访问
HomeMatic 论坛——维护者在论坛上的用户名是
claymore666。 - 发现安全问题? 请不要公开发布。有关私下报告的方式,请参阅 SECURITY.md。
- 想提交补丁? CONTRIBUTING.md 介绍了设置方法、 目标分支、编码规范和测试政策。
所有参与者都应遵守 行为准则。
项目文档
| 文档 | 内容 |
|---|---|
| ROADMAP.md | 项目的发展方向,以及明确不会实现的内容 |
| GOVERNANCE.md | 决策者、决策方式,以及已知的连续性缺口 |
| SECURITY.md | 报告方式、安全要求、威胁模型 |
| docs/architecture.md | 高层设计和请求流程 |
| docs/assurance-case.md | 安全要求成立的原因及相关证据 |
| CHANGELOG.md | 各个版本的变更内容 |
相关项目
- OpenCCU — 由社区维护、无云服务的 CCU 固件,适用于 Raspberry Pi、x86/ARM 以及 CCU3/ELV-Charly 硬件(原名 RaspberryMatic;基于 OCCU 框架构建)
- debmatic — 在 Debian、Ubuntu、Raspberry Pi OS、Armbian 上运行 HomeMatic
- OCCU — eQ-3 原版 Open CCU SDK(上游 HomeMatic 软件);目前正逐步由社区维护的 OpenCCU 取代
- MCP — Model Context Protocol 规范
- ccu-ai-mcp,由 Mathias (mdzio) 开发 — 一个面向 HomeMatic 的同类 MCP 服务,采用刻意不同且优雅的方案(精简的 Go 核心搭配用户自定义的 HM-Script 工具)。请参阅他在 HomeMatic 论坛 上发布的介绍。
许可证
MIT
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。