← all writing
2026-06-18 · 4 min read

Spendly: the expense tracker that never leaves your Mac

How Spendly turns bank SMS alerts into a private spending dashboard that runs entirely on your Mac, with only store names and currency rates ever touching the internet.

A finance tracker that never leaves your Mac. Your bank texts get read on your own machine, and your money data never touches the cloud.

This is the setup guide for Spendly. The build story lives there.

Spendly turns the bank and UPI debit alerts your phone already gets into a private spending dashboard. The texts get forwarded to your Mac, read locally, and shown on a dashboard only you can open. The only things that ever cross the internet are store names, so it can label categories, and a currency rate for foreign spends. Never an amount, never an account, never the raw message.

What you get

  • A private dashboard: spend by category, by payment method, over time, top merchants, and recent transactions
  • Automatic import straight from your bank SMS, no manual entry
  • A cash entry form for spends that never came as a text
  • Foreign charges shown in the original currency next to the rupee amount
  • Installs like an app, on both your Mac and your phone

What never leaves your Mac

This is the whole point, so it is worth being exact:

  • Every amount, account number, card tail, date, and raw message stays in one file on your Mac.
  • OTPs, salary, and refunds are dropped before anything is even saved.
  • The only thing sent out is a deduplicated list of store names, like SWIGGY or ZEPTO, so they can be sorted into categories, plus a plain currency rate lookup like USD to INR for foreign spends.
  • Each store is labeled once and cached, so the normal state is zero network calls.

You can also run it fully offline, where nothing leaves the machine at all.

Before you start

  • A Mac and an iPhone signed into the same Apple ID
  • Python 3, which is already on every Mac, so nothing to install
  • The Spendly project files on your Mac
  • Optional: a Claude or OpenAI API key if you want AI to label categories. Skip it to stay fully offline.

Setup

1. Forward your bank texts to your Mac

Bank debit alerts arrive as SMS, so you relay them to your Mac. On the iPhone, go to Settings, then Messages, then Text Message Forwarding, and toggle on your MacBook. Apple shows a one-time code on the Mac to confirm. Then open Messages on the Mac and check that a recent bank alert is actually there. If it is not, nothing downstream can see it.

2. Let the importer read your Messages

Your Mac keeps all messages in a protected file, so you give your terminal permission to read it. Go to System Settings, then Privacy & Security, then Full Disk Access, click the plus, add the Terminal app, then quit and reopen the terminal. The importer only ever reads a copy of that file. It never changes your actual messages.

3. Run it

From the project folder:

cd finance-tracker
python3 src/pipeline.py

The first time, you can scan fewer messages as a quick test:

python3 src/pipeline.py --limit 200

It is safe to re-run anytime. It reads your debit alerts, drops anything that is not a real spend like OTPs, income, and personal messages, pulls out the amount, store, and date, converts foreign spends to rupees, and saves everything to one local file.

4. Choose how categories get labeled

Copy the example settings file first:

cp .env.example .env

Then pick one option inside that file:

  • LLM_PROVIDER=none for fully offline. A local keyword list labels your stores and nothing leaves the machine.
  • LLM_PROVIDER=anthropic with your ANTHROPIC_API_KEY
  • LLM_PROVIDER=openai with your OPENAI_API_KEY

Even with AI turned on, it only ever sends bare store names, never an amount or account, and it caches each one so it asks only once.

5. Open the dashboard

python3 server.py

Then open http://localhost:8000 on your Mac. It is only reachable from your own machine. You can click Install in the browser to keep it as its own standalone window.

6. Open it on your phone with Tailscale

The dashboard lives on your Mac, so to reach it from your phone without putting anything on the public internet, use Tailscale. It puts both devices on a private, encrypted network.

  1. Install Tailscale on the Mac and the iPhone, and sign both into the same account.
  2. In the Tailscale settings, turn on MagicDNS and HTTPS certificates. This is a one-time step.
  3. With the dashboard running, share it on your private network:
tailscale serve --bg 8000
tailscale serve status

The status command prints the link to use. Open that link on your phone and add it to your Home Screen to install it as an app. One thing to know: your Mac has to be awake for the phone to load it, since the Mac is the server.

7. Optional: keep it syncing on its own

Instead of running it by hand, a small background agent can start the dashboard when you log in and pull in new texts every 15 minutes. New spends then show up on their own.

Privacy, in one line

Your money data lives in one file on your Mac. The internet only ever sees a list of store names and a currency rate. Everything else, the amounts, accounts, OTPs, income, and raw texts, stays local or is dropped before it is ever saved.