mcpField
T
tolpo

tolpo

本地服务
github.com/signerless其他92 周前更新

关于 tolpo

tolpo 是面向家庭网络中 AI Agent 和代码的 TP-Link Tapo 设备本地控制接口,直接通过局域网通信。它按级别限制敏感或难以撤销的操作。

主要功能

  1. 01基于局域网的设备发现与控制
  2. 02设备状态和传感器读数
  3. 03灯、插座、摄像头等设备支持
  4. 04可配置的操作安全级别
  5. 05MCP 服务和 OpenAPI HTTP API

适用场景

  1. 01查看门窗、温度和告警
  2. 02调节灯光或切换插座
  3. 03获取已配置摄像头的快照
  4. 04为脚本开放智能家居设备控制

MCP 相关

MCP 服务将 Tapo 设备状态和获准的控制操作作为工具提供给 AI 客户端。同一核心还提供带 OpenAPI 描述的 HTTP API。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"signerless-tolpo": {
"command": "npx",
"args": [
"-y",
"tolpo"
],
"env": {
"TAPO_EMAIL": "<TAPO_EMAIL>",
"TAPO_PASSWORD": "<TAPO_PASSWORD>"
}
}
}
}
启动命令npx -y tolpo
需要配置的环境变量
TAPO_EMAILEmail of the Tapo account the devices belong to
TAPO_PASSWORD密钥Password of that Tapo account

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmtolpo0.2.1

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

tolpo

以本地优先的方式,为 AI Agent 控制 TP-Link Tapo 智能家居设备。

CI License: MIT Python 3.11+

tolpo 将网络中的 Tapo 设备整合为一个统一接口,供 AI Agent 或你自己的代码读取和控制。它通过开源库 python-kasa 在局域网内直接与每台设备通信,因此任何请求都不会离开你的家,也不会经过厂商云端。它唯一需要的凭据是设备已关联的 Tapo 账户。

它基于同一核心提供两种接口:

  • MCP 服务,助手(例如 Claude)可将其用作工具(turn off the office lights、“有门开着吗?”)。
  • HTTP API,在 /docs 提供 OpenAPI 描述,供脚本和仪表板使用。

目标是让 Agent 能够完成 Tapo 应用在你的网络上能做的一切:控制灯、插座、集线器及其传感器、摄像头、门铃、扫地机器人、日程安排、固件、房间、配对,甚至控制设备向互联网发送的内容。这赋予了 Agent 很多权限,因此每项操作都有一个级别,只有最低级别默认启用。请参阅Agent 能做什么和安全模型。

功能

  • 支持灯、插座、H100/H200 集线器及其传感器、摄像头和门铃,每种设备都提供实时状态和可更改项目列表。
  • Tapo 应用的各个部分会划分为不同区域,例如灯、插座、摄像头、门铃和网络。tolpo 会记住之前运行时发现的设备类型;你从未拥有过的类型所对应的区域会保持关闭。
  • 每项操作都有 0 到 4 级。读取和可逆控制(电源、亮度、颜色)默认启用。设置、安全变更以及难以撤销的操作(例如配对或恢复出厂设置)默认关闭,需提升级别后才能使用;最后两类操作还需要每次调用时提供确认短语。Wi-Fi 名称、设置代码、密码和令牌绝不会返回。
  • 在配置中指定摄像头名称后,Agent 即可通过 Tapo 应用使用的同一视频通道获取单张图片、一段短图片序列或已保存的视频片段。无需额外的摄像头账户。
  • 设备发现结合广播和针对每个地址的直接扫描,会在运行之间记住设备,并重试唤醒较慢的设备。无法连接设备时,响应会说明具体设备和原因。
  • 状态会短暂缓存,设备名称也能立即解析,因此 Agent 不会被响应缓慢的集线器阻塞。
  • 完整测试套件使用模拟设备运行,无需任何硬件。

支持的设备

tolpo 适用于所有 python-kasa 能够连接的设备,因此列表范围比我们实际拥有的硬件更广。表格将两类设备区分开来:我们使用真实设备测试过的,以及 python-kasa 文档中标记为支持、但我们尚未尝试过的设备。

