Skip to Content
DocumentationIntroduction

Introduction

Luno is an open-source communication agent platform. It turns an ordinary Android phone into a secure, self-hosted communication node that your own backend controls over a versioned, real-time protocol.

The first version focuses on SMS: an Android device runs a long-lived background service that sends and receives text messages and reports device health — SIM state, signal, battery, delivery status — to any server that speaks the Luno protocol.

Why it exists

Commercial SMS gateways charge per message, hold your message history, and put a third party between your application and your carrier. For a great many use cases — internal alerting, OTP delivery in markets where local routes are expensive, field notifications, two-way support lines — the cheapest and most private route is a SIM you already own, in a phone you already control.

What has been missing is the software to make that phone behave like infrastructure rather than a handset. That is what Luno is:

  • Self-hosted. There is no Luno cloud. Your backend is the only server involved, and it is the only place message content ever lands.
  • Backend-agnostic. The node prescribes no server technology and hardcodes no endpoints. Firebase, Supabase, Express, Next.js, NestJS, a Go service, a Cloudflare Worker — all work equally, because the node depends only on the wire protocol.
  • Durable by construction. Every command is persisted before the radio is touched and every inbound message before it is reported, so a killed process or a dead network loses nothing.

How it fits together

Backend (any Luno-protocol server) │ WSS (primary) · HTTPS (fallback + enrolment) │ versioned wire protocol Android node ├─ Native Kotlin agent — the entire gateway │ connection · queue · telephony · crypto · retries └─ Flutter UI — pairing, dashboard, logs, settings Android telephony APIs → SIM / radio / carrier

Two boundaries define the whole system, and almost every design decision falls out of them:

  1. Node ↔ backend is the versioned wire protocol. This is the real API and the real extension seam — a future Linux modem node is a different program speaking the same protocol.
  2. Native ↔ Flutter is a Pigeon platform channel. Commands and rendered state cross it. Sockets, queues, telephony and retries never do.

Flutter is UI-only. The gateway is a native Android foreground service. If the Dart process is killed, the gateway keeps running — that is the acceptance test for the boundary, not a nice-to-have.

What v1 is, and is not

IsAn SMS send/receive agent for Android, a published wire protocol, and server SDKs that implement the backend half
Is notA hosted service, an MMS/USSD/voice gateway, a Linux or Windows modem node, or a replacement for a carrier-grade A2P route

MMS, USSD and non-Android nodes are anticipated by the design — the Transport interface and the protocol are both transport-neutral — but they are explicitly out of scope for v1. See the roadmap for what is planned and what is deliberately deferred.

Luno drives a consumer SIM. Carriers apply anti-spam rules to consumer plans, and sending bulk marketing traffic through one is a fast route to a blocked SIM. Luno enforces rate limits and recipient allowlists on the device precisely because this risk is real — read Security before you deploy.

Where to go next