expenses-tracker-mcp
# Expenses Tracker
Track expenses locally, import bank statements, and classify transactions with an AI assistant through MCP.
Built with **FastAPI, SQLite, and React**. The backend stores transactions in a local SQLite database and serves both the web app and the API under `/api`. An included Model Context Protocol (MCP) server lets compatible AI assistants query and classify transactions.
## App Demo
You can either interact with the webapp or with an AI agent to get overview on expenses per account in the last months
### Web app


### MCP interactions with Codex

### MCP categorize new transactions imported

## Features
- Import bank statement CSV files
- Add, edit, delete, filter, and classify transactions
- Maintain accounts and account groups
- View monthly overview, category totals, and daily reports
- Run a local MCP server for agents to automatically classify your transactions
## Project structure
```text
src/expenses_tracker/
cli.py Command-line entry point
web.py FastAPI app and web-server runner
database.py SQLite setup and seed accounts
transactions.py Transaction data operations
import_statement.py CSV statement import logic
api/routes.py API routes
mcp/server.py MCP server for expense tools
static/ Built frontend served by FastAPI
frontend/
index.html Vite entry HTML
src/ React source
vite.config.js Builds into src/expenses_tracker/static
```
## Requirements
- Python 3.12+
- [uv](https://docs.astral.sh/uv/)
## Setup
From the repository root, install Python dependencies:
```bash
uv sync
```
The built frontend is included in `src/expenses_tracker/static` and served directly by FastAPI.
## Run the Web App
```bash
uv run expenses web
```
The app starts on `http://127.0.0.1:8125` and opens the default browser automatically.
## Bank statement imports
Select a CSV bank statement from the transactions screen to import it.
Expected CSV columns:
- `Transaction Date` in `DD/MM/YYYY` format
- `Transaction Description`
- `Debit Amount`
- `Credit Amount`
Debit amounts are stored as negative pence values. Credit amounts are stored as positive pence values. Imported transactions are assigned to the `Pending` account by default.
## MCP server
The MCP server communicates over standard input and output (stdio). To launch it from the repository root:
```bash
uv run expenses mcp
```
To connect an MCP-compatible client, configure it to launch `uv` with these arguments, replacing the path with your local checkout:
```json
{
"mcpServers": {
"expenses-tracker": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/expenses-tracker", "run", "expenses", "mcp"]
}
}
}
```
The configuration format depends on your client; the example above is for clients that accept an `mcpServers` JSON object. If you installed the package and `expenses` is on your client's PATH, use command `expenses` with arguments `["mcp"]` instead.
Available tools include:
- guarded read-only SQL queries
- transaction listing with filters
- account listing
- pending transaction grouping
- classification summaries
- account assignment for selected transactions or filtered batches
TDQS
Scored across 8 tools
Tools are mostly distinct: raw SQL, list operations, update operations, and create account each target a unique action. However, list_pending_groups and get_classification_summary both group transactions, and update_transactions_account vs bulk_update_by_filter could be confused, though descriptions clarify the difference.
The majority follow a clear verb_noun pattern (list_, create_, update_, get_). Minor deviations like bulk_update_by_filter and run_readonly_sql are still readable and consistent in style, so the overall pattern is predictable.
8 tools is well-scoped for an expense tracking server. Each tool serves a clear purpose in querying, updating, or creating accounts, with no redundant or missing trivialities.
The surface covers listing, classification, account creation, and transaction updates, but lacks a create_transaction tool, which is a core operation for an expense tracker. Also missing account update/delete, leaving notable gaps for full lifecycle management.