设备在此处测试过python-kasa 文档中支持,但未在此处尝试Agent 可获取的信息
灯泡彩色灯泡L430CL430P、L530B、L530E、L530EA、L535E状态、亮度、白光色温和颜色
智能插座智能插座P115P110、P110M状态,以及功率、电压和电流读数
集线器集线器H200H100,以及与集线器配对的 S200B 和 S200D 按钮与其配对的传感器会作为独立设备显示,也可以读取其事件日志。使用更高权限级别时:警报器、传感器设置、配对
门窗传感器门窗传感器T110开启或关闭状态、电池电量低标记
温湿度传感器温湿度传感器T310T315(带显示屏的型号)温度、湿度、电池电量低标记
运动传感器运动传感器T100按照 python-kasa 文档提供的运动状态。未使用真实硬件验证
漏水传感器漏水传感器T300漏水警报和电池电量
摄像头摄像头C225、C610、C465C100、C101、C110、C200、C210、C220、C325WB、C460、C520WS、C720、TC40、TC65、TC70状态、电池电量(适用时)、最近一次警报和检测开关。使用更高权限级别时:检测调整、图像和音频设置、水平和垂直转动、存储卡。可启用的摄像头还能获取图片和视频片段
可视门铃门铃D230D100C、D130状态和电池电量、通过集线器获取图片和实时视频。使用更高权限级别时:铃声、快捷回复、防盗、唤醒
扫地机器人python-kasa 清洁模块支持的型号状态、启动和停止、房间和区域、吸力和水量、计划任务。根据应用的协议构建,未使用真实硬件验证
门锁python-kasa 不支持暂不可用。DL100、DL105、DL110、DL130 和 DLW10 使用的协议不受 python-kasa 识别。tolpo 可以解析它们的发现记录,但尚未连接任何功能

C610 和 C465 尚未列入 python-kasa 的设备清单,但两者都能正常连接。C465 需要在 compat.py 中进行一处小型证书修复。完整的上游设备列表见 python-kasa 的 SUPPORTED.md。

未列出的型号也可能可用,因为 tolpo 会将设备交给 python-kasa 处理,并显示其报告的内容。运行 tolpo scan 即可确认。无论设备能否正常工作,都请通过设备支持问题告知我们,以便完善此表。

环境要求

  • Python 3.11 或更高版本
  • 同一网络上的一个或多个 TP-Link Tapo 设备,并已在 Tapo 应用中完成设置
  • Tapo 账户邮箱和密码
  • ffmpeg,仅在需要获取摄像头图片时需要
  • 用于安装的 uv(或普通的 pip)

安装

使用 npx

需要 Node 和 uv。不会全局安装任何内容:

npx -y tolpo scan      # find your devices
npx -y tolpo mcp       # run as an MCP server

tolpo 是一个 Python 程序。npm 包中包含 Python 代码,并通过 uv 运行,因此首次运行会下载大约 40 个 Python 包,耗时比之后的运行更长。如果 AI 客户端不再等待,请先运行一次 npx -y tolpo --help,然后重新启动客户端。

使用 Docker

适用于长期运行的设备,例如 Raspberry Pi 或 Linux 家庭服务器。镜像是公开的,因此拉取时无需登录,并且支持 amd64 和 arm64。

将凭据保存在只有你能读取的文件中,并通过 --env-file 传入:

(umask 077; printf '[email protected]\nTAPO_PASSWORD=your-password\n' > ~/.tolpo.env)

docker run --rm -i --network host --env-file ~/.tolpo.env ghcr.io/signerless/tolpo

这会通过 stdio 运行 MCP 服务。对于 HTTP API,请添加令牌,因为它不再绑定到 loopback:

echo "TOLPO_TOKEN=$(openssl rand -hex 24)" >> ~/.tolpo.env

docker run -d --name tolpo --restart unless-stopped --network host --env-file ~/.tolpo.env \
  ghcr.io/signerless/tolpo serve --host 0.0.0.0

