ManiFinance

My own finance app. It pulls transactions directly from my two banks via open banking and shows budget, savings, subscriptions and investments. The video was recorded with demo data.

September 2026Next.jsTursoOpen bankingMCP
ManiFinanceDemo data

In short

2banks via open banking
7steps in the job every morning
12tools, shared by the chat and the MCP server
46 → 31database queries on the front page

Why I built it

Ready-made budget apps give you an overview, but you can’t ask your own questions of the numbers or change the logic that decides what a transaction is. I wanted the raw data in my own database, a categorisation I can adjust myself, and a way to ask questions of the numbers.

What it does

Every morning a job syncs the accounts, fetches exchange rates and share prices, and keeps track of when the bank’s consent to data access needs renewing.

The morning job7 steps · fixed order
  1. Exchange rates from the ECB first, so euro transactions get today’s rate right away

  2. Share prices for every holding and everything on the watchlist

  3. Sync of all accounts new transactions from both banks, without duplicates

  4. Consent reminder a notice before the MitID consent to the bank expires

  5. Alerts double charges, unusually large amounts and fees

  6. Month-end close when a pay period ends, it is closed once

  7. Weekly email Sundays only: the week’s numbers in five lines

If one step fails, the others still run. Notices arrive as push notifications, otherwise by email.

There is a budget, savings goals tied to accounts with an expected date, a return curve for investments and a figure for what is available once fixed costs and agreed savings are deducted. Possible double charges and unusually large expenses arrive as a push notification on the phone, and each pay period is closed when it ends.

Categorisation

Categorisation follows fixed rules in a set order:

  1. 1
    Manual correctionalways wins if I have corrected a transaction myself
  2. 2
    My own rulesare used next, if there is no manual correction
  3. 3
    Automatic patternsare the last resort

Transfers between my own accounts are recognised, so they don’t count as expenses twice. Receipts can be added as a photo.

The bank’s raw text is turned into a real namethe raw text can still be seen in the details
  1. The bank writesMCD 03942 LIME*KRSEL 33GO
  2. Card purchase and terminal number are removed: MCD 03942
  3. Lower case, symbols become spaces: lime krsel 33go
  4. Matched among known shops
  5. The app showsLime

Ask your numbers

You can ask about the numbers in a chat in the app and through an MCP server, so an AI assistant answers from the real transactions instead of guessing.

Chat in the appExample

Do I have two transactions from the same place on the same day?

Calling soeg_posteringer · done

Yes, once: two Lime rides on the same day. The bank texts differ, so they are two real rides and not the same transaction twice.

The answer is based on the transactions the tool found.

The chat and the MCP server share the same 12 tools:

  • maanedsoversigtMonthly overview
  • historikMonthly history
  • soeg_posteringerSearch transactions
  • saldiBalances
  • til_raadighedAvailable
  • budgetstatusBudget status
  • abonnementerSubscriptions
  • opsparingsmaalSavings goals
  • personerPeople
  • investeringerInvestments
  • kategorierCategories
  • saet_kategoriSet category

The tech

Next.js and React with an SQLite database at Turso, and Drizzle to keep the database structure and the code in step. The bank connection runs through Enable Banking, an authorised provider of open banking access. The layout builds on Jakob Fisker’s component library “Fisker Finance”.

The path of a transaction4 links
  1. The banktwo banks, my own accounts
  2. Enable Bankingopen banking with MitID consent
  3. TursoSQLite + Drizzle
  4. The appNext.js + React, chat and MCP

Tested against the real numbers

The calculations behind budget and spending existed in two versions, one in the code and one in the database. When they were merged into one, the result was run against the whole database before the change went live. Every number on the analysis and budget pages matched, except five zero-amount transactions that dropped out of a count.

A review of the speed brought the number of database queries down:

Database queries on the front page

46→31

Before
Now

Database queries on the analysis page

61→29

Before
Now

The main lesson: categorising from the banks’ free text needs ongoing checks against real data. Several errors only showed up when the numbers were reviewed systematically.

Shall we talk?

I reply within 1–2 working days. I’m the one who replies, and the one who builds the site.