内容
# ccu-mcp
通过Claude、Cursor或任何MCP客户端与您的HomeMatic智能家居对话。
<a href="https://glama.ai/mcp/servers/claymore666/ccu-mcp">
<img width="380" height="200" src="https://glama.ai/mcp/servers/claymore666/ccu-mcp/badge" alt="ccu-mcp MCP server" />
</a>
ccu-mcp连接到CCU内置的JSON-RPC API,并将您的设备、房间、程序和系统变量作为MCP工具公开。无需插件,无需XML-API,无需云服务 — 直接连接到本地网络上的CCU。
与任何HomeMatic CCU兼容: [debmatic](https://github.com/alexreinert/debmatic) (Debian上的HomeMatic),CCU3或 [OpenCCU](https://github.com/OpenCCU/OpenCCU) (前身为RaspberryMatic)— 任何公开标准`/api/homematic.cgi`端点的设备。
## 功能
询问您的AI助手:
- “浴室的温度是多少?”
- “有任何窗户打开吗?”
- “将客厅的暖气设置为21度”
- “给我看看所有电池电量低的设备”
- “天然气表的读数是多少?”
- “哪些设备电池电量低或长时间未被看到?”
- “查找所有通道名称与其设备名称不匹配的设备”
- “重命名所有设备以遵循一致的命名约定,并带有楼层标签(UG / OG / EG)”
- “哪个房间有窗户传感器?”
MCP服务器处理设备发现、类型解析、会话管理和值转换 — AI只需调用工具。
## 先决条件
- 运行中的HomeMatic CCU(debmatic,CCU3或OpenCCU — 前身为RaspberryMatic)在您的网络上可访问
- CCU的管理员用户名和密码(您登录WebUI时使用的相同凭证)
- Node.js 22+(用于从源代码运行或stdio模式)或Docker
## 快速入门
```bash
export CCU_HOST=您的-ccu-主机名或-ip
export CCU_PASSWORD=您的-ccu-管理员密码
npx ccu-mcp --stdio
```
如果它打印`server_ready`到stderr,则表示它正在工作。按Ctrl+C停止。现在在您的MCP客户端中设置它 — 请参见下文。
## 安装
有两种运行此程序的方法: **stdio** (服务器作为MCP客户端的子进程运行)或 **HTTP** (服务器在Docker中独立运行,客户端通过网络连接)。请选择一种。
### 选项A:stdio(直接,最简单)
这是最简单的设置。您的MCP客户端(Claude Code,Cursor等)启动服务器作为子进程 — 无需Docker,无需网络配置,无需身份验证令牌。
对于Claude Code,在您的项目目录(或您将使用Claude Code的任何目录)中创建一个`.mcp.json`文件:
```json
{
"mcpServers": {
"ccu-mcp": {
"command": "npx",
"args": ["ccu-mcp", "--stdio"],
"env": {
"CCU_HOST": "您的-ccu-主机名或-ip",
"CCU_PASSWORD": "您的-ccu-管理员密码"
}
}
}
}
```
将`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:
```bash
claude mcp add ccu-mcp -- npx ccu-mcp --stdio
```
### 选项B:Docker(独立的HTTP服务器)
如果您想让服务器独立运行 — 例如在家庭服务器上,为多个客户端提供访问,或当您的MCP客户端支持HTTP远程访问时使用。
**1. 启动容器:**
```bash
docker run -d \
--name ccu-mcp \
-e CCU_HOST=您的-ccu-主机名或-ip \
-e CCU_PASSWORD=您的-ccu-管理员密码 \
-v ccu-data:/data \
-p 3000:3000 \
ccu-mcp
```
**2. 获取身份验证令牌。** 服务器在首次启动时生成一个随机Bearer令牌,并将其保存在容器的數據卷中。您需要此令牌来验证您的MCP客户端。使用以下命令获取它:
```bash
docker exec ccu-mcp grep MCP_AUTH_TOKEN /data/.env
```
这将打印类似`MCP_AUTH_TOKEN=e96suzi1iG0H-GPif6K2...`的内容。`=`之后的部分是您的令牌。
**3. 配置您的MCP客户端。** 如果您的客户端使用`.mcp.json`,请添加HTTP服务器:
```json
{
"mcpServers": {
"ccu-mcp": {
"url": "http://您的服务器-ip:3000",
"headers": {
"Authorization": "Bearer 粘贴您的令牌"
}
}
}
}
```
要自动注入令牌(需要`jq`):
```bash
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. 检查它是否健康:**
```bash
curl http://localhost:3000/health
```
#### 基于浏览器的客户端(CORS)
默认情况下,HTTP服务器发送 **无** CORS标头,因此随机网页无法驱动本地实例。要允许基于浏览器的MCP客户端(如 [MCP Inspector](https://github.com/modelcontextprotocol/inspector))直接连接,请设置`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`的请求。如果您通过反向代理、容器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)内仍然有效,以便飞行中的客户端存活下来。过期也会实时强制执行:过时的令牌会在运行时被拒绝,并带有`401` + `WWW-Authenticate: Bearer … error="invalid_token"`错误。为了更早地强制轮换,请删除`$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](https://www.fail2ban.org/),它在请求到达服务器之前禁止源IP。要使之易用,每个拒绝的请求都会在stderr上记录一个结构化行:
```json
{"ts":"2026-06-18T17:28:00.370Z","level":"warn","msg":"auth_failed","client":"203.0.113.7","hadToken":true}
```
现成的fail2ban配置包含在 [`fail2ban/`](fail2ban/) 中:复制 `filter.d/ccu-mcp.conf` 到 `/etc/fail2ban/filter.d/` 和 jail in `jail.d/ccu-mcp.local` 到 `/etc/fail2ban/jail.d/`(默认为5次失败10分钟 → 1小时禁令)。服务器记录到stderr,因此指向它收集的位置 — 日志(`backend = systemd`)时作为单元运行,或重定向stderr/`docker logs`时作为文件运行;两者都在jail文件中详细说明。需要 `LOG_LEVEL=warn` 或更低级别(默认为`info`,足够),`error`会抑制该行。反向代理记录的IP是代理的,因此在反向代理的访问日志中运行fail2ban。
CORS支持首先由 [@marcinn2](https://github.com/marcinn2) 在他的分支 [marcinn2/debmatic-mcp](https://github.com/marcinn2/debmatic-mcp) 中实现 — 谢谢!
### HTTPS
如果您的CCU使用HTTPS(自签名证书可以),请添加以下环境变量:
```bash
CCU_HTTPS=true
CCU_PORT=443
```
服务器自动接受自签名证书 — 默认情况下 **关闭** 证书验证(服务器在运行未经验证的连接时记录警告)。实际验证连接并关闭MITM间隙,您有三个选项:
- **固定指纹** (最简单的自签名设备证书):设置`CCU_TLS_FINGERPRINT`为证书的SHA-256(十六进制,可带或不带冒号)。连接被拒绝,除非CCU呈现确切的证书。阅读它:
```bash
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_HOST` | 必需 | 您的CCU的主机名或IP |
| `CCU_PASSWORD` | 必需 | CCU管理员密码 |
| `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脚本执行超时(毫秒) |
| `LOG_LEVEL` | `info` | `error`, `warn`, `info`, 或 `debug` |
| `CACHE_DIR` | `/data` | 存储设备类型缓存和会话的位置 |
| `CACHE_TTL` | `86400` | 缓存生命周期(秒) |
| `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`一起接受; 删除它(及其`restart`)以结束重叠。仅限显式令牌路径 |
| `MCP_AUTH_TOKEN_TTL_DAYS` | 未设置(永不过期) | 自动生成的令牌生命周期(天数)(允许分数) 。过期后它会自动轮换到下一个启动并在stderr上打印,而替换的令牌在`MCP_AUTH_TOKEN_GRACE_HOURS`(默认为24)内仍然有效,以便飞行中的客户端存活下来。 |
| `MCP_AUTH_TOKEN_GRACE_HOURS` | `24` | 自动轮换后,重叠期间(小时)内仍接受旧令牌 |
| `MCP_ALLOWED_ORIGINS` | 未设置 | 浏览器来源的逗号分隔的允许列表。 未设置 = 无跨源浏览器访问(默认拒绝)。 允许的来源被精确地反映在`Access-Control-Allow-Origin`中(永不`*`); 该列表还驱动DNS重绑定源检查 |
| `MCP_ALLOWED_HOSTS` | `localhost`/`127.0.0.1` | DNS重绑定保护接受的额外`Host`值(逗号分隔的`host:port`); 将您的主机名添加到反向代理或容器DNS名称 |
| `MCP_HOST` | 未设置(所有接口) | HTTP侦听器的绑定地址; 设置`127.0.0.1`以限制环回(例如在TLS终止的代理后面),这也会使纯文本警告静默 |
| `MCP_TLS_CERT` / `MCP_TLS_KEY` | 未设置 | PEM证书/密钥路径。 设置 **两者** 以本地提供MCP HTTPS; 留空则为纯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资源变更通知的轮询间隔(秒) |
### 如何提供这些(内联,`.env`或导出)
所需的`CCU_HOST` / `CCU_PASSWORD`(以及所有其他内容)是 **环境变量**。在您喜欢的任何一种中提供它们 - 您只需要一个:
- **内联在`.mcp.json`** - 上面显示的`env`块(最简单;自包含)。
- **Shell `export`** - 如上面的[快速入门](#快速入门)所示。
- **`.env`文件** - 将秘密排除在`.mcp.json`之外。该服务器不读取`.env`,因此请使用Node的内置标志(Node≥20.6):
```json
{
"mcpServers": {
"ccu-mcp": {
"command": "node",
"args": ["--env-file=/path/to/.env", "/path/to/ccu-mcp/dist/index.js", "--stdio"]
}
}
}
```
复制 [`.env.example`](.env.example) 到 `.env` 并填写(它记录了每个变量)。Docker用户可以使用相同的文件与 `docker run --env-file .env`
或compose的`env_file:`。保持`.env` gitignore。
### 多个CCU目标(配置文件)
默认情况下,上面的`CCU_*`变量配置单个CCU。要从一个服务器访问多个CCU(例如 **prod + dev**),请定义命名配置文件。像其他配置一样设置它们(内联,`.env`或导出 — 请参见上文):
```sh
CCU_PROFILES=prod,dev
CCU_DEFAULT_PROFILE=prod # 启动时活动(默认为第一个列表)
CCU_PROD_HOST=ccu.example
CCU_PROD_USER=ai
CCU_PROD_PASSWORD=...
CCU_PROD_HTTPS=true
CCU_PROD_PROTECTED=true # 写入确认:true
CCU_PROD_READONLY=true # 写入工具直接拒绝
CCU_DEV_HOST=127.0.0.1
CCU_DEV_PORT=18080
CCU_DEV_USER=Admin
CCU_DEV_PASSWORD= # 可能为空(例如OpenCCU开发盒)
```
每个配置文件采用与平面变量相同的设置,带有前缀
`CCU_<NAME>_`(名称大写,非字母数字字符→ `_`):`HOST`(必需),
`PASSWORD`(可能为空),`USER`,`PORT`,`HTTPS`,`TIMEOUT`,`SCRIPT_TIMEOUT`,
`TLS_FINGERPRINT`,`CA_CERT`,`TLS_VERIFY` — 另外两个策略标志:
- `CCU_<NAME>_PROTECTED=true` — 写入工具除非调用`confirm: true`,否则拒绝写入。对于该目标,`confirm: true`解锁写入权限,持续到会话结束。
- `CCU_<NAME>_READONLY=true` — 写入工具直接拒绝。
如果未设置`CCU_PROFILES`,则使用平面`CCU_*`变量作为单个`default`
配置文件(行为不变)。在运行时,`list_ccu_targets`显示目标,
`get_connection_info`报告活动目标,而`use_ccu`切换它。读取工具
还接受一个可选的`target`,用于在单个调用中从另一个CCU读取而无需切换。
## 工具
25种工具,按实际需求分类:
**查找事物** — `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`
**其他** — `help`(上下文感知), `run_script`(原始HomeMatic脚本,用于批量操作,重命名设备/通道,查询房间成员资格,或其他未涵盖的内容)
大多数工具会自动从设备地址解析接口和值类型;您不需要了解设备位于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`秒),并在设备列表更改时通知连接的客户端。
它还附带MCP **提示** — 现成的您可以在支持它们的客户端中调用的工作流(例如Claude Code中的斜杠命令):
- `check-windows` — 有任何窗户或门打开吗?
- `room-status` — 房间的完整状态报告
- `set-heating` — 设置房间的目标温度
- `good-night` — 准备房子过夜
- `diagnostics` — 检查设备问题
- `device-info` — 设备功能和参数的详细资料
## 工作原理
服务器与CCU的JSON-RPC API(WebUI使用的同一个API)通信。在启动时:
1. 登录并缓存会话(在重启期间重用)
2. 从磁盘加载设备类型缓存(或在后台预热)
3. 在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 6按钮遥控器)
- RPI-RF-MOD(无线电模块)
其他类型的设备也应该有效 — 服务器会向CCU查询参数描述,而不是维护静态设备数据库。
## 相关项目
- [OpenCCU](https://github.com/OpenCCU/OpenCCU) — 社区维护的、云免费的CCU固件,用于Raspberry Pi、x86/ARM和CCU3/ELV-Charly硬件(前身为 **RaspberryMatic**;基于OCCU框架构建)
- [debmatic](https://github.com/alexreinert/debmatic) — 在Debian、Ubuntu、树莓派操作系统、Armbian上运行HomeMatic
- [OCCU](https://github.com/eq-3/occu) — eQ-3的原始开放CCU SDK(上游HomeMatic软件);现在由社区维护的 [OpenCCU](https://github.com/OpenCCU/OpenCCU) 取代
- [MCP](https://modelcontextprotocol.io/) — 模型上下文协议规范
- [ccu-ai-mcp](https://github.com/mdzio/ccu-ai-mcp) 由 **Mathias (mdzio)** 提供 — 采用全新的、优雅的方法的HomeMatic的MCP服务器。参见他在 [HomeMatic论坛](https://homematic-forum.de/forum/viewtopic.php?t=88426) 上的文章。
## 许可证
MIT
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器