--network host 可让容器通过 UDP 广播发现设备,但仅适用于 Linux。macOS 和 Windows 上的 Docker Desktop 会在虚拟机中运行容器,无法以这种方式发现设备,因此请在这些系统上使用 npx 安装方式。

CI 会为两种架构构建镜像,并在镜像内检查 MCP 握手。目前尚未尝试从容器内发现真实设备。镜像不包含 ffmpeg,因此目前无法获取摄像头图片。

从源代码安装
git clone https://github.com/signerless/tolpo && cd tolpo
uv venv --python 3.13 .venv
uv pip install --python .venv/bin/python -e ".[dev]"

配置

凭据可以来自环境变量或配置文件。服务会先读取文件,然后由环境变量覆盖其中的设置。

export TAPO_EMAIL='[email protected]'
export TAPO_PASSWORD='your-password'

也可以使用 ~/.config/tolpo/config.toml(其中包含密码,请对其运行 chmod 600):

[tapo]
email = "[email protected]"
password = "your-password"
# or point at an existing JSON file instead of copying the secret:
# credentials_file = "~/.tapo_config.json"

[server]
host = "127.0.0.1"          # loopback only; a token is required to bind elsewhere
port = 8765
# token = "a-long-random-string"
# cache_ttl_seconds = 10
# areas = ["lights", "plugs", "hub"]   # which parts offer tools; empty means every part for the devices you own

[discovery]
# subnets = ["192.168.1.0/24"]   # default: the /24 of your default-route interface
# hosts   = ["192.168.10.20"]    # devices that ignore broadcast or live on another VLAN
# sweep   = true                 # also probe every address in the subnet (networks up to /22)
interval_seconds = 600

[policy]
# The highest level of action an agent may use, from 0 to 4. See the Security model.
tier = 1
# Single device methods an agent may use above `tier`, for example ["setLedStatus"].
allow_methods = []
# Features an agent may write beyond power, brightness and color.
# Plain ids ("pan_left") or kind-qualified ones ("camera.state").
allow_write = []

[cameras]
# Pictures are off for every camera until you name it here, as it is called in the Tapo app.
snapshots = []                    # for example ["Hallway Cam"]
# Optional. A camera account made in the Tapo app switches pictures to the standard RTSP stream.
# username = "camera-account-name"
# password = "camera-account-password"
# ffmpeg = "/opt/homebrew/bin/ffmpeg"   # only if ffmpeg is not on your PATH
# clip_dir = "/Users/you/tolpo-clips"   # the one folder where camera clips may be saved; no folder, no clips

环境变量会覆盖文件中的设置:TOLPO_CONFIG(配置文件本身)、TOLPO_CREDENTIALS_FILE、TOLPO_TIER、TOLPO_AREAS(以逗号分隔的名称)、TOLPO_SNAPSHOTS、TOLPO_CLIP_DIR、TOLPO_FFMPEG、TOLPO_CAMERA_USERNAME 和 TOLPO_CAMERA_PASSWORD。如果 tier 不是 0 到 4 之间的整数,服务将无法启动。

部分功能使用独立文件,以免任何机密信息进入主配置文件。自动化功能会保存其规则和警报发件箱;本地房间和分组保存在 ~/.local/state/tolpo 中(可通过 TOLPO_STATE_DIR 更改)。网络区域会读取 ~/.config/tolpo/network.toml(可通过 TOLPO_NETWORK_CONFIG 更改),该文件指定每个路由器密码所在的环境变量,但不会保存密码本身。

通过只读扫描验证设置:运行 npx -y tolpo scan,或在源代码检出目录中运行 .venv/bin/tolpo scan。

与 Claude(MCP)搭配使用

将凭据放入 ~/.config/tolpo/config.toml(请参阅 Configuration,并对其运行 chmod 600)。服务会自行读取该文件,因此不会将任何机密信息写入 AI 客户端的设置。然后注册一次服务:

claude mcp add tolpo -- npx -y tolpo mcp

