The Problem
I wanted my AI agent (Hermes) to send and receive SMS messages — reminders, notifications, alerts — without paying for Twilio or any third-party SMS API. The answer was sitting in a drawer: an old Android phone with an unlimited texts SIM plan.
The Stack
- Android phone — any old device with a SIM card and SMS capability. I'm using a Xiaomi running a custom ROM, but stock works too.
- SMS Gate app — open-source Android app (sms-gate.app) that exposes a local HTTP API on the phone for sending/receiving SMS and registering webhooks.
- Tailscale — WireGuard-based mesh VPN. Every device gets a stable IP. The phone and server don't need to be on the same network.
- Custom FastAPI gateway — a lightweight Python service running on my home server that sits between the agent and the phone. It handles message queuing with SQLite, retry logic (30-second intervals, up to 10 attempts), webhook forwarding, and a contact book.
How It Works
- The SMS Gate app runs on the phone and exposes a REST API over Tailscale (e.g.
http://100.x.x.x:8080). - The FastAPI gateway on the server proxies all requests to the phone's local API. It exposes
/send,/messages,/events,/contacts,/stats, and/healthendpoints over HTTPS using Tailscale certs. - Webhooks are registered on the phone for
sms:received,sms:sent,sms:delivered, andsms:failed. Incoming texts are forwarded to Telegram so I never miss a message. - My AI agent calls the gateway's
/sendendpoint. The gateway queues the message, forwards it to the phone, and tracks delivery status. If the phone is offline, messages wait in SQLite and get retried automatically.
Why Not Twilio?
Twilio charges per message. For a personal agent that sends reminders and notifications, those costs add up. This setup costs exactly £0/month beyond the SIM plan I already had. The trade-off is maintaining a phone on a charger — which is fine for a homelab.
Why Not the Official Private Server?
The SMS Gate project ships a Go-based private server with MariaDB designed for multi-tenant SaaS. For a single user with one phone, that's overkill. My FastAPI + SQLite replacement is one container instead of five, with all the features I actually need: queue, retry, webhooks, contacts, and phone health monitoring.
Lessons Learned
- Tailscale is the secret sauce. No port forwarding, no dynamic DNS, no firewall rules. Install it on both devices and they can talk to each other from anywhere.
- Turn off RCS on the SIM. RCS messages don't trigger the SMS Gate webhooks — only standard SMS does.
- Battery management. Keep the phone plugged in. The gateway has a
/healthendpoint that checks phone battery and connectivity status. - SQLite is enough. For a single-device gateway processing a few dozen messages a day, SQLite handles queue and event storage without any overhead.
The Result
My agent can now text me (or anyone in my contacts) from a cron job, a webhook, or a conversation. Incoming texts land in my Telegram. Total monthly cost: whatever the SIM plan costs. Total infrastructure: one old phone on a charger and one Docker container.
The code is on GitHub (private repo) and the gateway skill is part of my agent's skill set. Whole thing took an afternoon to build.