内容
send-to-influx
===========
https://github.com/L337-org/send-to-influx
-----------------------------------------
将智能家居和能源设备的指标收集到InfluxDB中,然后真正地控制它们!
内置的 [MCP 服务器](#remote-mcp-server) 意味着您可以选择自己的AI作为一个地方来**控制**您的设备,查询它们的**实时和历史状态**,并询问关于**不同测量值之间关系**的**复杂问题**,以及在您的数据中**发现趋势**。
由于数据存储在InfluxDB中,因此它也可以在Grafana仪表盘和其他支持它的可视化工具中**显示**。
目前,它支持Hue Bridges,MyEnergi Zappi/Eddi/Harvi设备,Open-Meteo天气,国家电网碳强度,Octopus Energy,Nuki智能锁和Speedtest网络性能数据源。大多数是只读的;当您选择加入时,可以通过MCP服务器**控制**Hue灯/插座和按需Speedtest运行。
它可以作为.deb包安装在支持的平台上,或者在Python虚拟环境中直接从源代码运行。
有关每个源收集哪些字段以及单位的详细参考,请参见 [UNITS.md](UNITS.md)。
目录
--------
- 数据源
- [Hue Bridge](#hue-bridge)
- [MyEnergi Zappi / Eddi / Harvi](#myenergi-zappi--eddi--harvi)
- [英国国家电网碳强度](#uk-national-grid-carbon-intensity)
- [Open-Meteo](#open-meteo)
- [Octopus Energy](#octopus-energy)
- [Nuki智能锁(MQTT)](#nuki-smart-lock-mqtt)
- [Speedtest](#speedtest)
- [InfluxDB设置](#influxdb)
- [运行脚本](#running-the-script)
- [使用.deb包](#using-the-deb-package)
- [远程MCP服务器(通过MCP客户端查询和控制设备)](#remote-mcp-server)
- [用法/命令行参考](#usage)
- [贡献](#contributing)
- [隐私和安全](#privacy-and-security)
Hue Bridge
----------
它将从Hue运动传感器收集占用率、温度和光照读数,从智能插座收集开关状态,从灯收集亮度,但可以修改为从网桥收集其他数据。
要为Hue Bridge创建用户名和密码,请按照以下网址的说明进行:https://developers.meethue.com/develop/get-started-2/
Hue网桥通常通过`https`使用自签名本地证书访问,因此默认情况下跳过TLS验证(`insecure: true`)。如果您的网桥具有有效的证书,请在`hue`设置块中将`insecure`设置为`false`以启用验证。
MyEnergi Zappi / Eddi / Harvi
-----------------------------
有关如何获取API密钥的信息,请参阅:https://support.myenergi.com/hc/en-gb/articles/5069627351185-How-do-I-get-an-API-key
一些API字段的信息可以在以下网址找到:https://github.com/twonk/MyEnergi-App-Api
- **Zappi**:电动汽车充电器。收集实时状态字段以及每日能量总值(充电、导入、导出、生成)。
- **Harvi**:CT钳能量监测器。收集CT钳功率读数(ectp1/ectp2/ectp3)和通道名称。
- **Eddi**:热水分流器。收集实时状态字段(频率、电压、分流量、温度等)。
英国国家电网碳强度
------------------------------
从国家电网ESO碳强度API获取实时的国家电网碳强度(gCO2/kWh)和发电燃料混合比例(风能、太阳能、天然气、核能等)。无需API密钥。数据每30分钟更新一次。
API文档:https://carbon-intensity.github.io/api-definitions/
在设置中将`include_generation`设置为`true`,即可收集发电燃料混合百分比。
Open-Meteo
----------
无需API密钥即可免费获取天气数据。配置纬度和经度,并从`current`天气变量中选择要收集的字段(请参阅https://open-meteo.com/en/docs获取完整列表)。推荐的间隔为15分钟(900秒)或更长。
Octopus Energy
--------------
通过Octopus Energy API从智能电表收集半小时的电力消耗数据。您的API密钥可在https://octopus.energy/dashboard/developer/找到。
如果您还配置了`gas_mprn`和`gas_meter_serial`,还可以收集天然气消耗,记为`gas_consumption`(请参阅 [UNITS.md](UNITS.md) 了解其单位,该单位取决于您的表类型)。
如果您使用的是分时电价(例如Agile Octopus),您可以配置`product_code`和`tariff_code`来收集当前的电价单元以及消耗量。
注意:智能电表读数通常延迟高达24小时,因此消耗数据始终代表最近的过去读数,而不是实时使用情况。
Nuki智能锁(MQTT)
----------------------
通过Nuki的本地MQTT API(支持Smart Lock 3.0 Pro固件3.5.12+和所有更新的WiFi型号)从WiFi连接的Nuki智能锁收集锁状态和门传感器状态(以及电池和连接字段)。 send-to-influx保持持久订阅,并在一个锁或门传感器状态更改时写入一个点,因此可以在两次轮询之间捕捉到门开启和关闭。该功能还会每隔`interval`秒进行一次完整的全状态快照,作为安全网(并保持空闲锁的状态心跳);由于Nuki发布每个状态主题时都带有MQTT保留标志,因此快照的简短重订阅会接收到代理人配置的每个锁的最新已知状态。
> **行为变更 5.1:** MQTT源(Nuki)现在实时流式传输状态更改,而不仅仅是每`interval`次采样一次,因此您将看到更密集的数据 - 更多的点,在事情实际变化的时刻。测量和字段名称保持不变,因此现有的仪表盘和查询保持不变;无需新配置,升级时无需操作。
此功能需要LAN上的MQTT代理程序,例如Mosquitto。注意,Nuki设备仅支持对私有范围LAN地址使用纯净的、未加密的MQTT(端口1883),因此请仅在受信任的网络上使用此功能。
在Debian/Ubuntu上设置Mosquitto:
1. `sudo apt install mosquitto mosquitto-clients` - 客户端工具(下文中使用以验证设置)与代理程序分开在不同的软件包中,不与之捆绑。
2. 创建`/etc/mosquitto/conf.d/local.conf`(文件名必须以`.conf`结尾,否则将被静默忽略):
listener 1883 0.0.0.0
allow_anonymous false
password_file /etc/mosquitto/passwd
3. 为锁(发布者)和send-to-influx(订阅者)创建两个单独的代理凭证。不要重用一个登录名,因为可以独立旋转或吊销两者:
sudo mosquitto_passwd -c /etc/mosquitto/passwd nuki-lock
sudo mosquitto_passwd /etc/mosquitto/passwd sendtoinflux
在重新启动Mosquitto之前创建密码文件 - 它拒绝启动,如果配置的`password_file`尚不存在:
4. 文件由`root:root`所有,模式为`600`,而`mosquitto`服务用户无法读取,因此修复组和模式:
sudo chgrp mosquitto /etc/mosquitto/passwd
sudo chmod 640 /etc/mosquitto/passwd
`mosquitto_passwd`会在后续运行中警告此所有权问题(“组不是root ...”)- 这是一个已知的上游缺陷;不要遵循其建议的`chown root`/`chmod 0700`修复程序,否则代理将无法读取文件:
5. 重启Mosquitto(`sudo systemctl restart mosquitto`)。
6. 在Nuki应用中:设备管理 > MQTT - 输入代理的地址、`nuki-lock`凭证,并关闭**“允许锁定”**,以便锁仅发布状态,从不订阅命令主题(此集成无论如何都是只读的)。
7. 使用`sendtoinflux`凭证(即`settings.yaml`中的凭证)验证端到端:
mosquitto_sub -h <broker-host> -u sendtoinflux -P <password> -t 'nuki/#' -v
这应该立即打印锁的所有保留状态主题。
然后在`settings.yaml`中填写共享的`mqtt:`块,并添加`nuki`到`sources:`。在打包安装中,可以使用`send-to-influx-set-credential`将代理密码移动到`systemd-creds`中,就像其他凭证一样。
如果您的代理允许匿名访问,您可以留空`username`和`password` - 上述两凭证设置是推荐的默认值,而不是必需品。要将已身份验证的安装切换到匿名安装,请在`settings.yaml`中留空`mqtt.username`并运行`sudo send-to-influx-set-credential mqtt-password --remove`。安装程序无法执行此操作,因为空白答案意味着“保留当前值”。
Speedtest
---------
此功能使用speedtest-cli Python库,运行下载和上传测试并存储结果。
如果对候选服务器的所有延迟探测都失败,speedtest-cli会报告一个不合常理的`ping`(硬编码惩罚值平均分配,最高可达1800000毫秒)而不是引发错误。speedtest-cli使用硬编码10秒连接超时时间来计时每个延迟探测,因此没有实际测量值可以超过5000毫秒;任何`ping` >= 5000毫秒都被视为不可靠/失败的测量值,并引发连接错误(重试并带有回退)而不是写入InfluxDB。
InfluxDB
--------
支持InfluxDB v1和v2。
对于v1,在`influx`设置块中配置`user`和`password`,并按源使用`db`:
influx:
url: "http://influx.example.com:8086"
user: "your_user"
password: "your_password"
对于v2,请使用`token`和`org`代替,并可选地为每个源使用`bucket`(如果未设置`bucket`,则默认为`db`):
influx:
url: "http://influx.example.com:8086"
token: "your_token"
org: "your_org"
如果您的InfluxDB URL使用`https`和自签名或内部颁发的证书,则默认情况下会失败TLS证书验证。在`influx`设置块中设置`insecure: true`以跳过验证:
influx:
url: "https://influx.example.com:8086"
user: "your_user"
password: "your_password"
insecure: true
运行脚本
------------------
- 复制example_settings.yaml到settings.yaml
- 修改文件权限,例如`chmod 600 settings.yaml`,使其不允许其他用户读取
- 填写您的设备和InfluxDB的值
- 使用`pip install -r requirements.txt`安装运行时依赖
- 将脚本在screen会话中运行并等待数据流入。
或者,请参阅下面的[使用.deb包](#using-the-deb-package)。
日志输出发送到stdout,带有时间戳和日志级别,例如:
2026-06-29 14:23:01 WARNING 源'hue'失败:连接超时。5秒后重启(尝试1)。
启动时,INFO行记录启动的版本和将要运行的源,因此可以在日志中看到重启:
2026-06-29 14:23:00 INFO 启动send-to-influx v1.0(源=hue, zappi, speedtest)
还可以通过在`settings.yaml`中添加可选的`logfile`键将日志写入文件。当日志达到`log_max_bytes`(默认为10 MiB)时,会自动旋转日志文件,最多保留`log_backup_count`个旧副本(默认为3):
logfile: "/var/log/send-to-influx.log"
# log_max_bytes: 10485760
# log_backup_count: 3
如果您[使用.deb包](#using-the-deb-package),则不需要这样做:该包自带一个单独的专用日志文件机制,用于记录服务消息,使其脱离共享的`daemon.log`/`syslog`日志。您可以自行设置日志文件,但请不要指向`/var/log/send-to-influx.log`,因为这是打包机制写入的文件,您将看到两个独立的写入同一个文件的日志。
日志级别默认为`INFO`。在`settings.yaml`中设置可选的`loglevel`键(例如`DEBUG`、`WARNING`),或在命令行上传递`-v`/`--verbose`以强制设置为`DEBUG`:
loglevel: "INFO"
默认情况下,脚本在`settings.yaml`所在的项目根目录中查找`settings.yaml`。要使用位于其他位置的配置文件(例如`/etc/send-to-influx/settings.yaml`用于打包安装),请传递`--settings <path>`:
sendtoinflux.py --settings /etc/send-to-influx/settings.yaml
默认情况下,`sendtoinflux.py`为`sources`设置中列出的每个源启动一个工作进程。每个源都在自己的循环中使用自己的`interval`运行。
如果源遇到瞬时故障(例如,与其API或InfluxDB通信的网络错误) - 无论是在单源还是多源模式下运行 - 它都会自动重启并具有指数退化(基准5秒,最大300秒),以避免紧密的故障循环。在多源模式下,只会重试失败的源;其他源继续运行。配置问题(例如,源缺少其设置部分)不会重试:在单源模式下,进程退出,退出代码为1;在多源模式下,该源的工作进程停止,并记录关键日志,而其他源继续运行。
如果InfluxDB本身暂时不可达,则写入失败的点会在内存中缓冲(每个源,最多几个点),并在InfluxDB可达时自动发送 - 最旧的先发送,分成几个请求。写入失败的点(例如,由于存储桶保留窗口已过时)会被丢弃,而不会阻塞后面的点。缓冲区仅存在于内存中:它不会在进程重启时存活,如果设置文件的InfluxDB目标在后台更改,则会将日志记录发送到新的目标。心跳状态点永远不会被缓冲 - 它们是实时信号,因此失败的点会直接被丢弃。
每次收集周期(成功或失败)后,都会将`collector_status,source=<name>`心跳点写入InfluxDB,并带有字段`ok`(`1`/`0`)和`consecutive_failures`。如果没有心跳,Grafana中只会显示一个空白。心跳不会在`--print`模式下写入,因为该模式永远不会发送任何数据到InfluxDB。
命令行选项:
- 要运行单个数据源,请使用`source`选项,例如`sendtoinflux.py --source zappi`。
- 要转储Hue Bridge的所有数据以查看名称等,请运行`sendtoinflux.py --source hue --dump`,它将输出所有数据作为json。当`sources`在`settings.yaml`中配置时,必须同时使用`--dump`和`--source`,以便脚本知道要转储哪个源。
- 要将数据打印为json而不是发送到InfluxDB,请运行`sendtoinflux.py --source hue --print`,它将解析的数据结构输出为json。
- 要检查`settings.yaml`是否有效而启动任何收集器,请运行`sendtoinflux.py --check-config`。它打印`Configuration OK`并退出0,或者退出1并显示错误详细信息。
- 要打印安装的版本,请运行`sendtoinflux.py --version`。
多源模式的配置选项:
- `sources`: `--source`不提供时的源名称列表并行运行
- `stagger_seconds`(可选):源启动之间的延迟(默认为`10`)- 失败重试:具有5秒基准和300秒最大值的指数退化
使用.deb包----------------------
您可以将send-to-influx安装为systemd管理的服务,通过.deb包。
### 从APT仓库安装
curl -fsSL https://apt.l337.org/send-to-influx.gpg | sudo tee /usr/share/keyrings/send-to-influx.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/send-to-influx.gpg] https://apt.l337.org/ ./" | sudo tee /etc/apt/sources.list.d/send-to-influx.list
sudo apt update
sudo apt install send-to-influx
存储库仅保留几个版本的`.deb`文件(较旧版本可在 [Releases页面](https://github.com/L337-org/send-to-influx/releases)上找到),并由 [L337-org/apt](https://github.com/L337-org/apt)维护,该存储库从L337-org项目的GitHub Releases中聚合`.deb`发布资产(新版本会在一小时内到达)。
### 自己构建
```bash
packaging/deb/build-deb.sh
sudo dpkg -i send-to-influx_*.deb
```
该软件包是与架构无关的(`all`)- 应用程序及其依赖项都是纯 Python 代码,
并且任何可选的编译加速器(例如 PyYAML 的加速器)都在构建时从捆绑的 venv 中剥离,
而是采用纯 Python 代码的备用方案 - 因此它可以在任何 Debian/Ubuntu 机器上构建
(该脚本需要 `/usr/bin/python3` 和 `dpkg-deb`)并安装在任何 Debian/Ubuntu 架构上,
包括 arm64(例如树莓派)。CI 在每次推送/拉取请求时在 arm64 运行器上构建软件包
(一个必需的状态检查)并针对它运行 `packaging/deb/test-packaging.sh` - 一个场景套件,
涵盖升级到最新发布的版本、新的 debconf 种子安装、纯升级在手动编辑的配置文件上保持沉默、
运行服务时的重启、在升级时重启、debconf 语义、debconf 默认优先级下的问题可见性和清理,
以及捕获将来的依赖项更改,这些更改将使编译扩展变为负载承载而非可选,然后才能合并。
同一个套件也在 Debian 12 容器(systemd 252,与树莓派 OS bookworm 匹配)中运行,
因此也涵盖了较旧的 systemd-creds 工具的行为差异 - 运行器的新 systemd 曾经准确掩盖了这种差异。
venv 的 `site-packages` 通常位于 `lib/pythonX.Y/` 下,其名称与创建它的解释器的确切主版本号相同,
这将安装目标绑定到构建主机上(例如 GitHub 的 CI 运行器镜像)使用的 Python 版本,
而不是安装目标实际具有的版本,并且这两个版本会随着时间的推移而不同步。
由于 venv 中的所有内容都是纯 Python 代码(见上文),`build-deb.sh` 将 3.10 到 3.30 的每个小版本号的 `lib/pythonX.Y`
链接到实际填充的版本号,并声明一个匹配的 `python3 (>= 3.10), python3 (<< 3.31)` 依赖项,
因此软件包无论目标的 `/usr/bin/python3` 属于哪个小版本号都能正确安装(上限保持依赖项和符号链接范围不会无声无息地分开 -
如果 Python 接近 3.30,会将两者一起调整)。
### 安装后
无论哪种方式,软件包都会安装(但不会启动)服务,因为它首先需要配置:
- 编辑 `/etc/send-to-influx/settings.yaml`(在软件包首次安装时从 `example_settings.yaml` 创建,
并且在后续升级中不会被触及 - 只有全新安装或您自己的编辑,或者下面描述的 debconf/`send-to-influx-set-credential` 流程,
才会写入该文件)。
- 然后启用并启动它:`systemctl enable --now send-to-influx`
在升级过程中,**正在运行**的服务会自动重启,以便它能实际使用新版本 -
升级通常是无人值守的(cron/apt 定时器),在这种情况下,输出中的“请重启”提示永远不会被看到,
否则旧代码将继续运行,直到下一次重启。**已停止**的服务保持停止状态;升级从不启动任何服务。
日志进入 journal(`journalctl -u send-to-influx -f`)并具有与上述 stdout 相同的带时间戳的格式。
Journald 还会像往常一样转发到 syslog,并且软件包会附带 rsyslog 和 logrotate 配置
(`/etc/rsyslog.d/49-send-to-influx.conf`,`/etc/logrotate.d/send-to-influx`,
`Recommends:`,不是 `Depends:` - 无论如何,服务都可以通过 journal 工作)
将此服务的消息从共享的 `daemon.log`/`syslog` 重定向到它们自己的 `/var/log/send-to-influx.log`。
无需配置此功能;只要安装了 rsyslog,就会启用重定向,并且每天进行轮换(保留 7 天)-
与 haproxy 等软件包使用的模式相同 - 此外还需要 logrotate,它会自动运行。
如果没有 logrotate,文件仍然会正确写入,只是不会轮换。直接编辑任一文件(两者都是真正的、
可编辑的配置文件,在升级过程中保留)以更改保留期或过滤。
### 安装期间配置(debconf)
`.deb` 的全新交互式安装会提示 debconf:首先是您的 InfluxDB 连接详细信息(无论您如何回答其他问题,
都会无条件询问 - 如果您只想将现有的 InfluxDB 凭证移动到 `systemd-creds` 而不触及任何其他内容,则此功能很有用),
然后是您要配置的数据源的列表,然后 - 仅对于您选择的数据源 - 实际连接到数据源的 API 的字段(凭证和诸如 Hue 网桥主机名或 Octopus 电表号码之类的内容;
调优设置(如间隔)保留其预设值,可以在以后在 `settings.yaml` 中调整)。您还会被问到(默认为“否”)是否启用
[远程 MCP 服务器](#远程MCP服务器) - 回答“是”并收集其公共 URL、登录用户名和密码(密码像其他凭证一样进入 `systemd-creds`)。
纯软件包升级从不提示,从不应用 debconf 答案:您的 `settings.yaml` 和凭证仅在全新安装的提示或显式 `sudo dpkg-reconfigure send-to-influx`
(在任何时候重新运行相同的流程)时写入。您输入的机密存储在 `systemd-creds`(见下文)中,从不以明文写入 `settings.yaml`。
debconf 本身在 `postinst` 运行期间会暂时保存您输入的内容,使用其自己的独立、 `chmod 600` 密码存储,
然后在读取完毕后立即将每个密码类型的答案清除为一个空字符串 - 无论后续迁移到 `systemd-creds` 是否成功,
请参阅 SECURITY.md 获取详细信息。非机密答案(例如 Hue 网桥主机名、Octopus 电表号码等)不是密码类型,而是像其他软件包的 debconf 答案一样,
存储在 debconf 的常规数据库中。如果每个数据源所需的所有字段都已回答 **并且** 您的 InfluxDB 连接详细信息已成功解析,
则会在 `settings.yaml` 中自动将其添加到 `sources:` 中,并在可能的情况下为您创建所需的 InfluxDB 数据库/存储桶 -
如果数据源的所有其他内容都已填写完毕,但 InfluxDB 本身无法访问或身份验证,则不会启用该数据源。
当您使用 `dpkg-reconfigure` 重新访问提示时,已留空的机密字段如果已存储在 `systemd-creds` 中,则视为已提供,
因此添加新数据源永远不需要重新输入已经迁移的凭证。
您可以将所有问题留空,而是手动配置 `settings.yaml` - 此处不需要任何内容。在任何时候都可以重新运行 `sudo dpkg-reconfigure send-to-influx`
以更改您的答案;密码提示始终会再次显示为空白(debconf 自己的 UI 约定,用于密码类型的问题 -
它不会重新显示以前的答案),因此留空一个空白字段可以保留已经存储的任何内容,而不是清除它。
### 在 systemd-creds 中存储机密
默认情况下,`settings.yaml` 像源代码路径一样存储凭证(InfluxDB token/user/password,Hue 网桥用户,
MyEnergi API 密钥,Octopus API 密钥)以明文。在打包安装(需要 `systemd >= 250`)上,您可以改为将它们移到
[systemd-creds](https://systemd.io/CREDENTIALS/) 中 - 使用 TPM 绑定或主机导出的密钥加密存储,
解密后仅在受限的内存位置中可用于服务:
```bash
sudo send-to-influx-set-credential influx-token
sudo send-to-influx-set-credential --list
```
运行 `send-to-influx-set-credential --list` 以查看完整的凭证名称列表。每个 `set` 调用都会提示输入值(或从 stdin 读取,
例如 `echo -n "$TOKEN" | sudo send-to-influx-set-credential influx-token`)并用一个注释替换 `settings.yaml` 中的明文值,
即现在在其他地方管理该凭证 - 该文件对于其余内容保持可读,但该字段将永远不会再次从中读取。使用
`send-to-influx-set-credential <name> --remove` 将凭证从 systemd-creds 中删除 - 请注意,这会将 `settings.yaml` 字段重置为其占位符,
而不是恢复机密(加密值被销毁,不会解密回文件中),因此如果您仍然需要,请手动重新输入该值。
这是完全可选的,并且每个字段都是可选的 - 您可以自由混合 systemd-creds 和明文值,并且无论如何,源代码路径不受影响,
因为 systemd-creds 仅在打包的 systemd 服务下适用。
### 远程 MCP 服务器
send-to-influx 可以可选地在同一个进程中运行一个远程 [MCP](https://modelcontextprotocol.io/) 服务器,
以便 MCP 客户端 - Claude Desktop 或 Claude Mobile,或另一个 - 可以通过自定义连接器询问有关您设备的自然语言问题。
除非 **同时** 设置了 `user` 和 `password` 在 `mcp:` 设置块中,否则它被禁用 - 凭证存在是主要的启用机制。
设置 `mcp.disabled: true` 以强制关闭它,而不管用户/密码状态如何 - 如果将密码迁移到 systemd-creds(仅清空 YAML 字段不会禁用它,
因为存储的凭证仍将在加载时被替换)或简单地在排查其他问题时,可以使用此功能。
```yaml
mcp:
bind_address: "127.0.0.1:8420" # 仅限环回/私有地址 - 拒绝任何接口(0.0.0.0/::)和公共 IP 地址
public_url: "https://mcp.example.org" # 您的反向代理服务器提供外部 HTTPS 地址
user: "your-login-name"
password: "your-login-password"
```
要点:
- **您提供 TLS 侧。** 服务器本身使用纯 HTTP 在私有/环回地址上进行通信;
在它前面放置您自己的 TLS 终止反向代理(nginx,Caddy,...),并将 `public_url` 设置为代理服务器提供的地址。
绑定公共接口会被直接拒绝:服务器使用纯 HTTP - 包括 OAuth 登录和令牌 - 因此它必须位于您的
TLS 终止代理后面,而不能直接面向互联网。
- **身份验证是 OAuth 2.1**(Claude 的连接器 UI 使用此功能,以及远程 MCP 标准):
在您的 MCP 客户端(例如 Claude)中添加连接器,网址为 `https://mcp.example.org/mcp`,
它会注册自己并将您带到一个登录页面,该页面由 `mcp.user`/`mcp.password` 控制。
客户端的 OAuth **客户端 ID 留空** - 服务器使用动态客户端注册,填写一个会导致 `/authorize` 拒绝它的客户端 ID。
登录失败会被限制并记录。在打包安装中,可以使用 systemd-creds 存储密码:
`sudo send-to-influx-set-credential mcp-password`.
- **连接在重启后存活。** OAuth 客户端注册和刷新令牌会持久化(哈希)到 `mcp-oauth-state.json` 中,
与设置文件位于同一位置(或使用 `mcp.state_file` 覆盖),
因此软件包升级和重启不会使客户端重新进行身份验证。
- **默认情况下为只读。** 设备控制工具按收集器启用,并不注册,除非在收集器的设置块中启用 -
当未启用任何工具时,写入工具不会在服务器上存在。
**示例 nginx 配置.** 给服务器分配一个单独的子域,并在根目录下提供服务 - 其 OAuth 流使用多个根级路由
(`/authorize`,`/token`,`/.well-known/oauth-*`,`/login`),因此共享站点的子路径不起作用:
```nginx
server {
listen 443 ssl http2; # 'listen ... http2' 适用于旧版和新版 nginx;
listen [::]:443 ssl http2; # 新版 nginx(1.25.1+)更喜欢单独的 'http2 on;'
server_name mcp.example.org; # 必须与 mcp.public_url 中的主机匹配
ssl_certificate /etc/letsencrypt/live/mcp.example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mcp.example.org/privkey.pem;
location / {
# 字面意义上的 127.0.0.1,而不是 'localhost' - 'localhost' 可以解析为 ::1,而服务器监听 IPv4,
# 这会给出 502。proxy_pass 没有尾随斜杠。
proxy_pass http://127.0.0.1:8420;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
# 流式 HTTP / SSE:不要缓冲,保持上游连接活动,
# 并允许长时期的流。
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
```
人们容易犯的两个错误:
- **`public_url 必须是裸域名**(`https://host[:port]`,无路径)。服务器拒绝启动时在其包含路径,
因为 OAuth 元数据是从它构建的 - 因此使用子域(`https://mcp.example.org`),而不是路径前缀(`https://example.org/mcp`)。
- **在连接器中留空 OAuth 客户端 ID**(参见上面的 OAuth 点)- 服务器动态注册客户端,
而手动设置的客户端 ID 会使 `/authorize` 拒绝它。
每个可控制的收集器在其被启用时都会添加自己的工具 - 写操作因设备类型而异,无法共享一个工具。
要允许控制 Hue 灯和插座,请设置 `hue.mcp_read_write: true`。这会添加:
- **`hue_list_devices`** - 可控制的灯/插座,每个都有其 ID、名称和支持的控件(开/关、亮度、色温、颜色)。
- **`hue_set_light`** - 一个真正的物理操作:打开/关闭灯/插座,设置亮度(0-100%),白色温度(开尔文)或颜色(#rrggbb十六进制或类似“暖白色”)。它是功能感知的 -
请求一个纯白色灯泡的颜色被拒绝而不是被忽略,并且设置亮度/温度/颜色会打开灯,除非您关闭它。
要允许触发按需速度测试,请设置 `speedtest.mcp_read_write: true`。这会添加:
- **`speedtest_run`** - 现在在运行服务器的 host 上运行速度测试,并返回结果(也像计划运行一样记录)。
仅限同时每个主机运行一个。
连接后,客户端具有这些读取工具:
- **`list_sources`** - 可以查询的收集器,每个都有一个简短的描述。
- **`list_fields`** - 可用的字段及其单位(对于像 Nuki lock state 这样的编码字段)每个值代表什么。
- **`get_current_state`** - 当前源状态(“门是否锁定?”,“哪些灯处于开启状态?”)。大多数源实时从设备读取,
而 Speedtest 和 Octopus 代替报告其最新的记录读数。
- **`query_history`** - 字段在时间范围内的历史记录,可以是单个点或聚合(平均值/最大值/最小值/求和/计数/...)到桶(“这个月 vs 上个月的用电量?”,
“灯什么时候关掉?”)。
- **`get_documentation`** - 一次调用的参考资料,说明每个源报告的内容及其编码值的含义。
结果在整个过程中都是领域感知的:值携带其单位,编码字段会返回带有原始数字的解码标签。
相同的 数据也作为 MCP **资源**(文档参考,以及每个源的实时状态和模式资源)提供给使用它们的客户端。
服务器还提供几个**提示** - 客户端可以在客户端选择预制任务:*home status*(现在总结一切),
*usage trends*(历史分析,例如“本月 vs 上个月的电量”),并且当启用设备控制时,*control device*。
历史查询针对 InfluxDB 通过固定的参数化查询构建器 - 从未直接使用原始查询 - 字段名称与测量值的实时字段列表进行检查,
时间范围在应用中标准化,限制结果集的大小。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器