如果使用源代码检出,请指向你自己的副本:

claude mcp add tolpo -- $PWD/.venv/bin/tolpo mcp

如果你不想将凭据保存在文件中,也可以通过 -e TAPO_EMAIL=... -e TAPO_PASSWORD=... 传递,但客户端会以纯文本形式将它们存储在自己的设置中。

下次重启后,你可以提出诸如“将 office-1 调暗至 30%”、“有没有门开着?”或“楼上的温度是多少?”之类的问题。

工具功能
home_overview一览全屋情况:哪些设备已开启、门窗是否打开、水警报、离线设备、低电量电池、温度
list_devices查看设备及其状态;可按 kind 或名称筛选
get_device查看单个设备的所有功能,以及哪些功能可写入
camera_snapshot获取一台已启用摄像头的静态图片
set_power控制灯和插座的开关;接受多个目标和 office* 之类的通配符
set_light设置亮度、白光色温或色相与饱和度
set_feature设置其他功能,但仅限策略允许的情况
rescan查找新设备或已移动的设备

读取工具标记为只读,set_feature 标记为破坏性操作,因此 MCP 客户端可在必要时请求确认。响应内容精简:典型家庭的所有设备信息不到一千个 token。

Agent 可以做什么

Tapo 应用分为多个区域。每个区域是一组 MCP 工具,拥有自己的页面,其中列出该区域的所有工具。tolpo 会记住先前运行时发现的设备类型,并关闭从未拥有过的设备类型对应的区域,因此没有扫地机器人的家庭不会加载扫地机器人工具。首次运行或模型无法识别时,所有区域都会开启。可通过 [server] 下的 areas 或 TOLPO_AREAS 自行选择区域。工具 tolpo_areas 会告知 Agent 当前开启的区域。

区域涵盖内容工具数
灯灯泡和灯带:效果、预设、计划、倒计时、离家模式、通电默认设置19
插座插座和开关:计划、倒计时、能耗历史、电价、自动关闭、保护21
集线器集线器、传感器和散热器阀门:警报器、传感器设置、门、漏水、移动和按钮事件日志29
门铃可视门铃和门铃扬声器:铃声、快捷回复、防盗、唤醒、电池模式17
摄像头检测移动、人、宠物和车辆检测、区域、计划、警报和聚光灯、警报通知设置17
摄像头系统云台转动、图像、音频、电池、隐私模式、UPnP、固件、重启33
摄像头媒体存储卡、录制计划、录制索引、过往事件的缩略图、保存到文件夹的片段11
吸尘器扫地机器人:状态、启动和停止、房间和区域、吸力和水量、计划、磨损计数器27
门锁门锁:从发现记录中读取状态。目前尚不可用1
设备管理名称、时钟、LED、固件,以及 tolpo 自己的房间和分组24
自动化替代 Smart Actions 的本地规则引擎:触发条件、条件、操作和警报发件箱10
配对配对和移除集线器设备、连接 Wi-Fi、重启和恢复出厂设置。大部分操作需要等级 4,重启需要等级 29
家庭平面图3D 视图的平面图:根据设备绘制草图、读取、保存,以及查看位置4
历史记录门或窗开启的频率和持续时间,数据来自 tolpo record 保存的内容1
网络通过路由器、DNS 服务器或防火墙查看每台设备与哪些对象通信,并可选择阻止通信。阻止通信需要等级 4、在 network.toml 中设置 mode = "enforce",且 Linux 主机需负责路由流量10

此外,home_overview、list_devices、get_device、set_power、set_light、set_feature、 camera_snapshot 和 rescan 适用于所有设备。

所有区域合计有 242 个工具。它们的名称、描述和参数列表约占 40,000 个令牌。标准设置只会启用与家中检测到的设备相匹配的区域。一次性加载所有工具的客户端可以使用 areas 仅保留所需工具。

其中大部分内容基于对 Tapo 应用的分析构建,并在模拟设备上进行了测试。每个区域页面都会说明哪些部分在真实设备上试用过,哪些没有。对于请求的确切格式基于推测的情况,页面会标记为 UNVERIFIED;如果设备未报告支持该格式,工具就会拒绝执行。

