Skip to main content
Glama
Sharan0402

Expense Tracker MCP Server

by Sharan0402

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

Related MCP server: Expense Tracker MCP Server

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 key

  • store_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 key

  • receipt_id: Foreign key to receipts table

  • item_name_raw: Original item name from receipt

  • item_type: Normalized category

  • quantity: Item quantity (default: 1.0)

  • unit_price: Price per unit (nullable)

  • line_total: Total price for this line

  • created_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:

  1. Static Rules (fast, deterministic)

    • Checks item name against pre-defined patterns

    • Handles common grocery items with keyword matching

    • ~90% accuracy for typical grocery items

  2. 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

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

  1. Check that the path in claude_desktop_config.json is correct

  2. Restart Claude Desktop completely

  3. 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.py with @mcp.tool decorator

  • 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:


Built with FastMCP - The fast, Pythonic way to build MCP servers

Available Tools

3 tools
get_item_historyA

Query purchase history for a specific item type.

Returns detailed purchase history including:

  • List of all purchases with dates, stores, quantities, and prices

  • Statistics: total purchases, date range, average frequency, total spent

Args: item_type: Category to query (e.g., 'milk', 'bread', 'eggs') time_range_days: Number of days to look back (default: 365)

Returns: Dictionary with purchases list and aggregated statistics

ParametersJSON Schema
NameRequiredDescriptionDefault
item_typeYesItem category to query (e.g., 'milk', 'bread', 'eggs')
time_range_daysNoNumber of days to look back (default: 365)

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It describes the return format in detail (list of purchases with specific fields and aggregated statistics), which is valuable context. However, it lacks information on potential limitations, such as data availability, error handling, or performance considerations (e.g., large datasets). This partial coverage results in a baseline score.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and appropriately sized, starting with the core purpose, detailing return values, and listing parameters. Each sentence serves a clear purpose: the first states the action, the next two outline outputs, and the last specifies args and returns. It could be slightly more concise by avoiding redundancy with the schema, but overall, it's efficient and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (2 parameters, read-only query), no annotations, and the presence of an output schema (implied by 'Returns' section), the description is reasonably complete. It explains what the tool does, what it returns, and the parameters, compensating for the lack of annotations. However, it misses some behavioral context like data source or limitations, preventing a perfect score.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, meaning the input schema already fully documents both parameters ('item_type' and 'time_range_days') with descriptions and defaults. The description repeats some of this information (e.g., examples for 'item_type' and the default for 'time_range_days'), adding minimal value beyond the schema. According to the rules, with high schema coverage, the baseline is 3 even without additional param info in the description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose as 'Query purchase history for a specific item type,' which is a specific verb ('query') + resource ('purchase history') combination. It distinguishes itself from sibling tools like 'import_receipt_from_pdf' (data ingestion) and 'list_item_types' (metadata listing) by focusing on historical data retrieval. However, it doesn't explicitly contrast with potential alternatives for querying history, keeping it from a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for retrieving purchase history based on item type and time range, but provides no explicit guidance on when to use this tool versus alternatives. There's no mention of prerequisites, such as needing existing data from 'import_receipt_from_pdf,' or exclusions like not handling real-time data. This leaves usage context somewhat vague, relying on the agent to infer from the purpose.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

import_receipt_from_pdfA

Import and parse a receipt from a PDF file.

This tool:

  1. Extracts text from the PDF

  2. Parses receipt metadata (store, date, totals)

  3. Extracts line items with prices

  4. Categorizes each item using hybrid approach (static rules + LLM)

  5. Stores everything in SQLite database

Args: pdf_path: Absolute path to the PDF receipt file ctx: FastMCP context for logging and LLM access

Returns: Summary of imported receipt including store, date, item count, and category breakdown

