使用说明
MQTT MCP服务器
A. 模型上下文协议(MCP) 桥接服务器 LLM驱动的工作流程与物联网智能时钟。AI代理可以设置警报、显示消息, 并通过该服务器控制基于ESP32的时钟的亮度。
服务器使用 按方向划分的混合运输:命令(写入)分派到
clock-server的REST API,并且设备遥测(读取)通过MQTT到达。 clock-server
拥有面向MQTT发布、身份验证、速率限制和写路径审计的设备。
建筑学
REST writes (commands)
┌──────────────────────────────►┌──────────────┐
┌─────────────┐ stdio ┌─┴────────────────────┐ │ clock-server │──► MQTT ──► ┌──────────────┐
│ AI Agent │ ◄─────────► │ clock-mcp-server │ │ (REST API) │ │ Smart Clock │
│ (Claude, │ │ (FastMCP + httpx + │ └──────────────┘ │ (ESP32) │
│ Codex) │ │ paho) │◄── MQTT reads (state/events) ────────┤ │
└─────────────┘ └──────────────────────┘ └──────────────┘
- 写入路径(REST): 命令工具调度到
clock-server通过HTTP;一202 Accepted确认命令已被接受(而不是设备已动作)。 - 读取路径(MQTT): 服务器订阅设备状态/事件主题并缓存 读取端工具的最新观察结果。
六边形架构:
| 图层 | 位置 | 责任 |
|---|---|---|
| 域名 | src/clock_mcp/domain/ |
验证规则、类型异常(零基础设施依赖项) |
| 配置 | src/clock_mcp/config/ |
来自env/.env的Pydantic验证设置 |
| 认证 | src/clock_mcp/auth.py |
承载令牌验证+设备范围授权 |
| 适配器 | src/clock_mcp/adapters/ |
rest_adapter.py (httpx写入路径), mqtt_subscription_adapter.py (paho读取路径) |
| 服务项目 | src/clock_mcp/services/ |
命令调度(REST),读取端状态缓存 |
| 工具 | src/clock_mcp/tools/ |
MCP工具注册(set_alarm、display_message、set_brightness、读取端查询) |
快速开始
先决条件
- Python 3.12+
- 紫外线 (Python包管理器)
- MQTT代理(例如Mosquitto)——请参阅
docker-compose.yml在......下面
设置
git clone https://github.com/PaulKnauer/mqtt-mcp-server.git
cd mqtt-mcp-server
# Create config from template
cp .env.example .env
# Edit .env with your broker URL and credentials
# Run
uv run python -m clock_mcp
码头工人
docker build -t mqtt-mcp-server .
docker run --rm \
-e MQTT_MCP_BROKER_URL=mqtt://host:1883 \
-e MQTT_MCP_REST_BASE_URL=http://host:8080 \
mqtt-mcp-server
Docker Compose(本地MQTT代理)
version: "3.8"
services:
mosquitto:
image: eclipse-mosquitto:2
ports: ["1883:1883"]
mqtt-mcp:
build: .
depends_on: [mosquitto]
environment:
MQTT_MCP_BROKER_URL: mqtt://mosquitto:1883
此组合文件仅支持MQTT代理,因此它执行 读取路径 (设备状态/事件)。命令分派(写路径)还需要一个可访问的
clock-serverREST端点通过MQTT_MCP_REST_BASE_URL没有它,命令工具就会失效 关闭,直到可以访问时钟服务器。
配置
MQTT读取路径(设备状态/事件遥测):
| 变量 | 默认值 | 描述 |
|---|---|---|
MQTT_MCP_BROKER_URL |
mqtt://localhost:1883 |
MQTT代理URL(mqtt:// 或 mqtts://) |
MQTT_MCP_BROKER_USERNAME |
-- | MQTT代理用户名 |
MQTT_MCP_BROKER_PASSWORD |
-- | MQTT代理密码 |
MQTT_MCP_TOPIC_PREFIX |
clocks/commands |
MQTT命名空间前缀;读取端订阅筛选器从中派生(多段值必须以结尾 /commands) |
MQTT_MCP_AUTH_MODE |
none |
身份验证模式(none 或 static) |
MQTT_MCP_AUTH_TOKEN |
-- | 传统承载令牌(通配符范围 *) |
MQTT_MCP_AUTH_CREDENTIALS |
-- | 多凭证格式: id|token|scope1,scope2;id2|token2|* |
MQTT_MCP_LOG_LEVEL |
INFO |
日志级别(DEBUG, INFO, WARNING, ERROR) |
时钟服务器REST写入路径(命令调度):
| 变量 | 默认值 | 描述 |
|---|---|---|
MQTT_MCP_REST_BASE_URL |
http://localhost:8080 |
时钟服务器REST基本URL(http:// 或 https://) |
MQTT_MCP_REST_AUTH_TOKEN |
-- | 时钟服务器REST请求的承载令牌 |
MQTT_MCP_REST_FORWARD_PROTO_HTTPS |
true |
发送 X-Forwarded-Proto: https 关于REST请求 |
MQTT_MCP_REST_TIMEOUT_SECONDS |
5.0 |
REST请求超时(秒) |
工具
set_alarm
在智能时钟设备上设置闹钟。
参数:
device_id(str,必填):目标设备(例如“clock-1”)alarm_time(str,必填):RFC3339 UTC时间(例如,“2030-01-01T07:00:00Z”)label(str,可选):报警标签(例如“唤醒”)token(str,可选):承载令牌(启用身份验证时需要)
display_message
在智能时钟设备上显示消息。
参数:
device_id(str,必填):目标设备message(str,必填):消息文本duration_seconds(int,必填):显示持续时间(1-3600)token(str,可选):承载令牌
set_brightness
设置屏幕亮度。
参数:
device_id(str,必填):目标设备level(int,必填):亮度0-100token(str,可选):承载令牌
ping
活体检查。退货 {"status": "ok"}.
server_info
返回服务器元数据,包括读取路径MQTT连接状态和
clock_server_ready (写路径时钟服务器就绪)。
命令契约(REST写入路径)
命令工具发送到 clock-server的REST API。域安全验证运行
在每次请求之前;无效输入在没有网络调用的情况下返回安全错误形状。
clock-server (internal/api/handlers.go)是本合同的真实来源。
| 工具 | 方法 | 路径 | 正文字段 |
|---|---|---|---|
set_alarm |
POST |
/commands/alarms |
deviceId, alarmTime, label |
display_message |
POST |
/commands/messages |
deviceId, message, durationSeconds |
set_brightness |
PUT |
/commands/brightness |
deviceId, level |
请求体是带有camelCase字段的JSON,例如:
// POST /commands/alarms
{"deviceId": "clock-1", "alarmTime": "2030-01-01T07:00:00Z", "label": "wake up"}
// POST /commands/messages
{"deviceId": "clock-1", "message": "Meeting in 5", "durationSeconds": 30}
// PUT /commands/brightness
{"deviceId": "clock-1", "level": 75}
所需标题:
Authorization: Bearer <token>X-Forwarded-Proto: https(通过切换MQTT_MCP_REST_FORWARD_PROTO_HTTPS)Content-Type: application/json
成功是HTTP 202 Accepted --它证实了 clock-server 接受了命令,不是
设备应用了它。设备确认通过MQTT读取单独公开
下面的路径。非-2xx和传输错误映射到类型 DispatchError;令牌永远不会
记录。
MQTT读取合约(读取路径)
设备事件主题(只读)
| 主题 | 有效载荷 | 保留 |
|---|---|---|
clocks/events/{id}/heartbeat |
{"uptimeSeconds": N, "wifiRssi": N, ...} |
没有 |
clocks/events/{id}/alarm_triggered |
{"time": N, "label": "..."} |
没有 |
clocks/events/{id}/alarm_acknowledged |
{"action": "dismiss", ...} |
没有 |
clocks/events/{id}/command_result |
{"type": "set_alarm", "result": "applied"} |
没有 |
clocks/state/{id}/display |
{"mode": "clock", "brightness": 50} |
是的 |
clocks/state/{id}/alarm |
{"armed": true} |
是的 |
clocks/state/{id}/presence |
"online" / "offline" (LWT) |
是 |
发展
# Install dev dependencies
uv sync --group dev
# Run all quality gates
make ci
# Individual gates
make lint # ruff check + format
make type-check # mypy strict
make test # pytest
make coverage # pytest with coverage (≥70%)
make audit # pip-audit (CVE scan)
make build-check # uv build
添加新工具
- 将域模型添加到
src/clock_mcp/domain/models.py - 添加验证
src/clock_mcp/domain/safety.py - 添加一个方法
src/clock_mcp/services/clock_service.py - 将处理程序添加到
src/clock_mcp/tools/commands.py - 注册于
src/clock_mcp/tools/__init__.py::register_all() - 增添
KNOWN_TOOL_NAMES在src/clock_mcp/config/models.py - 在中添加测试
tests/unit/tools/
认证
两种身份验证模式:
- 无:无限制访问(本地/家庭使用)
- 静态:带有设备范围凭据的承载令牌
设备作用域支持精确匹配(clock-1),前缀匹配(clock-*),以及通配符(*).
令牌比较使用恒定时间 hmac.compare_digest 以防止定时攻击。
项目状态
版本:0.1.0——积极发展。尚未发布生产版本。
许可证
麻省理工学院