Install
openclaw skills install mqtt-client-openclawUniversal MQTT Client for OpenClaw with Node.js/mqtt.js. Enables Connection Management, Subscription Management, Message Handling and OpenClaw Integration for arbitrary MQTT-based automation.
openclaw skills install mqtt-client-openclawProduction-ready MQTT client for OpenClaw automation. Universal - not bound to specific systems.
Universal MQTT Client for OpenClaw with Node.js/mqtt.js. Connect to any MQTT broker to subscribe to topics, publish messages, and react to state changes. The client automatically handles reconnection, supports wildcards for flexible topic patterns, and can trigger alerts when values cross thresholds (e.g., battery below 10% or temperature above 30°C). Use this skill to integrate OpenClaw with smart home systems such as ioBroker, Home Assistant, Zigbee2MQTT, Shelly devices, other OpenClaw instances (to communicate between them), or any other MQTT-based system.
npm install mqtt
const { MqttClient } = require('./scripts/mqtt-client.js');
const client = new MqttClient({
broker: process.env.MQTT_BROKER,
username: process.env.MQTT_USERNAME,
password: process.env.MQTT_PASSWORD
});
client.on('message', (topic, payload) => console.log(`${topic}: ${payload}`));
await client.connect();
await client.subscribe('home/#');
| Variable | Default | Description |
|---|---|---|
MQTT_BROKER | localhost | Broker URL (with or without protocol) |
MQTT_BROKER_PORT | 1883 | Broker port |
MQTT_USERNAME | - | Username (optional) |
MQTT_PASSWORD | - | Password (optional) |
MQTT_CLIENT_ID | auto-generated | Client ID (max 23 chars) |
MQTT_SUBSCRIBE_TOPIC | # | Default topic to subscribe |
MQTT_KEEPALIVE | 60 | Keep-alive interval (seconds) |
MQTT_RECONNECT_PERIOD | 5000 | Reconnect interval (ms) |
When first used, the skill automatically creates config in ~/.openclaw/openclaw.json:
{
"skills": {
"entries": {
"mqtt-client": {
"enabled": true,
"env": {
"MQTT_BROKER": "localhost",
"MQTT_BROKER_PORT": "1883"
}
}
}
}
}
⚠️ Existing values are NOT overwritten.
const client = new MqttClient({
broker: 'mqtt://localhost:1883',
reconnectPeriod: 5000,
connectTimeout: 30000,
maxReconnectAttempts: 10
});
const client = new MqttClient({
broker: 'mqtt://localhost:1883',
keepalive: 60 // seconds
});
const client = new MqttClient({
will: {
topic: 'openclaw/status',
payload: JSON.stringify({ status: 'offline' }),
qos: 1,
retain: true
}
});
await client.disconnect(); // with timeout
await client.disconnect(5000);
// Single topic
await client.subscribe('home/bridge/info');
// Multiple topics
await client.subscribe(['home/bridge/info', 'home/bridge/state']);
| Wildcard | Description | Example |
|---|---|---|
+ | Single level | home/+/temperature |
# | Multi level | home/sensors/# |
| Level | Name | Description |
|---|---|---|
| 0 | At most once | Fire and forget |
| 1 | At least once | Acknowledged delivery |
| 2 | Exactly once | Handshake protocol |
await client.subscribe('topic', { qos: 2 });
await client.subscribe('new/topic');
await client.unsubscribe('old/topic');
await client.unsubscribeAll();
// Simple
await client.publish('home/lights/set', 'ON');
// With options
await client.publish('home/lights/set', 'ON', { qos: 1, retain: true });
// As JSON (auto-stringified)
await client.publish('home/lights/set', { state: 'ON', brightness: 255 });
// Set retained
await client.publish('home/announcement', 'Hello', { retain: true });
// Delete retained (empty payload)
await client.publish('home/announcement', '', { retain: true });
Automatic parsing - payload is already an object for JSON messages:
client.on('message', (topic, payload) => {
if (typeof payload === 'object') {
console.log('JSON:', payload.key);
}
});
React to value changes with triggers:
// Battery low trigger
client.addTrigger('battery-low', {
topic: 'home/+/battery',
path: 'value',
operator: '<',
threshold: 10,
valueType: 'number',
cooldown: 60000,
callback: (event) => console.log('⚠️ Low battery:', event.value)
});
// Temperature high trigger
client.addTrigger('temp-high', {
topic: 'home/sensors/+/temperature',
path: 'value',
operator: '>',
threshold: 30,
valueType: 'number',
callback: (event) => console.log('🔥 Hot:', event.value)
});
| Operator | Description |
|---|---|
> | Greater than |
< | Less than |
>= | Greater or equal |
<= | Less or equal |
== | Equal |
!= | Not equal |
contains | String contains |
startsWith | String starts with |
const health = client.getHealth();
// { connected, reconnecting, lastConnected, messagesReceived, latency }
const state = client.getState();
// { status, broker, subscriptions }
// Last messages for topic
const history = client.getMessageHistory('home/+/temperature');
// Last message
const last = client.getLastMessage('home/sensors/#');
// Clear history
client.clearHistory();
| Option | Type | Default | Description |
|---|---|---|---|
broker | string | env | MQTT Broker URL |
username | string | env | Username |
password | string | env | Password |
clientId | string | auto | Client ID |
reconnectPeriod | number | 5000 | Reconnect interval (ms) |
connectTimeout | number | 30000 | Connection timeout (ms) |
keepalive | number | 60 | Keep-alive (s) |
messageHistorySize | number | 50 | Max history entries |
parseJson | boolean | true | Auto JSON parse |
logLevel | string | info | debug/info/warn/error |
| Method | Description |
|---|---|
connect() | Establish connection |
disconnect([ms]) | Graceful disconnect |
subscribe(topic, opts) | Subscribe to topic(s) |
unsubscribe(topic) | Unsubscribe |
publish(topic, payload, opts) | Publish message |
getMessageHistory([topic]) | Get message history |
getHealth() | Health status |
getState() | Current state |
isConnected() | Connection check |
addTrigger(id, config) | Add threshold trigger |
removeTrigger(id) | Remove trigger |
getTriggers() | List triggers |
| Event | Description |
|---|---|
connect | Successfully connected |
disconnect | Disconnected |
message | Message received (topic, payload, packet) |
error | Error occurred |
offline | Client offline |
reconnecting | Attempting reconnect |
reconnect | Successfully reconnected |
mqtt-client.js - Main librarymqtt-topics.md - Topic naming conventions