This is a submission for the Hacktoberfest Weekend Challenge: Build for a Friend
Every few days my phone buzzes with a screenshot from my mom. It's always an SMS, and it's always followed by the same question: "What does this mean? Should I do something?"
Sometimes it's harmless: a subscription renewal, an EMI reminder, a recharge confirmation. Sometimes it's a scam: "Your KYC has expired, your account will be blocked today, click this link." To her, they look exactly the same. Bank messages are full of short forms like A/c XX1234, NEFT, Avl Bal, and debited, and scammers copy that style on purpose.
I'm not always free to answer right away. And the worst time for her to be confused is when a scammer is creating urgency.
So I built Offline SMS Buddy: a small app on her laptop where she pastes any confusing SMS and presses one big button. It answers three questions in plain language:
For example:
SMS: Your account will be debited ₹499 on 5 October for your recurring subscription.
Offline SMS Buddy: ₹499 will be automatically taken from your account on 5 October for a subscription. You don't need to do anything if you know about this subscription. If you don't recognise it, call your bank using the number on your card.
And when a message looks like a scam, the app shows a clear red warning: don't click the link, don't share any OTP, and call the bank directly.
The most important part: her SMS never leaves her computer. No cloud, no account, and it even works with the Wi-Fi turned off.
The stack is entirely open source and runs locally:
localhost:11434.
I didn't want to parse a paragraph and guess where "what to do" starts. Ollama lets you pass a JSON schema, so I define the answer shape with Pydantic and the model must fill in exactly those three fields:
class SmsExplanation(BaseModel):
meaning: str
what_to_do: str
be_careful: str
response = client.chat(
model=MODEL,
messages=[{"role": "user", "content": PROMPT.format(sms=sms)}],
format=SmsExplanation.model_json_schema(),
options={"temperature": 0.2},
)
Each field goes straight into its own section on the page. The low temperature (0.2) keeps the model close to what the SMS actually says instead of getting creative.
The prompt tells the model to use short sentences and avoid banking jargon. It also sets some strict rules: don't invent information that isn't in the SMS, and never suggest sharing an OTP. If a message asks her to click a link, update KYC, or threatens to block her account, the model must tell her to verify with the official bank or company first.
Small models are good, but they aren't perfect, and with scams a single miss matters. So the app also runs a plain regex check. If an SMS contains a link, a shortened URL, "KYC" or "blocked", the red warning appears no matter what the model says. If it mentions an OTP, there's always a "never share this code" reminder. The AI explains, and the simple code makes sure the most important warning is never skipped.
For this project, open-source AI isn't just a nice extra. Without it, the idea doesn't work.
1. Her SMS messages are some of the most private data she has.
They contain bank balances, partial account numbers, OTPs, loan EMIs, and delivery addresses. Sending all of that to a cloud API I don't control (with its own logging, retention and terms of service) would create a new privacy risk inside a tool meant to protect her. With an open-weight model running through Ollama, the message goes from the text box to localhost and back. That's the whole journey.
2. It works without internet.
Once the model is downloaded, the app works fully offline. I tested it with the Wi-Fi switched off. That matters for a tool she should be able to trust at any moment, not only when the connection is good.
3. It costs nothing to run.
There are no API keys, no per-request billing, and no subscription that runs out. She can paste a hundred messages a day and it costs ₹0. A closed API would mean I'd have to manage billing for my mom's laptop forever.
4. I can swap or tune the model freely.
The model name is a single constant in llm.py. If a better small open model comes out next month, I run ollama pull and change one line. With a closed API, the provider decides when the model changes, and that can change the app's behaviour without warning.
5. Nobody can take it away.
If an API gets deprecated, a price changes, or an account gets locked, the app keeps working. The model file sits on her disk.