An SMS only AI assistant for feature phones. This repo is the production backend.
A user in Kenya texts a question to a local number over plain SMS, or walks a USSD menu, with no smartphone and no data plan. Seconds later an answer written by a large language model arrives back as an SMS. This repo is the full backend loop from an inbound SMS to a paid, delivered answer.
It handles four things.
- The Africa's Talking SMS and USSD gateway, which receives inbound messages and sends replies.
- An OpenAI conversation engine that turns a question into an answer.
- A credit wallet that tracks what each phone number has left to spend.
- M-Pesa Daraja STK Push payments, so a user can top up their wallet from a feature phone.
The work runs across async Celery workers, so the inbound webhook can return fast while the answer is generated and delivered in the background.
Most tools built on large language models assume a smartphone, an app, and a data plan. A large number of people in Kenya have none of those. They have a basic feature phone and a prepaid SIM, and the one channel that always works is plain SMS. USSD, the star and hash menu you dial, works on the same phones.
m-jibu meets people on that channel. No app to install, no data plan to buy, no account to create in a browser. You text a question and you get an answer. The whole design follows from that one constraint.
This is a real, small pilot deployed in Kenya. It is early, and the numbers below are small pilot numbers, not a growth claim.
As of a 2026-05 snapshot the pilot had handled the following.
- 62 registered phone numbers.
- 167 messages handled.
- 13 completed payments.
That is the honest picture. The point of the pilot is to prove the full loop works on real phones over real SMS, and it does.
- Django 5.2 and Django REST Framework on Python 3.12.
- Celery 5.5 with Redis as the broker and Celery Beat as the scheduler.
- PostgreSQL 15.
- OpenAI for the conversation engine.
- Africa's Talking for the SMS and USSD gateway.
- Safaricom M-Pesa Daraja for STK Push payments.
- Docker Compose for the stack, with Caddy in front for TLS.
No secret ships in this repo. Every secret is read from the environment at run time.
The repo carries only an envs.example template with placeholder values. The real values live only on the server, in environment files that are never committed. When you set up your own copy you fill the placeholders in your own local environment file. Nothing sensitive ever enters git history.
You need Docker and Docker Compose. Everything runs inside containers, so you do not install Python, PostgreSQL, or Redis on your own machine.
First copy the templates into real environment files and fill in the placeholders.
cp envs.example/app.env docker/app/.env
mkdir -p docker/db && cp envs.example/db.env docker/db/.envOpen docker/app/.env and replace each placeholder with a real value. For a first local run you can point the payment and gateway settings at their sandbox modes, and you need a real OpenAI key only when you want to exercise the answer flow.
Build the stack.
docker compose -f local.yml buildRun the stack.
docker compose -f local.yml up -dRun the tests.
docker compose -f local.yml run --rm app pytestm-jibu is a companion project to Bluefield. Bluefield is about verifiable infrastructure, and m-jibu is about reaching people over SMS.
MIT.