finance-mcp-server
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.

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 buildGet your data in
Live bank sync (SimpleFIN) — recommended
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.mcpbmanifest.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 Code — claude 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 |
| Import a Rocket Money CSV (idempotent) |
| Count, date span, per-category totals |
| Filter by date/category/merchant/amount/flow |
| Inflow/outflow by category over a range |
| Recurring charges + price-hike flags |
| N-day projection with low-point warning |
| Every charge from a merchant + summary |
| Avalanche/snowball simulation |
| Connect a bank via a SimpleFIN setup token |
| Live per-account balances + net worth |
| Pull new transactions + refresh balances |
| Forget the SimpleFIN connection |
| Map a merchant substring → category (recategorizes matches) |
| List rules + re-apply them across the store |
| 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