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.
picoclaw-xmp/README.md

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 (port 19080) — one XMPP connection (receive and send). Exposes POST /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 via POST /publish to the MQTT service.
  • src/mqtt_service.py (port 19081) — one MQTT connection subscribed to {prefix}/{agent_id}/+/response. Exposes POST /publish {jid, text} to publish {"text": ...} to {prefix}/{agent_id}/{jid}/request. Every MQTT response is forwarded via POST /send to 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.mqtt with a matching agent_id and topic_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

Tech Stack