meshtastic-platform

May 20, 2026 · View on GitHub

Hermes Agent gateway plugin: Meshtastic LoRa radio as a first-class messaging platform.

Install

The plugin is auto-discovered by the Hermes plugin loader because it lives under ~/.hermes/plugins/. No further install steps.

Python deps (already installed system-wide on this host):

pip install meshtastic pypubsub

Configure

All env vars are optional; defaults assume a USB-attached node at /dev/ttyUSB0. Put these in ~/.hermes/.env:

MESHTASTIC_PORT=/dev/ttyUSB0           # serial device (omit to use TCP)
# MESHTASTIC_HOST=192.168.1.42         # OR a networked node (overrides serial)
MESHTASTIC_CHANNEL_INDEX=0             # default broadcast channel
MESHTASTIC_HOME_CHANNEL=!55c66f70      # cron / notification target (!hex or #N)
MESHTASTIC_ALLOWED_NODES=!55c66f70     # comma-separated allowlist (case-insensitive)
# MESHTASTIC_ALLOW_ALL=true            # dev only — accept any node

Then restart the gateway:

hermes gateway restart

Identity model

Nodes are identified by Meshtastic hex IDs like !31fde7c3. These are the user_id passed to the authorization layer. DMs use chat_id = !hex; broadcasts on channel N use chat_id = #N.

Constraints

  • Text only — send_image / send_document / send_voice / send_video all fail fast with "Meshtastic does not support media".
  • Per-packet payload limit ~228 B on LongFast; we cap at 200 B and split.
  • 3 s sleep between chunks to respect LoRa airtime.
  • No typing indicator (LoRa has none).
  • pii_safe=True — node IDs are public.

Cron delivery

Set MESHTASTIC_HOME_CHANNEL and add a cron job with deliver=meshtastic. The standalone sender opens a fresh SerialInterface, sends the chunked message, and closes — it works even when the gateway process isn't running in the same shell.

Testing outbound from the CLI

hermes send meshtastic '!55c66f70' 'hello from hermes via lora'