Skip to main content
Glama
bhuvpal

Personal Expense Tracker

by bhuvpal

Personal Expense Tracker

A simple expense tracking API built with FastAPI, SQLite, and FastMCP.

The project lets you add expenses, view them by date range, and get a quick summary of spending by category.

Features

  • Add a new expense

  • Store expenses in SQLite

  • Filter expenses by date range

  • Get spending totals by category

  • Optional category filtering for summaries

  • Expose the FastAPI app through an MCP server

Related MCP server: Expense Tracker MCP Server

Tech Stack

  • Python 3.12+

  • FastAPI

  • SQLite

  • Pydantic

  • FastMCP

  • uv

Project Structure

PersonalExpenseTracker/
│
├── main.py           # FastAPI application and API routes
├── server.py         # FastMCP server
├── categories.json   # Expense categories
├── pyproject.toml    # Project configuration
├── uv.lock           # Locked dependencies
├── .gitignore
└── README.md

Getting Started

Clone the repository:

git clone https://github.com/bhuvpal/PersonalExpenseTracker.git
cd PersonalExpenseTracker

Install dependencies:

uv sync

Run the FastAPI server:

uv run uvicorn main:app --reload

The API will be available at:

http://127.0.0.1:8000

FastAPI also provides interactive API documentation at:

http://127.0.0.1:8000/docs

API Endpoints

Method

Endpoint

Purpose

GET

/

Check if the API is running

POST

/expenses

Add an expense

GET

/expenses

Get expenses for a date range

GET

/expenses/summarize

Get spending summary by category

Example Expense

{
  "amount": 250,
  "date": "2026-09-04",
  "category": "Food",
  "sub_category": "Lunch",
  "note": "Lunch with friends"
}

MCP Server

The project also includes a FastMCP server that exposes the FastAPI application for MCP-based usage.

Run it with:

uv run python server.py

Database

Expenses are stored locally in a SQLite database.

Each expense contains:

  • Amount

  • Date

  • Category

  • Sub-category

  • Note

Why I Built This

I built this project to practice building APIs with FastAPI and explore how existing APIs can be exposed through Model Context Protocol (MCP).

Author

Bhuv Pal

GitHub: @bhuvpal

Available Tools

4 tools
add_expense_expenses_postAdd Expense Expenses PostC

Add an expense to the database.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateYes
noteNo
amountYes
categoryYes
sub_categoryNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.2/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full behavioral burden. It implies a write/mutation but discloses nothing about required permissions, duplicate handling, validation rules, or side effects such as whether the expense is immediately persisted or visible to other users.

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

Conciseness3/5

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

The single sentence is front-loaded and free of padding, but its brevity reflects under-specification rather than economy. It is appropriately sized for what little it attempts to say.

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

Completeness2/5

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

An output schema exists, so return values need not be explained here, but for a five-parameter mutation with no annotations and 0% schema coverage the description leaves the agent without the field-level or behavioral information needed to call it correctly.

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

Parameters1/5

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

Schema description coverage is 0% with five parameters (amount, date, category, note, sub_category) and the description mentions none of them. No format hints are given for date, no currency/unit hint for amount, and no allowed values for category, leaving every parameter undocumented in both the schema and the description.

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

Purpose3/5

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

It states a clear verb and resource (add an expense), so the basic operation is unambiguous and it does not overlap with the list/summarize siblings. However, it adds nothing beyond what the tool name already conveys and gives no sense of scope, such as what constitutes a valid expense or which fields are needed.

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

Usage Guidelines2/5

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

There is no guidance on when to use this tool, when not to, or how it relates to the sibling tools list_expenses and summarize_expenses. The agent must infer usage entirely from the name.

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

homeHomeD

Home

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

D1.6/5.0
Behavior1/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure, and it discloses nothing. There is no indication of what the operation does, whether it mutates state, what it returns, or any side effects.

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

Conciseness2/5

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

The description is a single word with no structure or front-loaded information. This is under-specification rather than conciseness, since no substance exists to be concise about.

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

Completeness1/5

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

For a tool with no annotations, no parameters, no output schema, and no surrounding explanation, the description is completely inadequate. An agent has no basis to decide whether or how to invoke it.

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 tool takes zero parameters and the schema is empty, so there is nothing to document and no parameter semantics to compensate for. Baseline for a zero-parameter tool applies.

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

Purpose1/5

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

Tautological: description restates name/title.

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

Usage Guidelines1/5

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

There is no guidance whatsoever on when to use this tool, when not to, or which sibling to prefer. Given siblings like list_expenses_expenses_get and add_expense_expenses_post, the absence of routing information is a serious gap.

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

list_expenses_expenses_getList Expenses Expenses GetC

List all expenses in the database.

