finance-mcp-server
It is a local-first personal finance MCP server that syncs bank data via SimpleFIN (or imports Rocket Money CSV) into SQLite and exposes analytics tools for Claude to answer spending questions.
Sync live bank accounts and balances via SimpleFIN (link, sync, disconnect, real-time balances/net worth)
Import Rocket Money CSV exports idempotently, deduping by stable hash
Search transactions by date, category, merchant, amount, or flow
View spending by category, data overview, and merchant history with spend summaries
Detect subscriptions and recurring charges, flagging price hikes
Forecast cash flow over 7–90 days with a low-point warning
Simulate debt payoff plans using avalanche, snowball, or compare strategies
Add/list/remove merchant→category rules to recategorize past and future transactions
Run a local HUD dashboard showing net worth, balances, category spending, subscriptions, and cash-flow projection
Keep data local: only question answers leave your machine
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@finance-mcp-server What did I spend on dining out last month?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 buildRelated MCP server: goetta-finance
Get 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
Available Tools
15 toolsfinance_add_category_ruleAdd Category RuleAIdempotent
Create a rule that assigns a category to any transaction whose merchant name or bank descriptor contains a given substring — and immediately recategorize all matching transactions (past and future imports/syncs honor it too). Use this to clean up transactions stuck in 'other'. Match is case-insensitive. Args: match (substring, e.g. 'menards'), category. Returns how many transactions were recategorized. Example: {match:'robinhood', category:'transfers'}.
Inputs: match (required), category (required).
finance_balancesReal-Time BalancesAIdempotent
Live per-account balances and net worth via SimpleFIN (fetched fresh on each call, then cached). Credit-card and loan balances are shown as positive amounts OWED and subtracted from net worth. If the live fetch fails, returns the last cached balances with a note. Requires finance_link_bank first. No args. Returns { accounts: [{name, institution, type, balance, currency, as_of}], assets, liabilities, net_worth, live }.
Inputs: no named parameters.
finance_cash_flow_forecastCash Flow ForecastARead-onlyIdempotent
Project cash flow over the next N days from detected recurring bills (outflows) and recurring income (inflows, cadence-aware). Args: starting_balance (current available cash; default 0), window_days (7-90, default 30). Returns a day-by-day projection with the running balance and a flag for the lowest point. Note: starting_balance isn't in the CSV — pass your real current balance for an accurate low-point.
Inputs: window_days, starting_balance.
finance_data_overviewData OverviewARead-onlyIdempotent
Summarize what's in the store: total transaction count, date span, last import time, and per-category inflow/outflow totals across all history. Call this first to know what data is available. No args.
Inputs: no named parameters.
finance_debt_payoff_planDebt Payoff PlanARead-onlyIdempotent
Simulate a debt-payoff plan given a list of debts and a monthly budget. Strategy 'avalanche' (highest APR first) or 'snowball' (smallest balance first), or 'compare' to run both and show interest/time saved. Debts are provided by you (not read from the CSV). Args: debts: [{id, name, balance, apr, minPayment}], monthly_budget, strategy. Returns the plan(s): months to debt-free, total interest, debt-free date, per-debt payoff month.
Inputs: debts (required), monthly_budget (required), strategy.
finance_disconnect_bankDisconnect BankADestructiveIdempotent
Forget the SimpleFIN connection (clears the stored access URL). Imported transactions and cached balances are kept. No args.
Inputs: no named parameters.
finance_import_csvImport Rocket Money CSVAIdempotent
Import a Rocket Money transaction CSV export into the local store. Idempotent: re-importing the same or an updated export dedupes by a stable row hash, so only genuinely new transactions are added. Args: path (absolute path to the .csv). Returns counts (parsed/inserted/skipped), the date span, and any parsing warnings.
Inputs: path (required).
finance_link_bankLink Bank (SimpleFIN)A
Connect a bank via SimpleFIN Bridge for real-time balances and ongoing transaction sync. Get a one-time setup token from bridge.simplefin.org (My Account → generate a token) and pass it here. Claims the token into a durable access URL stored locally, then runs an initial 365-day sync. Idempotent transactions (dedupe by provider id). Args: setup_token. Returns account balances + import counts.
Inputs: setup_token (required).
finance_list_category_rulesList Category RulesAIdempotent
List all merchant→category rules (most specific first) and re-apply them across the whole store, returning how many transactions changed. Call after editing rules to resync. No args.
Inputs: no named parameters.
finance_list_subscriptionsList Subscriptions & Recurring ChargesARead-onlyIdempotent
Detect recurring charges (subscriptions, memberships, bills) from transaction history using merchant-key normalization and cadence analysis. Flags price hikes vs the prior baseline. Args: none (analyzes all history). Returns { totals: {monthly, annual, count, hikes}, subscriptions: [{label, category, cadence, lastAmount, monthlyCost, occurrences, lastDate, nextDate, daysUntilNext, priceHike?}] }.
Inputs: no named parameters.
finance_merchant_historyMerchant HistoryARead-onlyIdempotent
Every charge from a given merchant (substring match on name/descriptor), with a spend summary. Useful for 'how much have I paid X' and spotting creep. Args: merchant (required), from/to (optional). Returns { merchant, count, total_spent, total_received, first_date, last_date, average, transactions: [...] }.
Inputs: merchant (required), to, from.
finance_remove_category_ruleRemove Category RuleADestructiveIdempotent
Delete a category rule by its exact match string. Transactions it already recategorized keep their current category (rules don't store the original). Args: match. Returns whether a rule was removed.
Inputs: match (required).
finance_search_transactionsSearch TransactionsARead-onlyIdempotent
Search transactions with filters. All optional; combine freely. Returns newest-first, paginated. Amounts are signed (positive = money in, negative = money out). Args: from/to (YYYY-MM-DD), category, merchant (substring on name/descriptor), min_amount/max_amount (by absolute value), flow ('in'|'out'|'all'), limit (1-500, default 100), offset. Returns { total, count, offset, has_more, transactions: [{id, txn_date, amount, description, category, account, institution}] }.
Inputs: to, flow, from, limit, +5 more.
finance_spending_by_categorySpending by CategoryARead-onlyIdempotent
Total inflow and outflow grouped by category over an optional date range (defaults to all history). Sorted by outflow descending. Args: from/to (YYYY-MM-DD). Returns { range, categories: [{category, inflow, outflow, count}], total_outflow, total_inflow, net }.
Inputs: to, from.
finance_syncSync Bank (SimpleFIN)A
Pull new transactions and refresh balances from SimpleFIN. By default fetches from the day after the latest transaction already in the store (so it won't re-pull or double-count history from your CSV) — pass days_back to force a wider window (e.g. 365 for a full refresh). Transactions dedupe by provider id. Requires finance_link_bank first. Args: days_back (optional, 1-730). Returns { accounts, newTransactions, store_span }.
Inputs: days_back.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 15 tools
Each tool targets a distinct operation in the personal finance domain: import, search, analysis (categories, subscriptions, cash flow, merchant history), debt planning, bank connectivity, and rule management. No two tools have overlapping purposes; an agent can easily differentiate them.
All tool names follow the consistent snake_case pattern 'finance_verb_noun' (e.g., finance_import_csv, finance_search_transactions, finance_link_bank). This uniformity makes the tool set predictable and easy to navigate.
With 15 tools, the server is well-scoped for a personal finance assistant. It covers data import, querying, analysis, planning, and bank integration without being overwhelming. Each tool serves a clear purpose.
The tool set covers core workflows: importing, searching, categorizing (via rules), analyzing spending, detecting subscriptions, forecasting cash flow, planning debt payoff, and syncing bank transactions. Minor gaps exist, such as the lack of direct transaction editing or deletion, but these can be worked around.
Maintenance
Related MCP Connectors
Ask Claude about your income and spending, and import bank statements. No bank login.
Personal finance for AI agents — onboard, import statements, categorize & budget over MCP.
Read-only finance MCP server. Connects your banks, cards, payment apps, books and payroll into one ledger for your AI. Can't move money. Open source (AGPL-3.0), free during beta.
Personal finance, bank account, and shared memory connector for Claude, ChatGPT, Gemini Spark & more
Related MCP Servers
- FlicenseBqualityDmaintenanceA personal MCP server that gives Claude native access to YNAB budget data.46-
- AlicenseNot gradedqualityBmaintenanceA local-first MCP server that connects SimpleFIN bank accounts to Claude, storing data in a local DuckDB file and providing a web dashboard.2MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that lets you log and query your own spending through natural conversation with Claude, instead of a spreadsheet or app.33 npm6ISC
- FlicenseAqualityDmaintenancePersonal finance MCP server that integrates Plaid bank data with local SQLite memory for conversational budgeting, goal tracking, and transaction management.15-