Skip to main content
The cloud relay (the native Rust ados-cloud service) lets you monitor and control a drone from outside its network. It works behind NAT, through firewalls and over cellular, with no port forwarding: every connection is outbound. The relay is opt-in and off by default. On the same LAN, Mission Control reaches the agent directly (see Pairing).
The relay carries flight commands to the drone from anywhere. Read Safety before you fly a drone you reach over the relay, and turn on MAVLink signing.

What crosses the relay

The relay bridges the raw MAVLink stream to the broker so a remote Mission Control decodes it in the browser, exactly as it does over the LAN WebSocket. There is no separate telemetry topic.

Video signaling

  1. Mission Control publishes an SDP offer to ados/{deviceId}/webrtc/offer, tagged with its session id.
  2. ados-cloud POSTs the offer to the local MediaMTX WHEP endpoint.
  3. MediaMTX returns an SDP answer.
  4. ados-cloud publishes the answer to ados/{deviceId}/webrtc/answer/{sessionId}.
  5. The browser and the drone connect peer to peer, and video flows directly between them.
The number of concurrent sessions is capped, and a session is torn down when the browser closes it. MQTT carries only the handshake. A network that blocks peer-to-peer WebRTC (for example a symmetric-NAT cellular carrier) still gets telemetry and commands over MQTT, but no video.

Connection modes

No cloud connectivity. The MAVLink proxy, video and REST API all work locally; only remote access is off.
Use this for air-gapped work, bench testing or LAN-only flying.
All server.* keys:

MQTT transport

ados-cloud uses rumqttc over WSS/TLS (system webpki roots), QoS 0 for the MAVLink plane and QoS 1 for WebRTC signaling, and a bounded publish queue that drops when the broker is down. Each lane holds its own broker session with its own ClientID (ados-{deviceId} for MAVLink, ados-{deviceId}-msp, ados-{deviceId}-webrtc, ados-{deviceId}-plugin-publish, ados-{deviceId}-plugin-update), so the lanes never evict each other. A dropped session reconnects every 3 seconds and resubscribes on every reconnect.

Heartbeat

While paired, the agent POSTs its status to {convex}/agent/status every 5 s (fixed, not configurable), authenticated by its X-ADOS-Key. Mission Control reads the status row to show the drone online and to fill the per-drone view.

Security

  • MQTT uses WebSocket over TLS (wss://, port 443) in cloud mode.
  • Convex HTTP uses HTTPS.
  • WebRTC media is encrypted with DTLS-SRTP.
  • The agent authenticates with the API key it received at pairing.
No inbound ports are required on the drone’s network.

Checking cloud status

From the CLI:
cloud_choice carries mode, backend_url and paired. Plain ados status prints the same as a Cloud relay line. From the REST API:

Next steps

Cloud infrastructure

Backend architecture and the full MQTT topic reference.

Self-hosting

Run the broker, bridge and backend yourself.

MAVLink signing

Protect commands that travel over the relay.

Battery health

Per-pack health computed on the drone.
Last modified on October 11, 2026