ParametersJSON Schema
NameRequiredDescriptionDefault
pdf_pathYesAbsolute path to PDF receipt file

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden and does well by detailing the multi-step behavior (extraction, parsing, categorization, storage). It explains the hybrid categorization approach and mentions database storage, though it could add more about error handling, performance, or permissions needed for file access.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a clear opening sentence, bullet points for steps, and separate sections for Args and Returns. It's appropriately sized but could be slightly more concise by integrating the Args section into the main text since it repeats schema information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (multi-step processing), no annotations, and the presence of an output schema, the description is fairly complete. It outlines the process and return values, though it could benefit from mentioning error cases or limitations (e.g., PDF quality requirements).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents the single parameter 'pdf_path'. The description adds minimal value beyond the schema by restating the parameter in the 'Args' section without providing additional context like file format constraints or examples.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Import and parse a receipt from a PDF file') and details the multi-step process (extract text, parse metadata, extract line items, categorize, store). It distinguishes itself from sibling tools like 'get_item_history' and 'list_item_types' by focusing on data ingestion rather than querying existing data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when needing to process PDF receipts, but lacks explicit guidance on when to use this tool versus alternatives (none mentioned) or any prerequisites. It doesn't specify scenarios where this tool is preferred or when it should be avoided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_item_typesA

List all item types/categories in the database with statistics.

Returns summary statistics for each item type including:

  • Total number of purchases

  • Most recent purchase date

  • Total amount spent

Useful for getting an overview of all tracked expense categories.

Returns: Dictionary with list of all item types and their statistics

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes the tool's behavior by specifying what statistics are returned (total purchases, recent purchase date, total amount spent) and the output format (dictionary with list). It does not cover aspects like rate limits or error handling, but provides solid operational context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with the core purpose, followed by bullet points for statistics and a usage note. Every sentence adds value without redundancy, making it efficient and easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (0 parameters), no annotations, and the presence of an output schema (which handles return values), the description is complete. It covers purpose, behavior, usage context, and output semantics adequately without needing to explain parameters or duplicate schema details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 0 parameters with 100% coverage, so the baseline is 4. The description adds no parameter information, which is appropriate given no parameters exist, and it does not mislead about inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('List') and resource ('all item types/categories in the database'), and distinguishes it from siblings by specifying it returns statistics rather than individual item history or PDF imports. It goes beyond the name/title to explain what 'list' entails.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool ('Useful for getting an overview of all tracked expense categories'), which implicitly differentiates it from siblings focused on history or imports. However, it does not explicitly state when not to use it or name alternatives, keeping it from a perfect score.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A3.8/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: get_item_history retrieves detailed purchase history for a specific item, import_receipt_from_pdf processes new receipts into the database, and list_item_types provides an overview of all tracked categories. There is no overlap in functionality, and an agent could easily select the appropriate tool based on the task.

Naming Consistency4/5

The tool names follow a consistent verb_noun pattern (get_item_history, import_receipt_from_pdf, list_item_types), making them predictable and readable. The minor deviation is that 'import_receipt_from_pdf' includes a preposition ('from'), but this does not significantly impact consistency or clarity.

Tool Count3/5

With only 3 tools, the server feels slightly thin for an expense tracker domain, as it lacks operations like updating or deleting entries, or querying by other criteria (e.g., date ranges or stores). However, the tools cover core functionalities (import, query history, list categories), so it is borderline but functional.

Completeness3/5

The tool set covers basic import and query operations but has notable gaps: there are no tools for updating or deleting data, managing stores or receipts beyond import, or advanced filtering (e.g., by date or store). This could lead to agent failures if such operations are needed, though core workflows (adding receipts and viewing history) are supported.

Maintenance

ActivityInactive
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables extraction of structured data from documents like invoices, receipts, and bank statements using local Vision AI (Ollama) or cloud providers (Gemini), with data stored in a local SQLite database.
    9
    MIT
  • F
    license
    A
    quality
    D
    maintenance
    Enables AI assistants like Claude to manage personal expenses locally using SQLite. Supports adding, categorizing, summarizing expenses, setting budgets, and exporting data without cloud services.
    8
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables natural language management of personal expenses, including adding, listing, and summarizing expenses with local SQLite storage.
  • F
    license
    A
    quality
    D
    maintenance
    Parses Italian INAZ payslip PDFs into a local SQLite database, enabling AI clients to analyze salary history, search items, and get detailed breakdowns while keeping data on your machine.
    5
    1

Appeared in Searches

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Sharan0402/expense-tracker-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server