npm.io
1.0.5 • Published yesterday

aios-mqtt-channel

Licence
MIT
Version
1.0.5
Deps
4
Size
101 kB
Vulns
0
Weekly
0

aios-mqtt-channel

License: MIT

aios-mqtt-channel 是面向 OpenClaw 的 MQTT 双向通道插件。它把 MQTT Broker 接入 OpenClaw,用于 IoT、家庭自动化、服务告警和其他需要经由 MQTT 收发消息的场景。

说明:

  • npm 包名、插件 id、channel id 统一为 aios-mqtt-channel
  • 当前版本面向 OpenClaw 2026.5.x 通道 SDK
  • 支持新的 channel/setup 接口和 configured-state 元数据

功能

  • 订阅 MQTT inbound topic,把消息送入 OpenClaw
  • 将 Agent 回复发布到 MQTT outbound topic
  • 支持多账号配置,一个账号对应一个 MQTT 客户端
  • 支持断线重连和自动重新订阅
  • 支持 mqtt://mqtts://
  • 支持 QoS 0 / 1 / 2
  • 支持用环境变量覆盖敏感配置

安装

openclaw plugins install aios-mqtt-channel

查看 OpenClaw 当前实际加载的是哪一份插件:

openclaw plugins info aios-mqtt-channel

如果当前加载的是托管在 ~/.openclaw/extensions/aios-mqtt-channel 下的版本,可以更新:

openclaw plugins update aios-mqtt-channel

如果 plugins info 显示的是旧的手工备份目录,而不是正式安装记录:

  1. ~/.openclaw/extensions/ 下旧的 aios-mqtt-channel 目录移走
  2. 重新执行 openclaw plugins install aios-mqtt-channel
  3. 重启 OpenClaw 网关

不要把 aios-mqtt-channel.bak-* 这类备份目录留在 ~/.openclaw/extensions/ 下,否则 OpenClaw 可能会识别到重复插件。

配置

把下面内容加入 ~/.openclaw/openclaw.json

{
  "channels": {
    "aios-mqtt-channel": {
      "enabled": true,
      "accounts": {
        "default": {
          "brokerUrl": "mqtts://your-server:8883",
          "username": "your-name",
          "password": "your-password",
          "clientId": "openclaw-agent",
          "topics": {
            "inbound": "openclaw/inbound",
            "outbound": "openclaw/outbound"
          },
          "qos": 1,
          "disableBlockStreaming": false,
          "tls": {
            "enabled": true,
            "rejectUnauthorized": true
          }
        },
        "lowcode": {
          "brokerUrl": "mqtt://localhost:1884",
          "topics": {
            "inbound": "openclaw/inbound-lowcode",
            "outbound": "openclaw/outbound-lowcode"
          },
          "qos": 1,
          "disableBlockStreaming": false
        }
      }
    }
  },
  "plugins": {
    "allow": [
      "aios-mqtt-channel"
    ],
    "entries": {
      "aios-mqtt-channel": {
        "enabled": true
      }
    }
  }
}

字段说明:

  • channels["aios-mqtt-channel"] 是通道配置根节点
  • accounts 下每个键都是一个 OpenClaw 账号 id;插件会为每个账号启动一个 MQTT 客户端
  • topics.inbound 是发给 OpenClaw 的 topic
  • topics.outbound 是 OpenClaw 回写回复的 topic
  • disableBlockStreaming 控制该账号默认是否禁用 block streaming
  • 旧版单账号写法仍然兼容,并会被视为 default 账号;新部署建议统一使用 accounts

也可以通过交互式命令配置:

openclaw configure channels

配置完成后重启 OpenClaw 网关。若使用 systemd:

systemctl restart openclaw

环境变量

以下环境变量会覆盖 openclaw.json 中对应字段,适合放置敏感信息:

MQTT_BROKER_URL
MQTT_USERNAME
MQTT_PASSWORD
MQTT_CLIENT_ID
MQTT_CA_PATH

说明:

  • 至少提供 MQTT_BROKER_URL 才能仅靠环境变量形成一个可用的默认账号
  • MQTT_PASSWORD 推荐只通过环境变量注入
  • MQTT_CA_PATH 当前只作为配置字段传递,代码尚未自动读取证书文件内容

