Architecture Overview
The Device Gateway sits between your physical devices and the Lua agent runtime. It handles authentication, connection management, command routing, and trigger delivery.Self-Describing Flow
When a device connects, it does not need any server-side configuration. The device tells the gateway what it can do, and the gateway tells the agent.Device connects with command manifest
The device client sends its
commands array during the Socket.IO auth handshake or MQTT online status message. Each command includes a name, description, and optional JSON Schema for input parameters.Gateway registers device
The gateway validates the API key, registers the device in Valkey, and stores the command manifest alongside the connection metadata.
Agent discovers tools
When the agent processes a user message, it queries connected devices and merges their commands into the tool list. Each device command appears as a tool named
device:{deviceName}:{commandName}.Command Delivery Path
When the agent decides to use a device tool, the command flows through the gateway:commandId for idempotency. If the device receives the same command twice (due to retry or redelivery), it returns the cached response.
Trigger Flow
Triggers go in the opposite direction — from device to agent:Triggers are fire-and-forget from the device’s perspective. The device gets an acknowledgment that the gateway received the trigger, but does not wait for the agent to finish processing it.
Transport Comparison
| Feature | Socket.IO | MQTT |
|---|---|---|
| Protocol | WebSocket over HTTPS | MQTT 3.1.1 over TLS |
| Default URL | https://api.heylua.ai | mqtts://mqtt.heylua.ai:8883 |
| Reconnection | Built-in with jitter | Built-in with backoff |
| Message ordering | Guaranteed (single socket) | Guaranteed per topic (QoS 1) |
| Offline queueing | No | Yes (persistent session, clean: false) |
| Last Will (LWT) | Not applicable | Automatic offline status on disconnect |
| Best for | Node.js, desktops, servers | Microcontrollers, battery devices, flaky networks |
| RAM footprint | ~10 MB (Node.js) | ~30 KB (MicroPython on Pico W) |
Security Model
API Key Authentication
Every device connection requires a valid API key. The key is sent during the auth handshake (Socket.IO) or as the MQTT password. Keys are never stored in retained MQTT messages.
Agent Scoping
A device can only interact with the agent it authenticates against. Cross-agent communication is not possible.
TLS Encryption
All transports use TLS. Socket.IO connects over HTTPS. MQTT connects over port 8883 with TLS.
Heartbeat Monitoring
The gateway expects a heartbeat every 30 seconds. Missed heartbeats trigger disconnect detection. MQTT additionally uses Last Will and Testament (LWT) for instant offline notification.
Connection Lifecycle
- Socket.IO
- MQTT
Next Steps
Self-Describing Commands
Deep dive into how devices declare their capabilities
Triggers
Understand device-to-agent event flow
MQTT Transport
Configure MQTT for constrained devices
Agent Tools
How device commands become agent tools