通过 HTTP 使用

npx -y tolpo serve          # or .venv/bin/tolpo serve from a source checkout
# http://127.0.0.1:8765, interactive docs at /docs
# Read
curl -s localhost:8765/devices                 # everything, with state and capabilities
curl -s localhost:8765/devices/front-door       # one device, every feature
curl -s "localhost:8765/devices?kind=sensor"    # doors, windows, water, temperature

# Write
curl -s localhost:8765/devices/hallway-cam/snapshot -o picture.jpg    # a camera you enabled
curl -s -X POST localhost:8765/devices/desk-lamp/power \
  -H 'content-type: application/json' -d '{"on": true}'
curl -s -X POST localhost:8765/devices/office-1/light \
  -H 'content-type: application/json' -d '{"brightness": 40, "color_temp": 3000}'
curl -s -X POST localhost:8765/batch/light \
  -H 'content-type: application/json' -d '{"targets": ["office*"], "brightness": 60}'

可以通过设备的简短 id(office-1)、其在 Tapo 应用中的名称(不区分大小写)来指定设备;在批量端点中,还可以使用 office* 这样的 glob 模式。如果某个名称匹配多台设备,服务会返回 409 并列出候选设备,而不会猜测。

3D 房屋视图

tolpo serve 还会在 http://127.0.0.1:8765/home 提供房屋的 3D 视图。它会绘制各个房间,将每台 设备放在所属房间,并显示设备状态:灯光会呈现实际颜色,墙上的门或窗在传感器报告打开时会开启,漏水会变红,温度会显示在传感器上方。点击设备即可切换开关、调节亮度或更改颜色。点击摄像头或门铃即可观看实时画面。没有设备的房间不会显示。

户型图由你决定,并保存在你的设备上,路径为 ~/.config/tolpo/home.json(可通过 server.home_layout 或 TOLPO_HOME_LAYOUT 更改)。最简单的创建方式是让你的 Agent“绘制我的户型图”:使用 home_plan_draft、home_plan_get 和 home_plan_set 工具,它会根据你的设备拟定户型图,询问房间信息并保存。你也可以在视图中点击 Edit layout,将设备拖到对应位置,然后保存。格式说明见 docs/areas/home_plan.md:

{"version": 1,
 "rooms": [{"id": "office", "name": "Office", "x": -7, "z": -5, "w": 5, "d": 5},
           {"id": "garden", "name": "Garden", "x": -9, "z": -12, "w": 21, "d": 7, "outside": true}],
 "devices": {"office-1": {"room": "office", "x": -5.75, "z": -3.75},
             "garden-cam": {"room": "garden", "x": 1.5, "z": -5.6, "yaw": 0}}}

实时视频来自 GET /devices/{id}/live,这是摄像头的 JPEG 图片流(每秒约 10 张),摄像头需列在 cameras.snapshots 中。每台摄像头只能开启一个视频流,最多同时使用两台摄像头。视频会在 15 分钟后结束;如果是电池供电的摄像头,则会在 2 分钟后结束,因为实时视频会让它保持唤醒。页面会从一个固定版本的 jsDelivr 路径加载 three.js,且只会与此服务通信。页面每 5 分钟查询一次电池摄像头的状态,而不是每隔几秒查询一次,因此不会唤醒它们。

门窗历史记录

对于连接到 TP-Link 云的传感器,Tapo hub 不会自行保存历史记录:按应用的方式查询时,H200 对门传感器会返回空列表,而应用会改为从云端读取历史记录。因此,tolpo 会自行记录:

tolpo record garage

它每 5 秒读取一次传感器状态(可通过 --every 更改),并将每次开关状态及时间保存到 ~/.local/share/tolpo/history.jsonl(可通过 server.history_file 或 TOLPO_HISTORY_FILE 指定);只有你能读取此文件。不指定名称即可记录所有门窗传感器。它只会在运行期间记录,因此要想获得没有缺漏的历史记录,请将其作为后台服务运行;电脑休眠或传感器无法连接的时段会记录为间隔。之后,recorded_history 工具会告诉 Agent 门每天开启了多少次、每次持续多久,并按天和小时统计;如果有时段没有记录,也会列出,而不是对此进行猜测。