用法

会话路由与 sessionId
  • 路由依据是 MQTT 账号 id 加上入站消息里的 senderId
  • 插件会以 peer.id = senderId 交给 OpenClaw 做 route 解析,再由 OpenClaw 根据 bindings 和 session 配置确定最终 agentIdsessionKey
  • sessionId 只是请求级字段;如果入站 JSON 带了它,插件会在出站 JSON 中原样回显,便于客户端做请求和回复关联
  • sessionId 不会创建新会话,也不会直接修改记忆上下文
  • 如果入站 JSON 没有 sessionId,出站默认会写回 "-1"

如果你希望不同对话彼此隔离,应当使用不同的 senderId

发送入站消息

发布到某个账号 inbound topic 的消息会被 OpenClaw 处理。支持纯文本和 JSON,推荐 JSON。

# 纯文本
mosquitto_pub -t "openclaw/inbound" -m "Alert: Service down on playground"

# JSON
mosquitto_pub -t "openclaw/inbound-lowcode" -m "{\"senderId\":\"pg-cli\",\"text\":\"hello\",\"sessionId\":\"abc-123\"}"

入站 JSON 示例:

{"senderId":"conn-test2","text":"What is your agent name?","sessionId":"conn-test2"}

按消息覆盖 disableBlockStreaming

{"senderId":"conn-test2","text":"Give me the final answer only","sessionId":"conn-test2","disableBlockStreaming":true}

说明:

  • disableBlockStreaming 只影响当前这一条 MQTT 请求
  • 如果消息里没有该字段,则继承账号级配置
  • true 表示尽量走非 block streaming 路径,优先得到 final 回复
  • false 表示允许本次请求使用 block streaming,即使账号默认关闭它
接收出站回复

Agent 回复会发布到对应账号的 outbound topic,格式为 JSON:

{"senderId":"openclaw","text":"...","kind":"final","sessionId":"conn-test2","ts":1700000000000}

订阅示例:

mosquitto_sub -t "openclaw/outbound-lowcode" -v

说明:

  • kind 会原样透传 OpenClaw 的出站类型,常见值是 blockfinal
  • 如果开启了 block streaming,可能先收到若干个 block,最后再收到 final
  • 如果入站消息设置了 disableBlockStreaming: true,该请求会尽量避免 block
  • 只有当入站 JSON 包含 sessionId 时,插件才会在出站中回显该值;否则默认是 "-1"
  • 数字类型的 sessionId 会被规范化为字符串
  • outbound.sendText() 同样使用上述 JSON 包装格式

排障

先确认 OpenClaw 实际加载的是哪份插件:

openclaw plugins info aios-mqtt-channel

如果是 systemd 部署,常用日志筛选:

journalctl -u openclaw -f | grep -E "MQTT channel ready|MQTT route resolved|MQTT inbound message|sent reply"

多账号正常启动时,应看到每个账号各自完成订阅,例如:

[default] MQTT channel ready, subscribed to openclaw/inbound
[lowcode] MQTT channel ready, subscribed to openclaw/inbound-lowcode

每条入站消息还会输出路由日志,例如:

MQTT route resolved topic=openclaw/inbound-lowcode inboundAccount=lowcode routeAccount=lowcode agent=lowcode session=...

如果这里显示 agent=main,说明 MQTT topic 命中了该插件,但 OpenClaw 仍按当前 bindings 把请求路由到了主 agent。

安全说明

任何能够向 inbound topic 发布消息的客户端,都等价于拥有对应 OpenClaw Agent 的访问能力。这个插件只应暴露在可信环境中,例如:

  • 受控 Broker
  • 开启认证
  • 私有网络
  • 上游再增加额外鉴权或校验层

如果需要接入不可信客户端,建议在消息发布到 openclaw/inbound 之前先做独立验证。

开发

# 在 monorepo 根目录下
cd plugins/aios-mqtt-channel

npm install
npm test
npm run typecheck
npm run build

架构

MQTT Broker (Mosquitto/EMQX)
     |
     +--> inbound topic ---> OpenClaw Gateway ---> Agent
     |
     +<-- outbound topic <-- OpenClaw Gateway <--- Agent

许可证

MIT

相关项目