expense-tracker
README.md
# š° Expense Tracker MCP Server
A production-ready **Model Context Protocol (MCP)** server for your personal expense tracker, built with **FastMCP 3.x** and backed by **Supabase** (PostgreSQL).
Connect it to Claude Desktop, Cursor, or any MCP-compatible client and manage your finances with natural language.
---
## ⨠Features
| Tool | What it does |
|---|---|
| `add_expense` | Record a new expense |
| `update_expense` | Modify any field of an existing expense |
| `delete_expense` | Permanently remove an expense |
| `get_expense` | Fetch a single expense by UUID |
| `list_expenses` | Filter expenses by date, category, shop, amount, payment method |
| `search_expenses` | Full-text search across title, shop, notes, category |
| `summarize_expenses` | Totals & % breakdown by category / month / shop |
| `get_monthly_report` | Full month report with per-category breakdown |
| `get_budget_status` | Compare spending vs a budget limit |
| `get_shops` | All shops you've visited + visit counts + total spent |
| `get_categories` | All unique categories in your data |
| `export_expenses` | Export to CSV |
**Resources** (live data snapshots):
- `expense://today` ā Today's spending
- `expense://recent/{n}` ā Last N expenses
- `expense://categories` ā All categories in use
---
## š Quick Setup
### 1. Create the Supabase Table
Go to [supabase.com](https://supabase.com) ā your project ā **SQL Editor** and run:
```sql
CREATE TABLE expenses (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
title TEXT NOT NULL,
amount NUMERIC(12, 2) NOT NULL CHECK (amount > 0),
category TEXT NOT NULL,
shop TEXT,
date DATE NOT NULL,
payment_method TEXT,
notes TEXT,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- Auto-update updated_at on every row change
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = now();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER set_updated_at
BEFORE UPDATE ON expenses
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
-- Indexes for fast filtering
CREATE INDEX idx_expenses_date ON expenses(date);
CREATE INDEX idx_expenses_category ON expenses(category);
CREATE INDEX idx_expenses_shop ON expenses(shop);
```
### 2. Get Your API Keys
In Supabase ā **Project Settings** ā **API**:
- Copy your **Project URL**
- Copy your **anon / public key** (or service role key for private use)
### 3. Create Your `.env` File
```bash
copy .env.example .env
```
Edit `.env`:
```env
SUPABASE_URL=https://your-project-id.supabase.co
SUPABASE_KEY=your-anon-key-here
```
### 4. Install Dependencies
```bash
uv sync
```
### 5. Test the Server
```bash
# Start the MCP inspector (browser UI to test all tools)
uv run fastmcp dev main.py
```
---
## š Claude Desktop Integration
Add this to your `claude_desktop_config.json`
(usually at `%APPDATA%\Claude\claude_desktop_config.json`):
```json
{
"mcpServers": {
"expense-tracker": {
"command": "uv",
"args": ["run", "python", "main.py"],
"cwd": "C:\\Users\\saina\\OneDrive\\Desktop\\expense-tracker-mcp-server"
}
}
}
```
Restart Claude Desktop. You'll see a š icon with `expense-tracker` tools available.
---
## š¬ Example Prompts
Once connected to Claude Desktop, try:
```
"Add an expense: ā¹450 for lunch at Dominos today, paid by UPI"
"Show me all my Food expenses this month"
"How much did I spend in June 2026?"
"Am I over my ā¹5000 Food budget this month?"
"Where do I spend money most often?"
"Search for all Zomato expenses"
"Give me a monthly report for June 2026"
"Export all expenses from this month as CSV"
"What's my total spending this week by category?"
```
---
## šļø Project Structure
```
expense-tracker-mcp-server/
āāā main.py # FastMCP server ā all 12 tools + 3 resources
āāā db.py # Supabase data access layer
āāā models.py # Pydantic validation models
āāā .env # Your secrets (never commit this!)
āāā .env.example # Template for .env
āāā pyproject.toml # Dependencies
```
---
## š”ļø Security Notes
- Never commit your `.env` file (it's in `.gitignore`)
- Use the **anon key** for personal use ā it's safe for client-side access
- Use **Row Level Security (RLS)** in Supabase if you ever share the project
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues