You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3.6 KiB
3.6 KiB
F3 Picoclaw XMPP
An XMPP ↔ PicoClaw bridge over MQTT, built as two independent long-running services that talk to each other over localhost HTTP. Each service owns exactly one persistent connection (one XMPP, one MQTT), so there is no connection contention between them.
How it works
XMPP user <─> [xmpp_service.py] ──HTTP /publish──> [mqtt_service.py] <─> MQTT broker
^ XMPP conn :19080 MQTT conn :19081
└───────────────── HTTP /send ◄──────────────────┘
src/xmpp_service.py(port19080) — one XMPP connection (receive and send). ExposesPOST /send{jid, text}to send an outgoing XMPP message (chat, or groupchat when the JID is a known room). Every incoming XMPP message is forwarded viaPOST /publishto the MQTT service.src/mqtt_service.py(port19081) — one MQTT connection subscribed to{prefix}/{agent_id}/+/response. ExposesPOST /publish{jid, text}to publish{"text": ...}to{prefix}/{agent_id}/{jid}/request. Every MQTT response is forwarded viaPOST /sendto the XMPP service.
The {jid} segment is the bare JID of the XMPP sender, so PicoClaw keeps an
independent conversation per sender. PicoClaw's streamed reply chunks arrive as
separate MQTT messages and are each forwarded as their own XMPP message.
If a service cannot reach the other over HTTP, it logs the error and continues.
Requirements
- Python >= 3.10
- uv package manager
- An MQTT broker (e.g. Mosquitto, EMQX)
- A running PicoClaw gateway with the MQTT
channel enabled (
channel_list.mqttwith a matchingagent_idandtopic_prefix)
Setup
# Install dependencies
uv sync
# Configure environment
cp .env.example .env
# Edit .env with your XMPP credentials and MQTT settings
Environment Variables
| Variable | Description |
|---|---|
XMPP_USERNAME |
Full JID for the XMPP bot account |
XMPP_PASSWORD |
XMPP account password |
XMPP_ROOMS |
Comma-separated list of MUC rooms to join |
MQTT_BROKER |
MQTT broker URL, e.g. tcp://host:1883 or ssl://host:8883 |
MQTT_USERNAME |
Optional broker username |
MQTT_PASSWORD |
Optional broker password |
MQTT_TOPIC_PREFIX |
Topic namespace prefix (default /picoclaw) |
MQTT_AGENT_ID |
PicoClaw agent id used in the topic path (default assistant) |
MQTT_CONN_CLIENT_ID |
Broker-level client id for MQTT connections |
MQTT_QOS |
MQTT QoS for publish/subscribe: 0, 1, or 2 (default 0) |
DEBUG |
Logging level: debug, info, warn, error, critical |
The service ports are hardcoded: XMPP service on 127.0.0.1:19080, MQTT
service on 127.0.0.1:19081.
Usage
Run both services (e.g. two terminals, or a process manager like systemd):
# Terminal 1 - XMPP side
uv run python -m src.xmpp_service
# Terminal 2 - MQTT side
uv run python -m src.mqtt_service
Project Structure
src/
├── xmpp_service.py # XMPP connection + HTTP :19080 (incoming -> MQTT, /send)
├── mqtt_service.py # MQTT connection + HTTP :19081 (responses -> XMPP, /publish)
├── xmpp.py # XMPP bot client (slixmpp)
├── picoclaw.py # PicoClaw MQTT client (paho-mqtt)
└── log.py # Logging configuration