miot-mcp
米家 MCP Server
中文文档 | English
一个基于 mijiaAPI 3.x 的产品化米家 MCP 服务。它不再要求客户端先理解 did、siid/piid/aiid 这些协议细节,而是优先面向“家庭、房间、设备名、场景名”提供更自然的查询和控制能力。
这版解决什么问题
面向 AI 客户端:优先暴露稳定、清晰的产品级工具,而不是底层协议字段
面向真实家庭场景:先看家庭与房间,再定位设备,再执行控制
面向 MCP 标准:工具返回结构化结果,服务状态和登录状态可直接被客户端消费
面向扩展:标准能力 schema、profile 驱动控制、资源模型可以继续演进
当前能力
服务与登录
get_service_statusprepare_loginreconnect_serviceclear_saved_loginrefresh_devicesget_tool_catalogping
家庭与设备
get_home_overviewlist_homeslist_devicesget_deviceget_device_statusget_device_capabilities
设备控制
control_by_intentcontrol_deviceturn_on_deviceturn_off_deviceset_brightnessset_color_temperatureset_target_temperatureset_hvac_modeset_fan_speedset_cover_position
场景与耗材
list_scenesexecute_sceneget_consumable_items
MCP 资源
mijia://servicemijia://homesmijia://devicesmijia://scenesmijia://capabilitiesmijia://tooling
安装
建议使用 Python 3.10+。
poetry install如果你不用 Poetry:
pip install -r requirements.txt启动
poetry run python mcp_server/mcp_server.py测试握手:
poetry run python mcp_server/mcp_test.py登录方式
mijiaAPI 3.x 已移除账号密码登录,只支持二维码登录。
首次需要登录时,服务会:
生成浏览器页:
~/.miot-mcp/qr.html同时生成二维码图片:
~/.miot-mcp/qr.png默认优先用系统浏览器打开
qr.html只有浏览器打不开时,才回退到图片查看器或终端二维码
认证信息会保存到:
~/.miot-mcp/auth_data.json推荐登录主路径
调用
prepare_login调用
get_service_status读取
service.qr.page_path或service.qr.image_path完成扫码后调用
reconnect_service或直接refresh_devices
登录相关状态
get_service_status 和 mijia://service 都会返回结构化登录状态,重点字段包括:
service.connectedservice.has_saved_loginservice.qr.open_modeservice.qr.page_pathservice.qr.image_pathservice.qr.login_urlassistant_summarynext_steps.should_scan_qr
环境变量
export MIJIA_ENABLE_QR="true"
export MIJIA_QR_OPEN_MODE="browser"
export MIJIA_LOG_LEVEL="INFO"说明:
MIJIA_ENABLE_QR:是否启用二维码登录,默认trueMIJIA_QR_OPEN_MODE:高级配置,支持browser/viewer/none,默认browserMIJIA_LOG_LEVEL:日志级别,支持DEBUG/INFO/WARNING/ERROR
MCP 客户端配置示例
推荐直接使用虚拟环境里的 Python,而不是 poetry run。
{
"mcpServers": {
"mijia": {
"command": "/path/to/venv/bin/python",
"args": [
"/path/to/miot-mcp/mcp_server/mcp_server.py"
],
"env": {
"MIJIA_ENABLE_QR": "true",
"MIJIA_QR_OPEN_MODE": "browser",
"MIJIA_LOG_LEVEL": "INFO"
}
}
}
}推荐调用路径
对于大多数 AI 客户端,建议优先这样使用:
prepare_loginget_service_statusrefresh_devicesget_home_overviewget_device_statuscontrol_by_intentlist_scenesexecute_scene
如果客户端需要更稳定、更显式的路由,再补充:
list_homeslist_devicesget_deviceget_device_capabilitiescontrol_device
常用工具说明
prepare_login
主动准备二维码登录。默认优先复用已有二维码页;如果需要重新走一轮扫码,可以传 force_reauth=true。
get_service_status
返回服务连接状态、认证文件路径、日志路径、二维码页路径、下一步建议。
get_home_overview
按家庭和房间输出设备总览,适合客户端先理解家庭结构。
get_device_status
查看单个设备当前状态、可用操作和推荐下一步。
get_device_capabilities
返回标准能力 schema 和 profile 驱动控制项,适合需要稳定路由的客户端。
control_by_intent
自然语言式控制入口。适合大多数日常使用场景,例如“把卧室台灯亮度调到 30%”。
control_device
统一结构化控制入口。适合客户端已经知道目标操作和参数时使用。
speaker_say
让小爱音箱语音播报任意文本("喊话")。适合长任务完成提醒、闹钟式播报、指定某台音箱念文字。
{
"name": "speaker_say",
"arguments": {
"text": "任务完成啦,图片已生成",
"speaker_name": "城市之光音响"
}
}为什么用 play-text 而不是 execute-text-directive:
小爱音箱有两个相关动作:
execute-text-directive— 把文本当问题/指令发给小爱解析 → 会触发它的 AI 回答(如"被你问住了"),不是纯播报play-text— 纯播放文本,参数_in=[text]单参,不触发 AI 对话 ←speaker_say用这个
坑:通用
run_action路径把参数塞进value字段会导致云 API 报-704220025 Action参数个数不匹配,必须用_inkwargs 姿势(device.run_action('play-text', _in=[text])→method['in']=[text])。
命令行方式(无需 MCP 客户端,直接脚本调用):
python speaker_say.py "任务完成啦" --speaker "城市之光音响"
python speaker_say.py "任务完成啦" --speaker "客厅音箱" --quiet # 静默(只执行不播报)参数:
text:要念的文本(自然语言)--speaker:音箱名称(模糊匹配,不传选第一台在线音箱)--quiet:静默执行(不语音播报)
使用示例
查看服务状态
{
"name": "get_service_status",
"arguments": {}
}主动准备登录
{
"name": "prepare_login",
"arguments": {
"reopen_qr": true
}
}刷新设备与房间映射
{
"name": "refresh_devices",
"arguments": {}
}查看家庭总览
{
"name": "get_home_overview",
"arguments": {}
}查看单个设备状态
{
"name": "get_device_status",
"arguments": {
"device_name": "吸顶灯",
"room": "客厅"
}
}查看能力 schema
{
"name": "get_device_capabilities",
"arguments": {
"device_name": "台灯",
"room": "卧室"
}
}自然语言控制
{
"name": "control_by_intent",
"arguments": {
"query": "把卧室台灯亮度调到30%"
}
}结构化控制
{
"name": "control_device",
"arguments": {
"operation": "set_color_temperature",
"device_name": "台灯",
"room": "卧室",
"value": 4000
}
}执行场景
{
"name": "execute_scene",
"arguments": {
"scene_name": "回家模式"
}
}当前边界
这版 MCP 重点覆盖的是最常见的家庭控制路径:
家庭与房间浏览
设备定位
通用能力控制
标准化能力 schema 暴露
场景执行
耗材查询
已重点覆盖的典型能力包括:
开关
亮度
色温
目标温度
模式
风速
开合位置
更底层、更强定制的能力仍然可以继续往 control_device 扩展,但不再作为默认使用方式对外暴露。
代码结构
当前服务内部主要有三层:
adapter/负责与mijiaAPI交互、登录、设备发现和二维码登录体验mcp_server/core/负责结果封装、能力计算、意图路由、标准化mcp_server/device_definitions/与mcp_server/device_resources/负责标准能力定义、意图定义和产品化资源模型
当前能力和路由不依赖插件自动发现,而是显式导入定义表。这样更清晰,也更适合 AI 客户端稳定调用。
DSH(DeepSeek Harness)集成插件
本仓库除 MCP 服务外,还附带一个 DeepSeek Harness 的 Cordis 插件(dsh-plugin/dsh-task-notify),让 DSH agent 能主动用小爱音箱喊话 + 飞书通知(长任务完成提醒):
工具 | 作用 |
| 长任务完成通知:飞书私聊必发 + 按勿扰状态决定是否用小爱音箱喊话 |
| 让指定小爱音箱念任意文本(纯播放,不触发小爱 AI 对话) |
| 切勿扰开关 / 切当前音箱 / 改飞书目标(跨会话持久化) |
| 查当前状态 |
安装 DSH 插件
# 1. 复制到 DSH profiles 的 node_modules
cp -r dsh-plugin/dsh-task-notify C:\Users\<you>\.dsh\profiles\node_modules\@oadank\dsh-task-notify
# 2. 注册到 ~/.dsh/profiles/web/cordis.patch.yml 的 insert 列表
- id: dsh-task-notify
name: '@oadank/dsh-task-notify'
# 3. 重启 dsh-web 生效插件调用 speaker_say.py(本仓库)完成小爱播报,默认音箱可用 set_notify_state(currentSpeaker, "音箱名") 切换,状态存 ~/.dsh/profiles/notify-state.json 跨会话持久化。
详细说明见 dsh-plugin/README.md。