MESH-API Skill
You can interact with a Meshtastic LoRa mesh network through a running MESH-API instance. MESH-API exposes a REST API (default port 5000) that lets you list online nodes, read recent messages, send texts to specific nodes or broadcast to channels, and check device connectivity.
Configuration
- •
MESH_API_URL— Base URL of the MESH-API instance (e.g.http://192.168.1.50:5000). Required. - •
MESH_API_KEY— Optional bearer token for future authentication support. If set, include it asAuthorization: Bearer <token>on every request. If empty or unset, omit the header entirely — MESH-API has no auth by default.
Available Endpoints
GET /nodes
List all mesh nodes the MESH-API instance can see.
Request:
curl -s "$MESH_API_URL/nodes"
Response: JSON array of node objects.
[
{"id": "!a1b2c3d4", "shortName": "TBot", "longName": "TBot Base Station"},
{"id": "!e5f6a7b8", "shortName": "Hike", "longName": "Hiker Node"}
]
- •
idis the Meshtastic hex node ID (always starts with!followed by 8 hex characters). - •
shortNameis a 4-character display name. - •
longNameis the full node name.
GET /messages
Retrieve recent messages from the mesh.
Request:
curl -s "$MESH_API_URL/messages"
Response: JSON array of message objects. Each message contains sender info, text, timestamp, and channel.
POST /send
Send a message to a specific node (direct) or broadcast to a channel.
Direct message to a node:
curl -s -X POST "$MESH_API_URL/send" \
-H "Content-Type: application/json" \
-d '{"message": "Hello from OpenClaw", "node_id": "!a1b2c3d4", "direct": true}'
Broadcast to a channel:
curl -s -X POST "$MESH_API_URL/send" \
-H "Content-Type: application/json" \
-d '{"message": "Hello mesh!", "channel_index": 0}'
Body parameters:
- •
message(string, required) — The text to send. - •
node_id(string, required for direct) — Target node hex ID (e.g.!a1b2c3d4). - •
direct(boolean) — Settruefor a direct message tonode_id. - •
channel_index(integer) — Channel index for broadcast (default0= LongFast).
Response:
{"status": "sent", "to": "!a1b2c3d4", "direct": true, "message": "Hello from OpenClaw"}
POST /ui_send
Broadcast a message to a channel (form-encoded, primarily used by the web UI).
Request:
curl -s -X POST "$MESH_API_URL/ui_send" \ -d "message=Hello+mesh!&channel_index=0"
Parameters (form-encoded):
- •
message(string, required) — The text to send. - •
channel_index(integer) — Channel index (default0). - •
destination_node(string, optional) — If provided, sends a direct message instead of broadcast.
For programmatic use, prefer POST /send with JSON. Use /ui_send only when mimicking the web UI.
GET /connection_status
Check whether MESH-API is connected to its Meshtastic radio device.
Request:
curl -s "$MESH_API_URL/connection_status"
Response:
{"status": "connected", "error": null}
- •
statuswill be"connected"or"disconnected". - •
errorcontains an error description string if disconnected, otherwisenull.
GET /commands_info
List all available slash commands registered on the mesh (including extension commands).
Request:
curl -s "$MESH_API_URL/commands_info"
Response: JSON array of command objects.
[
{"command": "/ping", "description": "Check if the bot is online"},
{"command": "/ai-9z", "description": "Ask the AI a question"},
{"command": "/nodes", "description": "List online mesh nodes"}
]
Natural Language Examples
When the user says something like the phrases below, map their intent to the corresponding API call:
| User says | Action |
|---|---|
| "Who is online on the mesh?" | GET /nodes — list all visible nodes and summarize who is online. |
| "What nodes are on the mesh network?" | GET /nodes |
| "Send 'hello' to TBot" | GET /nodes first to resolve the name "TBot" to a node ID, then POST /send with {"message": "hello", "node_id": "<resolved_id>", "direct": true}. |
| "Send a message to !a1b2c3d4" | POST /send with {"message": "<user's message>", "node_id": "!a1b2c3d4", "direct": true}. |
| "What's been said on the mesh recently?" | GET /messages — retrieve and summarize the recent messages. |
| "Show me mesh messages" | GET /messages |
| "Is the mesh connected?" | GET /connection_status — report whether the radio link is up. |
| "Check mesh connection" | GET /connection_status |
| "Broadcast 'weather alert' to the mesh" | POST /send with {"message": "weather alert", "channel_index": 0}. |
| "Broadcast on channel 2: meeting at noon" | POST /send with {"message": "meeting at noon", "channel_index": 2}. |
| "What commands does the mesh bot support?" | GET /commands_info — list and describe available slash commands. |
When resolving a node by name (e.g. "send to TBot"), always call GET /nodes first to find the matching id. Never guess a node ID.
IMPORTANT CONSTRAINTS
- •
Character limit. Meshtastic mesh messages have a strict practical limit. Keep any message you send via
POST /sendunder 200 characters unless the user explicitly requests a longer message. MESH-API will chunk longer messages automatically, but each chunk is a separate radio transmission — warn the user it will arrive as multiple packets and may take time. - •
No unsolicited long messages. Never send AI-generated text directly to the mesh without user confirmation if the text exceeds one chunk (200 characters). Always ask the user first: "This response is X characters and will be sent as N packets — proceed?"
- •
Bot-loop prevention. Messages prefixed with
m@i-are AI-generated mesh messages. If you see this prefix on an inbound mesh message (viaGET /messages), do not relay it back to the mesh. Doing so creates an infinite loop between AI agents on the network. - •
Node ID format. Meshtastic node IDs are hex strings matching the pattern
!followed by exactly 8 hexadecimal characters (e.g.!a1b2c3d4). Always validate a node ID matches this format before using it inPOST /send. If the user provides a name instead, resolve it viaGET /nodes. - •
Connection check. Before sending messages, it is good practice to call
GET /connection_statusto verify the mesh radio is connected. If status is"disconnected", inform the user and do not attempt to send. - •
No auth by default. MESH-API does not require authentication in its default configuration. The
MESH_API_KEYenv var is optional future-proofing. Only include theAuthorizationheader ifMESH_API_KEYis set and non-empty. - •
Rate awareness. Meshtastic is a low-bandwidth LoRa network. Do not send rapid bursts of messages. If you need to send multiple messages, space them out and inform the user about the delay.