Off-grid radio for sovereign AI. LoRa mesh comms via Meshtastic — no internet required.

Send and receive messages via Meshtastic LoRa mesh network. Use for off-grid messaging, mesh network status, reading recent mesh messages, or sending texts via LoRa radio.

MIT-0 · Free to use, modify, and redistribute. No attribution required.
3 · 1.5k · 0 current installs · 0 all-time installs
MIT-0
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Suspicious
medium confidence
Purpose & Capability
Name/description match the included files: bridge, CLI, MCP server, monitor and digest scripts. All binaries, files, and network endpoints (mqtt.meshtastic.org, optional map broker) are consistent with a Meshtastic LoRa bridge and local agent integration.
!
Instruction Scope
SKILL.md instructs the agent to read local artifacts (/tmp/mesh_messages.txt, /tmp/mesh_*), run systemctl commands, and set up cron or spawned agent sessions that 'Check /tmp/mesh_messages.txt' and 'deliver: true' to channels such as Telegram. Those instructions grant the agent broad discretion to collect, filter, translate, and forward local radio traffic to external channels — this is within the advertised feature set (alerts/digests) but the examples are vague and can lead to automated exfiltration of messages if misconfigured. Also instructs creating a systemd service and socket server on localhost (expected) but these increase runtime privileges and persistence on the host.
Install Mechanism
There is no external install spec; the repository contains Python scripts and README/SETUP instructions (pip install meshtastic paho-mqtt). No downloads from unknown URLs or archive extraction; install is manual/standard Python package usage. This is low risk from an installer perspective, but the code will be executed locally when run.
Credentials
The skill declares no required env vars, which aligns with the metadata. However CONFIG.md contains hard-coded MQTT credentials (mqtt.meshtastic.org, user 'meshdev', pass 'large4cats') and default broker/topic entries — these appear to be convenience/test defaults and not strictly necessary, but you should treat them as configuration values to review. The MCP server supports overrides via env vars (MESH_SOCKET_HOST, etc.), which is reasonable. There are no unrelated credentials requested, but the skill will read local config and /tmp files as part of normal operation.
Persistence & Privilege
always:false (good). The skill's instructions explicitly encourage installing a systemd service and scheduling cron/agent sessions to run periodic monitoring and digesting. That persistence is consistent with a bridge/monitoring tool, but combined with autonomous agent invocation and 'deliver: true' examples it can cause repeated autonomous reads of local logs and posting to external channels. The skill does not modify other skills or request system-wide tokens, but it does create long-running local services and files under /tmp and may run as a systemd-managed process (requires user to set proper User in service).
What to consider before installing
This package appears to implement the Meshtastic bridge you expect, but review a few items before installing: - CONFIG.md contains default MQTT credentials and broker settings — verify and replace them with your own values or set map publishing off if you don't want to relay to public brokers. Treat those as configuration, not secrets provided by the skill. - The skill logs inbound mesh traffic to /tmp/mesh_messages.txt and provides mechanisms (cron, spawned agent sessions, MCP tools) to read, filter, translate, and post those messages to external channels (Telegram, Discord, etc.). If you enable automated delivery, the agent may forward radio traffic off your machine. Make sure you control destination channels and understand potential privacy/legal concerns for relaying third-party radio messages. - The SKILL.md examples for monitoring are intentionally permissive ("Alert me of interesting ones with translations") — consider tightening the rules: explicit keyword lists, stricter filters, and disable automatic 'deliver: true' until you test manually. - The package suggests installing a systemd service that will run a long-lived bridge process. Ensure the service runs as a non-privileged user and check file permissions on /tmp logs and state files so other local users cannot read them if that matters. - The MCP server exposes tools that can operate the device and read logs; only run the MCP server if you trust the local environment and any clients that will connect to it. Audit which MCP clients you register it with (e.g., Claude Desktop) to avoid unintended remote control. If you want to proceed safely: - Audit the CONFIG.md and replace any defaults. - Run the bridge in an isolated environment (dedicated user account, container, or VM) until you are comfortable. - Disable map publishing and external MQTT publish by default. - Test manual commands (mesh.py send/status/messages) before enabling cron/agent automation or MCP exposure. Confidence notes: assessment is based on included SKILL.md and Python scripts; nothing obviously malicious was found, but the skill's automation examples can cause privacy-relevant data to be forwarded if misconfigured, so treat as suspicious until you confirm configuration and intended delivery targets.

Like a lobster shell, security has layers — review code before you run it.

Current versionv0.1.0
Download zip
latestvk970r1n1d4wj7ytz7436zx33bs80ex1e

License

MIT-0
Free to use, modify, and redistribute. No attribution required.

SKILL.md

Meshtastic Skill

Control a Meshtastic node via USB for off-grid LoRa mesh communication.

Prerequisites

  • Meshtastic-compatible hardware (RAK4631, T-Beam, Heltec, LilyGo, etc.)
  • USB connection to host machine
  • Python 3.9+ with meshtastic and paho-mqtt packages
  • See references/SETUP.md for full installation guide

Configuration

Edit CONFIG.md with your node details, MQTT settings, and alert destinations.

Architecture

┌─────────────────────────────────────────────────────────────┐
│                    MQTT Bridge                               │
├─────────────────────────────────────────────────────────────┤
│  RECEIVE: mqtt.meshtastic.org (global JSON traffic)         │
│  PUBLISH: optional map broker (protobuf)                    │
│  SOCKET:  localhost:7331 (commands: send, status, toggle)   │
├─────────────────────────────────────────────────────────────┤
│  Files:                                                      │
│  • /tmp/mesh_messages.txt - received messages log           │
│  • /tmp/mesh_nodes.json   - cached node positions           │
└─────────────────────────────────────────────────────────────┘

