Expense Tracker MCP Server
A local Model Context Protocol (MCP) server that helps you track grocery and shopping expenses by parsing PDF receipts, automatically categorizing items, and storing them in a SQLite database for easy querying.
Features
- PDF Receipt Parsing: Extract line items, prices, and metadata from PDF receipts
- Smart Categorization: Hybrid approach using static rules + LLM fallback for item classification
- SQLite Storage: Persistent local database for all your expense data
- Query Tools: Ask questions like "When did I last buy milk?" or "How often do I buy bread?"
- Multi-Store Support: Works with receipts from Walmart, Costco, Target, and more
Installation
Prerequisites
- Python 3.11 or higher
- uv (recommended) or pip
Step 1: Clone or Download
cd /Users/sharan/Desktop/expense_tracker_mcp
Step 2: Install Dependencies
Using uv (recommended):
uv sync
Using pip:
pip install -r requirements.txt
Step 3: Initialize Database
The database is automatically initialized when you first run the server. The SQLite database will be created at data/expenses.db.
Running Locally
To test the server locally:
python main.py
or with uv:
uv run main.py
The server will start and listen on stdin/stdout (MCP protocol).
Connecting to Claude Desktop
Step 1: Locate Claude Desktop Config
The configuration file is located at:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%/Claude/claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
Step 2: Add MCP Server Configuration
Edit the config file and add this entry to mcpServers:
{
"mcpServers": {
"expense-tracker": {
"command": "uv",
"args": [
"--directory",
"/Users/sharan/Desktop/expense_tracker_mcp",
"run",
"main.py"
]
}
}
}
Alternative (using python directly):
{
"mcpServers": {
"expense-tracker": {
"command": "/Users/sharan/Desktop/expense_tracker_mcp/.venv/bin/python",
"args": [
"/Users/sharan/Desktop/expense_tracker_mcp/main.py"
]
}
}
}
Step 3: Restart Claude Desktop
After saving the config, restart Claude Desktop to load the MCP server.
Usage
Once connected to Claude Desktop, you can use these tools:
1. Import a Receipt
Upload a PDF receipt and the server will parse it:
Import this receipt: /path/to/walmart_receipt.pdf
Example Response:
{
"status": "success",
"receipt_id": 1,
"store_name": "Walmart",
"purchase_date": "2025-01-15",
"total": 45.67,
"items_count": 12,
"item_types": {
"milk": 1,
"bread": 1,
"eggs": 1,
"veggies": 3,
"snacks": 2,
"beverages": 2,
"meat": 2
}
}
2. Query Item History
Ask when you last bought something:
When did I last buy milk?
or
Show me all my milk purchases in the last 6 months
Example Response:
{
"item_type": "milk",
"purchases": [
{
"date": "2025-01-15",
"store": "Walmart",
"item_name": "Organic Milk 2%",
"quantity": 1.0,
"price": 4.99
},
{
"date": "2024-12-28",
"store": "Costco",
"item_name": "Kirkland Milk",
"quantity": 2.0,
"price": 6.99
}
],
"stats": {
"total_purchases": 2,
"last_purchase_date": "2025-01-15",
"first_purchase_date": "2024-12-28",
"average_days_between": 18.0,
"total_spent": 11.98
}
}
3. List All Categories
See all item types you've purchased:
What categories of items have I bought?
Example Response:
{
"item_types": [
{
"item_type": "milk",
"total_purchases": 12,
"last_purchase_date": "2025-01-15",
"total_spent": 59.88
},
{
"item_type": "bread",
"total_purchases": 8,
"last_purchase_date": "2025-01-10",
"total_spent": 27.92
}
],
"total_categories": 15
}
Supported Item Categories
The categorizer recognizes these item types out of the box:
Dairy: milk, oatmilk, eggs, cheese, yogurt, butter
Grains: bread, rice, lentils, pasta, cereal
Produce: veggies, fruits, potatoes
Proteins: meat, fish
Snacks & Beverages: snacks, beverages
Pantry: oil, spices, sauce
Household: cleaning, paper
Fallback: other (for unrecognized items)
Adding New Categories
Edit expense_tracker/categorizer.py and add patterns to the ITEM_TYPE_MAPPINGS dictionary:
ITEM_TYPE_MAPPINGS = {
# ... existing categories ...
"tofu": ["tofu", "bean curd", "soy protein"],
}
Database Schema
The SQLite database (data/expenses.db) contains two main tables:
receipts
id: Auto-increment primary keystore_name: Store name (e.g., "Walmart")purchase_date: ISO format date (YYYY-MM-DD)subtotal: Subtotal amount (nullable)tax: Tax amount (nullable)total: Total amount (required)created_at: Timestamp
items
id: Auto-increment primary keyreceipt_id: Foreign key to receipts tableitem_name_raw: Original item name from receiptitem_type: Normalized categoryquantity: Item quantity (default: 1.0)unit_price: Price per unit (nullable)line_total: Total price for this linecreated_at: Timestamp
How It Works
1. PDF Parsing
Uses pdfplumber to extract text from PDF files, then applies regex patterns to identify:
- Store name (Walmart, Costco, Target, etc.)
- Purchase date (multiple date formats supported)
- Line items with quantities and prices
- Totals (subtotal, tax, total)
2. Item Categorization
Hybrid approach:
-
Static Rules (fast, deterministic)
- Checks item name against pre-defined patterns
- Handles common grocery items with keyword matching
- ~90% accuracy for typical grocery items
-
LLM Fallback (smart, adaptive)
- Uses Claude via FastMCP's
Context.sample()for unknown items - Provides better accuracy for unusual or new items
- Automatically adapts to items not in static mappings
- Uses Claude via FastMCP's
3. Database Storage
All data is stored in a local SQLite database with proper indexing for fast queries:
- Indexes on
purchase_date,store_name,item_type - Foreign key constraints for data integrity
- Support for aggregate queries and statistics
Troubleshooting
Server not appearing in Claude Desktop
- Check that the path in
claude_desktop_config.jsonis correct - Restart Claude Desktop completely
- Check Claude Desktop logs for errors
PDF parsing errors
- Ensure the PDF is text-based (not a scanned image)
- Try opening the PDF in a viewer to verify it contains selectable text
- Check that the file path is absolute, not relative
Database locked errors
- Close any other tools accessing
data/expenses.db - Make sure only one instance of the server is running
Development
Running Tests
pytest tests/
Adding New Features
The modular architecture makes it easy to extend:
- New categorization rules: Edit
expense_tracker/categorizer.py - New receipt formats: Update patterns in
expense_tracker/pdf_parser.py - New MCP tools: Add tool functions to
main.pywith@mcp.tooldecorator - Database changes: Modify schema in
expense_tracker/database.py
License
MIT License - feel free to use and modify for your needs.
Contributing
Contributions welcome! Areas for improvement:
- Support for more receipt formats
- Better item categorization rules
- Export to CSV/Excel functionality
- Visualization dashboards
- Multi-user support
Support
For issues or questions:
- Check the FastMCP documentation
- Review MCP protocol docs
- File an issue on GitHub
Built with FastMCP - The fast, Pythonic way to build MCP servers
