The README is direct about this: MCP tools can read and manage the key owner's vendors, categories and transactions, so connecting an agent is equivalent to handing over the account. Create a dedicated key for the MCP client and revoke it when you are done, rather than reusing the one your scripts already have. Also worth knowing before you commit: there is no bank sync, budget planning or net-worth tracking, and the project describes itself as early.
A self-hostable personal finance app — dashboards, categories, vendors, reports, searchable transaction history — that also exposes an MCP endpoint. The MCP surface reads and manages the same data the web app does, using the API key of whoever created it.
- Tools covering the current user, vendors, categories, transactions, dashboard summaries and statistics
- Transactions carry categories, notes, dates, vendors and currencies; multiple currencies convert to your default through Frankfurter
- Reversals are first class — `effect: 'reversal'` records a refund or chargeback as a positive amount that reports subtract from the category
- Summaries across daily, weekly, monthly, quarterly and yearly windows, with category split
- The same data is reachable over a REST API with the same key, or through a typed Node client
- Optional weekly and monthly email summaries with generated spending insights
- Vendor candidate search and enrichment, which calls the configured enrichment provider when one is set
You run it yourself: Node.js 22, npm 11, and Docker with Docker Compose v2. Published as xpenser version 0.1.0. Setup is `npm install`, `cp .env.example .env`, build the three shared workspaces, `docker compose up -d postgres`, then `npm run dev` — the web app on port 3000 and the API on port 4000, with migrations run at API startup. The MCP endpoint is Streamable HTTP at `/api/mcp` and authenticates with an API key created in Settings → Preferences → API keys, sent as a bearer token. Single-user deployments can set `XPENSER_SINGLE_USER_MODE=1` to skip account login in the web app; the API and MCP endpoint still require a key.
One command plus a key — npx -y mcp-remote https://xpenser.example.com/api/mcp, then supply credentials
