Skip to main content
Glama
Marcusdt-UX

finance-mcp-server

by Marcusdt-UX

finance-mcp-server

Your personal finance tracker as an MCP server. Sync your bank via SimpleFIN — or backfill from a CSV — into a local SQLite database and ask Claude about it: spending, subscriptions, cash flow, merchant history, debt payoff. Everything stays on your machine; the only thing that leaves is the answer to a question you asked.

Finance HUD dashboard (synthetic demo data)

The bundled HUD (npm run hud) rendering a synthetic demo dataset — net worth, per-account balances, category spending, subscription price-hike flags, and a 30-day cash-flow projection with the low point marked.

The analytics engine in src/core/ is pure, dependency-free TypeScript, kept separate from the MCP and storage layers so a future app can share the same core.

Setup

npm install
npm run build

Get your data in

The primary data source. Live account balances and ongoing transaction sync via SimpleFIN Bridge (read-only bank aggregation, ~$15/yr) — no CSV and no specific budgeting app required. Get a one-time setup token from bridge.simplefin.org (My Account), then:

npm run link -- "<paste-setup-token>"

This claims the token into a durable access URL stored locally in data/finance.db (it never leaves your machine) and runs an initial 365-day sync. After that, balances are live — finance_sync (or just ask Claude to sync) pulls new transactions. You can also link from within Claude via the finance_link_bank tool, but the CLI keeps the token out of the chat transcript. The database lives at data/finance.db (override with the FINANCE_DB_PATH env var).

Optional: Rocket Money CSV backfill

Purely optional — SimpleFIN alone runs the whole tracker. If you're coming from Rocket Money, you can backfill history from before your bank's sync window. Export from Rocket Money (Settings → Export Data → CSV), then:

npm run import -- "C:/path/to/rocket-money-export.csv"

Re-running with an updated export is safe — rows dedupe by a stable hash, so only genuinely new transactions are added.

Local HUD (dashboard)

A glanceable dashboard that reads finance.db fresh on every load — net worth + account balances, this month's spending by category, subscriptions with price-hike flags, and a 30-day cash-flow sparkline with the low point marked. Fully offline (no CDN, no external calls); localhost only.

npm run hud       # → http://localhost:4321  (Ctrl+C to stop)

Leave it running and bookmark it; it self-refreshes every 2 minutes and re-reads the DB, so once your bank is linked the balances stay current. Override the port with HUD_PORT.

Use it with Claude

Claude Desktop, one-click (.mcpb) — the easiest path. Grab finance-mcp.mcpb from the latest release (or build it yourself, below), then drag it onto Settings → Extensions in Claude Desktop. It'll ask for a Database file path — leave the default for a fresh store, or point it at an existing finance.db to reuse that data. The bundle is self-contained (bundled Node deps incl. the native SQLite binary) and, being compiled, is win32-x64 only for now; on other platforms use the manual config below after npm install && npm run build.

Build the .mcpb yourself:

npm install && npm run build
npm i -g @anthropic-ai/mcpb   # the official packer
npm prune --omit=dev          # ship prod deps only (do this in a copy, or re-`npm install` after)
mcpb pack . finance-mcp.mcpb

manifest.json at the repo root defines the bundle. It ships no data — the SQLite file (and the SimpleFIN credential inside it) always lives at the external path you configure, never in the bundle.

Claude Desktop, manual — add to claude_desktop_config.json:

{
  "mcpServers": {
    "finance": {
      "command": "node",
      "args": ["/absolute/path/to/finance-mcp-server/dist/index.js"],
      "env": { "FINANCE_DB_PATH": "/absolute/path/to/finance-mcp-server/data/finance.db" }
    }
  }
}

Claude Codeclaude mcp add finance -- node /absolute/path/to/finance-mcp-server/dist/index.js

Then ask things like:

  • "What did I spend on gas last quarter?"

  • "List my subscriptions and flag any price hikes."

  • "How much have I paid Amazon over the last year?"

  • "Forecast my cash flow for the next 30 days starting from $1,200."

  • "Given these balances and APRs, avalanche vs snowball — which saves more?"

Tools

Tool

What it does

finance_import_csv

Import a Rocket Money CSV (idempotent)

finance_data_overview

Count, date span, per-category totals

finance_search_transactions

Filter by date/category/merchant/amount/flow

finance_spending_by_category

Inflow/outflow by category over a range

finance_list_subscriptions

Recurring charges + price-hike flags

finance_cash_flow_forecast

N-day projection with low-point warning

finance_merchant_history

Every charge from a merchant + summary

finance_debt_payoff_plan

Avalanche/snowball simulation

finance_link_bank

Connect a bank via a SimpleFIN setup token

finance_balances

Live per-account balances + net worth

finance_sync

Pull new transactions + refresh balances

finance_disconnect_bank

Forget the SimpleFIN connection

finance_add_category_rule

Map a merchant substring → category (recategorizes matches)

finance_list_category_rules

List rules + re-apply them across the store

finance_remove_category_rule

Delete a rule

Fixing miscategorized transactions

CSV history carries Rocket Money's own categories, but transactions synced live from SimpleFIN only have raw bank descriptors, so many land in other. Fix them with rules — just tell Claude, e.g. "categorize anything from Menards as shopping." Each rule matches a case-insensitive substring against the merchant name / descriptor, recategorizes all matches immediately (past and future), and sticks for every later import/sync.

Privacy

data/ and all *.csv files are gitignored. Real transaction history is never committed and never sent anywhere except when you ask Claude a question that requires reading it. The screenshot above is generated from synthetic data.

License

MIT