相机照片

Agent 可以向相机请求一张静态照片。除非在配置中通过 Tapo 应用里的名称指定相机,否则所有相机均处于关闭状态:

[cameras]
snapshots = ["Hallway Cam"]

运行 tolpo 的机器上还需要安装 ffmpeg。请在 Agent 使用前自行检查设置。这会将一张照片保存到只有你能读取的文件中:

npx -y tolpo snapshot "Hallway Cam" -o hallway.jpg

若要在自己的屏幕上实时观看相机画面,请使用 npx -y tolpo watch "Hallway Cam"。它会打开 ffplay(ffmpeg 附带的程序),并在你关闭窗口时退出。添加 --seconds 30 可让它更早停止。不会录制任何内容,也不会向 Agent 发送任何内容。

tolpo 使用 ffmpeg 从相机的实时视频流中截取一帧,并以 JPEG 格式返回,宽度最多为 1280 像素。--quality high 会请求主码流,而不是小码流。连接视频流有两种方式:

  • 使用 Tapo 应用的视频通道,连接相机的 8800 端口。它使用 tolpo 已有的 Tapo 账户,因此无需进行其他设置。
  • 使用 RTSP:在 Tapo 应用中创建相机账户,并在 [cameras] 下添加 username 和 password。配置了相机账户后,tolpo 会使用 RTSP。

启用前请注意:

  • 照片会发送给 Agent 使用的大模型。仅启用你愿意让它查看的相机。
  • 相机处于隐私模式时不会提供照片。除非在 allow_write 中允许 camera.state,否则 Agent 无法关闭隐私模式。
  • 每张照片都会记录相机和时间,但不会记录照片本身。
  • 如果相机拒绝登录,tolpo 会让它静置五分钟,因为反复登录失败可能会导致相机被锁定。
  • 照片是实时截取的一帧,不是录像。电池供电的相机可能处于休眠状态,无法响应。
  • 使用 RTSP 时,ffmpeg 会在命令行中接收相机账户信息,因此同一台机器上的其他用户可能会在短时间内看到这些信息。
  • 连接到集线器的门铃没有自己的地址。它的照片和实时视频会像在应用中一样通过集线器传输;电池供电的门铃唤醒时,获取第一张照片大约需要 5 s。目前还无法访问它的录像。

camera_media 区域基于此功能提供更多能力。它可以读取存储卡及其录像索引、返回过往事件的缩略图、从实时视频流中连续截取一小段时间的照片,并将录像保存到你指定的唯一文件夹 clip_dir。缩略图、连续截取的照片和录像遵循与照片相同的规则:只能使用你指定的相机,且相机不能处于隐私模式;保存录像的工具只会返回路径,不会返回视频。读取存储卡状态、录像计划以及录像和事件列表适用于任何相机。格式化存储卡属于 4 级操作。

安全模型

此服务会控制实体设备,因此默认拒绝操作,只有在你提出请求时才会放宽限制。

设备上的每项操作都有一个级别。你可以在 [policy] 下使用 tier 选择 Agent 可使用的最高级别(默认为 1),也可以通过 allow_methods 单独允许高于该级别的设备方法。

级别名称含义示例
0读取查看所有非机密内容状态、设置、能耗、事件日志、存储卡索引
1控制可逆操作,就像你手动操作一样电源、亮度、颜色、摄像头转动、启动和停止吸尘器
2设置更改设备行为计划、检测调节、默认值、重命名、自动化规则
3安全涉及安全或隐私摄像头隐私模式、警笛、报警和布防状态、关闭摄像头补光灯、UPnP、音频输出
4生命周期难以撤销的操作配对和移除设备、恢复出厂设置、安装固件、更改 Wi-Fi、更改防火墙、格式化存储卡