┌─────────────┐     USB      ┌─────────────┐
│  LoRa Node  │◄────────────►│ Bridge.py   │
│  (Radio)    │              │  - Serial   │
└─────────────┘              │  - Socket   │
                             │  - MQTT     │
                             └──────┬──────┘
                                    │
           ┌────────────────────────┼────────────────────────┐
           │                        │                        │
           ▼                        ▼                        ▼
    localhost:7331           /tmp/mesh_*            MQTT Broker
    (send commands)          (message logs)         (mesh traffic)

Quick Reference

Send Messages

# Via socket (preferred - works while bridge running)
echo '{"cmd":"send","text":"Hello mesh!"}' | nc -w 2 127.0.0.1 7331

# Direct message to specific node
echo '{"cmd":"send","text":"Hey!","to":"!abcd1234"}' | nc -w 2 127.0.0.1 7331

# Check status
echo '{"cmd":"status"}' | nc -w 2 127.0.0.1 7331

# List RF nodes (seen via radio)
echo '{"cmd":"nodes"}' | nc -w 2 127.0.0.1 7331

Map Visibility (if configured)

# Toggle map publishing on/off
echo '{"cmd":"map"}' | nc -w 2 127.0.0.1 7331

# Explicitly enable/disable
echo '{"cmd":"map","enable":true}' | nc -w 2 127.0.0.1 7331
echo '{"cmd":"map","enable":false}' | nc -w 2 127.0.0.1 7331

# Force immediate position report
echo '{"cmd":"map_now"}' | nc -w 2 127.0.0.1 7331

Read Messages

# Recent messages (last 20)
tail -20 /tmp/mesh_messages.txt

# Filter common noise
tail -50 /tmp/mesh_messages.txt | grep -v -E "(Hello!|hey|mqtt-test)"

Message Log Format

TIMESTAMP|CHANNEL|SENDER|DISTANCE|TEXT
2026-02-02T12:43:59|LongFast|!433bf114|1572km|Moin moin!

Bridge Service

# Status
sudo systemctl status meshtastic-bridge

# Restart
sudo systemctl restart meshtastic-bridge

# View logs
sudo journalctl -u meshtastic-bridge -f

# Stop (needed for direct CLI access)
sudo systemctl stop meshtastic-bridge

Monitoring & Alerts

Option 1: Cron Job (Recommended)

cron.add({
  name: "mesh-monitor",
  schedule: { kind: "every", everyMs: 300000 },  // 5 min
  sessionTarget: "isolated",
  payload: {
    kind: "agentTurn",
    message: "Check /tmp/mesh_messages.txt for new messages. Filter out noise (test messages, 'Hello!', 'hey'). Alert me of interesting ones with translations if non-English.",
    timeoutSeconds: 60,
    deliver: true,
    channel: "telegram"  // or your channel
  }
})

Option 2: Digest Summary

cron.add({
  name: "mesh-digest",
  schedule: { kind: "cron", expr: "0 8,14,20 * * *", tz: "Europe/Madrid" },
  sessionTarget: "isolated",
  payload: {
    kind: "agentTurn",
    message: "Read /tmp/mesh_messages.txt. Create a digest of interesting messages from the last 6 hours. Translate non-English, guess country from distance. Post summary.",
    timeoutSeconds: 120,
    deliver: true,
    channel: "telegram"
  }
})

Option 3: Spawned Monitor Agent

sessions_spawn({
  task: "Monitor /tmp/mesh_messages.txt every 30 seconds. Alert me for interesting messages (not noise). Run for 1 hour.",
  label: "mesh-monitor",
  runTimeoutSeconds: 3600
})

Distance Reference

Approximate distances for country guessing (adjust for your location):

DistanceTypical Regions
<500kmNeighboring countries/regions
500-1000kmMedium range
1000-1500kmLong range
1500-2000kmVery long range (likely MQTT relay)
>2000kmMQTT-bridged traffic

Privacy Notes

  • Map reports can use fuzzy positioning (~2km precision)
  • Position publishing can be toggled off entirely
  • Local RF messages are logged but not shared externally by default
  • Never broadcast precise location in messages

Supported Hardware

DeviceNotes
RAK4631Recommended, reliable USB
T-BeamPopular, has GPS
Heltec V3Budget option
LilyGo T-EchoE-paper display

See references/SETUP.md for hardware-specific setup.

Regional Frequencies

RegionFrequencyTopic Root
Europe868 MHzmsh/EU_868/2/json
Americas915 MHzmsh/US/2/json
Australia/NZ915 MHzmsh/ANZ/2/json

Files

~/.openclaw/skills/meshtastic/
├── SKILL.md           # This file
├── CONFIG.md          # Your configuration
├── scripts/
│   └── mesh.py        # CLI wrapper
└── references/
    └── SETUP.md       # Installation guide

Troubleshooting

"Resource temporarily unavailable"

  • Only one process can use serial port at a time
  • Stop bridge before direct CLI: sudo systemctl stop meshtastic-bridge

No messages appearing

  • Check MQTT subscription topic matches your region
  • Verify firewall allows outbound port 1883
  • Check journalctl -u meshtastic-bridge for errors

Can't send messages

  • Ensure bridge is running (socket server)
  • Check serial port path in config
  • Try: echo '{"cmd":"status"}' | nc -w 2 127.0.0.1 7331

Considering BLE instead of USB?

  • Don't. USB is far more reliable on Linux.
  • BLE on Linux (BlueZ/bleak) has notification bugs, pairing inconsistencies, and random disconnects.
  • See references/SETUP.md for detailed findings.

Further Reading

Files

10 total
Select a file
Select a file to preview.

Comments

Loading comments…