ParametersJSON Schema
NameRequiredDescriptionDefault
end_dateYes
start_dateYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.2/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full disclosure burden, yet it says nothing about read-only semantics, pagination, result ordering, or how the required date window bounds the results. The only behavioral message ('all expenses') actively misleads about filtering.

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

Conciseness3/5

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

One short, front-loaded sentence with no wasted clauses, so it is structurally clean, but its brevity comes at the cost of under-specification rather than efficiency.

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

Completeness2/5

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

An output schema exists, so return values need not be explained, but the description leaves two required, undocumented date parameters and the absence of any annotation coverage unaddressed. For a two-required-parameter query tool this is not sufficient to call it correctly.

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

Parameters1/5

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

Both parameters are required and schema description coverage is 0%, so the description is the only place their meaning could be conveyed. Instead it never mentions start_date or end_date and claims to return 'all' expenses, which contradicts the mandatory date-range constraint.

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

Purpose3/5

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

The description states a clear verb ('List') and resource ('expenses'), but 'in the database' adds no scope information and the phrase 'all expenses' conflicts with the tool's required start_date/end_date filtering. It also does nothing to distinguish this tool from the sibling summarize_expenses_expenses_summarize_get.

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

Usage Guidelines2/5

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

There is no when-to-use guidance, no mention of the date range that the tool requires, and no routing to or away from the siblings add_expense or summarize_expenses. The agent must infer everything from the name.

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

summarize_expenses_expenses_summarize_getSummarize Expenses Expenses Summarize GetC

Summarize expenses by category.

ParametersJSON Schema
NameRequiredDescriptionDefault
categoryNo
end_dateYes
start_dateYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.4/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full behavioral burden, and it says almost nothing. It does not disclose whether this is a read-only aggregation, how dates bound the result, whether zero-expense categories appear, or what permissions are needed. The only behavioral hint is the 'by category' grouping.

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

Conciseness3/5

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

The single sentence is front-loaded and free of filler, so it is concise. But at this length it is under-specified rather than efficient, so it earns only a middling score.

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

Completeness2/5

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

An output schema exists, so return values need not be documented. Everything else is missing: no annotations, three undocumented parameters, no usage context, and no distinction from the sibling list tool, leaving the agent with little to call this correctly.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate and largely does not. It names 'category' but leaves its semantics unresolved (filter vs. grouping key) and says nothing about the required start_date/end_date formats or whether the range is inclusive.

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

Purpose3/5

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

The verb 'Summarize' and resource 'expenses' are clear, and 'by category' hints at grouping. However, it is ambiguous whether the 'category' parameter filters the data or is the grouping dimension, and it never contrasts itself with the sibling list_expenses_expenses_get, which is the obvious alternative for raw data.

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

Usage Guidelines2/5

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

There is no when-to-use guidance, no mention of alternatives such as list_expenses_expenses_get, and no prerequisites stated. The agent must infer that this is the aggregated-view counterpart to the list tool purely from the name.

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

Tool Schema Changelog

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

  1. 4 tool updatesv0.1.0
    • First observedadd_expense_expenses_post
    • First observedhome
    • First observedlist_expenses_expenses_get
    • First observedsummarize_expenses_expenses_summarize_get

TDQS

C2.2/5.0

Scored across 4 tools

Disambiguation4/5

The three core tools (list, add, summarize expenses) target clearly distinct operations. However, the fourth tool 'home' has a vague description that gives no indication of what it does, creating one point of ambiguity.

Naming Consistency2/5

The three expense tools use verbose auto-generated route-style names with redundant doubled segments and HTTP-method suffixes (e.g. list_expenses_expenses_get), while 'home' follows no pattern at all. The conventions are mixed and unpredictable.

Tool Count3/5

Four tools is on the thin side for an expense tracker, and one of them ('home') appears to be a non-functional placeholder rather than a real capability. The count is borderline but not egregious.

Completeness2/5

The surface only supports create, list, and summarize; there is no update or delete for expenses, and no filtering or retrieval of a single expense. These are significant lifecycle gaps for an expense tracker.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables users to track personal expenses through natural language interactions with comprehensive category support and financial summaries. Provides both local and remote MCP server options with SQLite storage for fast expense management operations.
    -
  • F
    license
    A
    quality
    C
    maintenance
    Enables logging expenses, summarizing spending, and checking wallet balance through natural conversation using MCP.
    5
    -
  • A
    license
    B
    quality
    A
    maintenance
    Enables local tracking of personal expenses by adding, listing, summarizing, updating, and deleting expense records stored in a CSV file through an MCP client.
    5
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables managing and analyzing personal expenses through MCP tools, including adding expense records, listing expenses within date ranges, and summarizing spending by category, with expense categories exposed as an MCP resource.
    -