级别 3 和 4 的每次调用还需要确认短语,例如 setLedStatus hallway-cam。拒绝信息会说明需要使用的短语,因此该短语的作用是暂停操作,让 Agent 询问用户,而不是证明用户已同意。短语会指出操作和设备(少数短语会指定一项更改或计划),因此同一个确认不能用于另一台设备或另一项操作。拒绝信息会说明操作内容,但绝不会说明如何放宽权限。

范围允许的操作
读取所有非机密内容。绝不会返回 Wi-Fi 名称、设置代码、密码、令牌、密钥和 MAC 地址
控制级别 1 下控制灯和插座的电源、亮度、色温、颜色和灯光预设
更多tier 所允许的任何级别,或 allow_methods 中指定的单个方法
功能通过 set_feature 写入的其他内容,须在 policy.allow_write 中指定(报警测试、水平/垂直转动、检测开关)
图片仅限 cameras.snapshots 中指定的摄像头。默认关闭。其他摄像头工具(设置、存储卡索引、事件列表)在你允许的级别下适用于所有摄像头
配对仅通过配对工具进行,级别为 4。set_feature 中的集线器 pair 和 unpair 功能仍会被阻止

通过 set_feature 操作摄像头时只允许读取:摄像头上的 state 开关是隐私快门,而不是电源继电器,因此不会被视为电源继电器。请通过 allow_write = ["camera.state"] 明确启用它,或使用级别 3 的隐私工具。在任何级别下,allow_write 中指定的功能都会被允许,且不需要确认短语,因此只应指定你确实愿意开放的功能。

无人请求时自动运行的规则(自动化)也受相同级别限制,并在运行时检查,而不只是在创建时检查。设置自动化规则需要级别 2。Agent 可随时停止所有规则,但重新启动规则需要级别 3 和确认短语。你也可以自行运行 tolpo automation resume;已在运行的服务会在重启时应用此命令。

此服务仅监听 127.0.0.1。如果使用其他地址且未提供 bearer 令牌,服务会拒绝启动;未提供令牌时,它还会拒绝 Host 标头不是本地地址的请求,从而阻止网页发起 DNS 重绑定攻击。

设备名称是由设置设备的人自由输入的文本。服务会对名称进行扁平化和缩短处理,再提供给 Agent;发送给 Agent 的指令也会要求其将名称和读数视为数据,而不是命令。共享的 Tapo 账户意味着账户中的任何人都可以重命名设备,因此请仅与信任的人共享账户。

忙碌网络中的发现机制

家庭中通常有许多设备,其中一些依靠电池供电,响应较慢。发现机制专为此类情况设计:

  • 先进行 UDP 广播,再向子网中的每个地址直接查询(discovery.sweep), 因为有些电池供电的摄像头会忽略广播,却总能响应直接查询。
  • 以前发现过的设备会记录在 ~/.cache/tolpo/hosts.json 中(地址、名称和型号, 不含机密信息),并在启动时直接查询。某台设备在某次扫描中未出现,不会因此被遗忘; 30 天未出现的条目会被删除。
  • 对于没有响应的设备,会在 5、15 和 45 秒后重试,并在每次重新扫描时再次尝试。

启动过程分阶段进行,让服务立即可用:首次扫描在后台运行,每台设备一旦响应便立即连接。只要设备已上线,就可以立即使用你指定了确切名称的设备,无需等待集线器;集线器冷启动可能需要约 10 秒。涉及整个家庭的操作会等待扫描完成,但最长不超过 15 秒;仍在连接中的设备会在后台完成连接。

无法访问设备时,响应会明确说明。home_overview 和 list_devices 会包含 complete: false,以及 not_connected 列表,其中列出每台无法访问设备的名称、型号和原因,避免 Agent 将离线的门传感器误判为门已关闭。

面向 AI Agent

请先调用 tolpo_areas。它会列出 tolpo 中已启用的部分、各部分提供的功能,以及所有者允许的权限级别。如果你是受命配置或使用 tolpo 的 AI Agent,请从 llms.txt 开始。如果你受命修改代码, 请先阅读 AGENTS.md。

