Skip to main content
Glama
Expense Tracker MCP

Expense Tracker MCP

Expense Tracker MCP

A local MCP server that lets an LLM (Claude Desktop, the FastMCP Inspector, or any MCP client) track your expenses and credits in a SQLite database on your machine.

Built with FastMCP.

Features

  • Add, list, update, and delete expenses

  • Track credits (money received) separately from expenses

  • Category / subcategory enforcement — the LLM can only use categories and subcategories you've defined, so entries stay clean and consistent

  • Per-category expense summary

  • Running balance (total credited − total spent)

  • All data stored locally in SQLite — nothing leaves your machine

Related MCP server: ExpenseTracker MCP Server

Project structure

expence-tracker-mcp/
├── server.py                              # entry point used by Claude Desktop / fastmcp CLI
├── src/expence_tracker_mcp/
│   ├── __init__.py                        # server: tools, resource, DB logic
│   ├── category.json                      # editable category → subcategory map
│   └── expenses.db                        # SQLite DB (auto-created on first run, gitignored)
├── pyproject.toml
└── uv.lock

Requirements

  • Python >= 3.13

  • uv

Setup

git clone <this-repo>
cd expence-tracker-mcp
uv sync

uv sync creates a .venv and installs fastmcp and its dependencies.

Running the server standalone

uv run server.py

Running the MCP Inspector (debugger)

Use this to interactively call the tools/resource in a browser before wiring it up to an LLM client.

uv run fastmcp dev inspector server.py

This prints a local URL (with an auth token) — open it in your browser, click Connect, then try the tools from the Tools tab.

Connecting to Claude Desktop

Add an entry to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "ExpenseTracker": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/absolute/path/to/expence-tracker-mcp",
        "fastmcp",
        "run",
        "server.py"
      ]
    }
  }
}

Replace the path with the absolute path to this project on your machine, then fully quit and reopen Claude Desktop (Cmd+Q, not just close the window) to pick up the change.

Tools

Tool

Description

add_expense(date, amount, category, subcategory, note="")

Add a new expense. category and subcategory are required and must come from category.json (see below).

list_expenses(category="", start_date="", end_date="")

List expenses, optionally filtered by category and/or date range (YYYY-MM-DD).

update_expense(id, date="", amount=None, category="", subcategory="", note="")

Update an existing expense. Only the fields you pass are changed.

delete_expense(id)

Delete an expense by id.

add_credit(date, amount, source="", note="")

Add credit (money received) to the tracker.

list_credits(start_date="", end_date="")

List credits, optionally filtered by date range.

summarize_expenses(start_date="", end_date="")

Totals grouped by category, plus overall total_spent.

get_balance()

Returns { total_credited, total_spent, balance }.

Every write tool returns {"status": "ok", ...} on success or {"status": "error", "message": "..."} on failure (e.g. invalid category, record not found) instead of raising — so the calling LLM can see what went wrong and retry.

Resource

Resource

Description

data://categories

The full category → subcategory map from category.json. The LLM is instructed (via the resource description) to always pick category/subcategory from here.

Customizing categories

Edit src/expence_tracker_mcp/category.json — it's read fresh on every tool call, so changes take effect immediately without restarting the server:

{
  "food": ["dining out", "snacks"],
  "travel": ["cab", "flight", "train", "fuel"],
  "rent": ["house rent", "office rent"],
  "groceries": []
}
  • A category must be a top-level key in this file, or add_expense / update_expense will reject it.

  • subcategory is required on add_expense.

  • If a category's subcategory list is non-empty, the subcategory must be one of those exact values.

  • If a category's subcategory list is empty (e.g. "groceries": []), any non-blank subcategory text is accepted — useful for categories too varied to enumerate.

This enforcement happens server-side in add_expense/update_expense, so invalid entries are rejected even if the LLM ignores the data://categories resource.

Database

SQLite database at src/expence_tracker_mcp/expenses.db, auto-created on first run with two tables:

CREATE TABLE expenses(
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    date TEXT NOT NULL,
    amount REAL NOT NULL,
    category TEXT NOT NULL,
    subcategory TEXT DEFAULT '',
    note TEXT DEFAULT ''
);

CREATE TABLE credits(
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    date TEXT NOT NULL,
    amount REAL NOT NULL,
    source TEXT DEFAULT '',
    note TEXT DEFAULT ''
);

The .db file is gitignored — each machine gets its own local data.

Inspecting the server

Check tool/resource counts without starting a full client:

uv run fastmcp inspect server.py

Available Tools

8 tools
add_creditAdd CreditC

Add credit (money received) to the tracker.

Inputs: date (required), amount (required), note, source. Returns: object

add_expenseAdd ExpenseA

Add a new expense. category and subcategory are required and must come from the data://categories resource. If a category's subcategory list is empty, any descriptive subcategory text is acceptable, but it must not be left blank.

Inputs: date (required), amount (required), category (required), subcategory (required), +1 more. Returns: object

delete_expenseDelete ExpenseB

Delete an expense by id.

Inputs: id (required). Returns: object

get_balanceGet BalanceA

Get total credited, total spent, and remaining balance.

Inputs: no named parameters. Returns: object

list_creditsList CreditsB

List credits, optionally filtered by date range (YYYY-MM-DD).

Inputs: end_date, start_date. Returns: result

list_expensesList ExpensesA

List expenses, optionally filtered by category and/or date range (YYYY-MM-DD).

Inputs: category, end_date, start_date. Returns: result

summarize_expensesSummarize ExpensesB

Summarize expenses by category, optionally filtered by date range (YYYY-MM-DD).

Inputs: end_date, start_date. Returns: object

update_expenseUpdate ExpenseA

Update an existing expense. Only provided fields are changed. category and subcategory must come from the data://categories resource.

Inputs: id (required), date, note, amount, +2 more. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 8 tools

    Disambiguation5/5

    Each tool targets a distinct resource and action: expenses have add/list/update/delete, credits have add/list, and summarize/get_balance provide reporting. There is no meaningful overlap or ambiguity between tools.

    Naming Consistency5/5

    All tools follow a clear verb_noun snake_case pattern. List operations use plural nouns (list_expenses, list_credits) while singular entity operations use singular nouns, which is a predictable and consistent convention.

    Tool Count5/5

    Eight tools is well-scoped for an expense tracker: full CRUD for expenses, credit tracking, and balance/summary reporting. Each tool earns its place without redundancy or bloat.

    Completeness4/5

    Expenses have complete CRUD coverage and reporting is solid, but credits only support add and list with no update or delete. This is a minor gap that agents can work around by re-adding corrected credits, but it is a slight lifecycle gap.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      C
      quality
      D
      maintenance
      Enables personal expense management with SQLite storage, allowing users to add, update, delete, list, and summarize expenses by category through natural language interactions.
      5
      -
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI assistants to manage personal expenses by adding, querying, and summarizing expense data through a SQLite database and configurable categories.
      1
      GPL 3.0
    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables management of expenses via SQLite database, including adding, listing, updating, deleting, filtering, and summing expenses through natural language.
      -