Stores parsed receipt data, expense items, and purchase history in a local SQLite database with support for querying transactions, item categories, and spending statistics.
Parses PDF receipts from Target stores to extract line items, prices, and purchase metadata for expense tracking.
Parses PDF receipts from Walmart stores to extract line items, prices, and purchase metadata for expense tracking.
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
Step 2: Install Dependencies
Using uv (recommended):
Using pip:
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:
or with uv:
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.jsonWindows:
%APPDATA%/Claude/claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
Step 2: Add MCP Server Configuration
Edit the config file and add this entry to mcpServers:
Alternative (using python directly):
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:
Example Response:
2. Query Item History
Ask when you last bought something:
or
Example Response:
3. List All Categories
See all item types you've purchased:
Example Response:
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:
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 itemsProvides better accuracy for unusual or new items
Automatically adapts to items not in static mappings
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_typeForeign 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 correctRestart 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.dbMake sure only one instance of the server is running
Development
Running Tests
Adding New Features
The modular architecture makes it easy to extend:
New categorization rules: Edit
expense_tracker/categorizer.pyNew receipt formats: Update patterns in
expense_tracker/pdf_parser.pyNew MCP tools: Add tool functions to
main.pywith@mcp.tooldecoratorDatabase 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