开发

.venv/bin/python -m pytest        # runs against simulated devices, no hardware required

项目结构:

src/tolpo/
  registry.py    device discovery, state cache, control operations
  policy.py      what may be read and written (deny-by-default)
  views.py       shared presentation for the HTTP and MCP layers
  api.py         FastAPI HTTP server
  mcp_server.py  MCP server (stdio)
  config.py      config file and environment loading
  compat.py      small fixes for devices python-kasa cannot reach yet
  snapshot.py    one picture from a camera, taken with ffmpeg
  media.py       the video channel of the Tapo app (port 8800)
  tsvideo.py     finds the video track in a camera's stream
  calls.py       the one way an area sends a method to a device, checked against its level
  provision.py   Wi-Fi setup of a new device from this machine (SoftAP), behind a plan
  areas/         one file per area of the Tapo app; adding an area adds a file
  automation/    the local rule engine
  network/       providers for routers, DNS servers and firewalls
  cli.py         serve / mcp / scan / snapshot / watch / automation entry points
tests/           full suite against simulated devices
docs/protocols.md  how Tapo devices talk on the local network
docs/areas/      one page per area, with every tool and what was only tried with simulated devices
assets/          logo, device icons and social preview

请参阅 CONTRIBUTING.md 了解基本准则,参阅 docs/protocols.md 了解协议说明,并参阅 SECURITY.md 报告漏洞。

背景

Tapo 设备所使用的协议并未由供应商公开文档。本项目的一部分工作是独立分析官方 Tapo 应用和真实设备,以便软件能够与所有者已有的硬件互通。分析结果记录在 docs/protocols.md 中:各型号使用的传输方式、发现机制的工作原理、较新的 TPAP 协议的形式,以及我们无法确定的内容。说明均以我们自己的语言撰写,不含供应商代码、密钥或凭据;tolpo 本身也只会使用你自己的 Tapo 账户登录。

兼容性和状态

这是 0.2.1 版本。通过 python-kasa,支持使用 KLAP 和 SSL-AES 传输协议的灯、插座、集线器和传感器;此外,还为带有 ECDSA 证书的摄像头(例如 C465)提供了一个小型补丁(compat.py),以支持 python-kasa 无法独立访问的设备。

首个版本之后新增的部分,是通过分析 Tapo 应用构建的,并在模拟设备上进行了测试。曾在一处有 4 个灯泡、1 个集线器、8 个传感器、1 个门铃、3 个摄像头和 1 个插座的真实家庭环境中尝试读取数据。还在那里尝试了少数可还原的写入操作:灯泡(电源、亮度、颜色、开机默认值、已保存的预设和已禁用的规则)、插座(电源、倒计时、LED、开机默认值和已禁用的规则)、摄像头补光灯、集线器指示灯、麦克风音量、检测开关和自动化规则,之后均恢复了原状。大多数其他写入操作尚未在真实硬件上尝试,各部分页面会注明具体情况。机器人吸尘器、门锁、暖气片阀门和防火墙提供商均未在真实设备上尝试过。

已知限制:摄像头可提供静态图片、短时连续图片和已保存的片段,但无法向 Agent 提供连续视频;连接在集线器后的门铃可提供图片,但无法提供录像;应用中仅限云端的部分(账户、家庭、共享、推送通知、Tapo Care、语音助手)无法访问,自动化部分会在本地取代其中一些功能;MCP 服务通过 stdio 运行,每个客户端对应一个进程,目前尚无共享 HTTP 传输;HTTP API 包含原有路由,以及少数用于摄像头存储卡(/devices/{id}/storage、/recordings/...)和门锁状态的路由,其他部分则仅提供 MCP 工具;此外,尚未测试位于第二个子网中的设备。

许可证

MIT,详见 LICENSE。

本项目与 TP-Link 无关,也未获得其认可。Tapo 是 TP-Link 的商标。所有设备通信均通过开源 python-kasa 库进行。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。