Skip to main content
Glama
SyedaNaziaGit

Expense-Tracker-MCP-Server

Expense Tracker MCP Server

A simple Expense Tracker MCP (Model Context Protocol) server built with FastMCP and SQLite, designed to be used from Claude Desktop. Ask Claude in plain English to log, list, and summarize your expenses.

This repo is also my learning log for MCP: it documents how I built this server step by step, how I connected it to Claude Desktop, and how I tried out a few other community MCP servers (Manim, Weather).

Related MCP server: expense-mcp

✨ Features

Tools

Tool

What it does

add_expense

Add a new expense (date, amount, category, note)

list_expenses

View expenses within a date range

summarize

Summarize spending by category

Resources

Resource

What it returns

expense:///categories

Available expense categories and subcategories

Tool and resource names above follow the reference project. Adjust the table to match whatever is defined in main.py.


Tech Stack

  • Python 3.12+

  • FastMCP (tested with 3.4.4) and MCP (tested with 1.28.1)

  • SQLite for storage

  • uv for dependency and environment management

  • Claude Desktop as the MCP client

  • MCP Inspector (by Anthropic) for testing and debugging


Project Structure

Expense-Tracker-MCP-Server/
├── main.py          # FastMCP server: tools and resources
├── expenses_db      # SQLite database file
├── pyproject.toml   # Project metadata and dependencies (uv)
├── uv.lock          # Locked dependency versions
└── README.md

Getting Started

Prerequisites

1. Install uv

pip install uv

2. Create the project

mkdir expense-tracker-mcp-server
cd expense-tracker-mcp-server
uv init .

3. Add FastMCP

uv add fastmcp

4. Verify the installation

fastmcp version

Sample output:

FastMCP version: 3.4.4
MCP version:     1.28.1
Python version:  3.12.6
Platform:        Windows-11

5. Write the server

Create main.py with your FastMCP tools and resources for a clean async SQLite example using aiosqlite).


Run and Debug

Test with MCP Inspector (the quickest way to check that tools work before touching Claude):

uv run fastmcp dev main.py

Run the server directly:

uv run fastmcp run main.py

Connect to Claude Desktop

uv run fastmcp install claude-desktop main.py

Option B: Edit the config manually

  1. Open Claude Desktop → Settings → Developer → Edit Config

  2. This opens claude_desktop_config.json. Add your server under mcpServers:

{
  "mcpServers": {
    "expense-tracker": {
      "command": "uv",
      "args": [
        "run",
        "--with",
        "fastmcp",
        "fastmcp",
        "run",
        "/absolute/path/to/main.py"
      ]
    }
  }
}
  1. Fully quit and restart Claude Desktop. Do this after every config change or newly added MCP server.

Screenshots

Claude Desktop MCP config Expense tracker in action


Example Prompts

Once connected, try these in Claude Desktop:

Add an expense

Add an expense for a cab ride to Delhi last Sunday. The fare was ₹600.

List expenses

Show all expenses between 2026-06-01 and 2026-06-30.

Summarize

Summarize my expenses for June 2026 by category.

Expense Categories

The server supports categories such as:

Food · Transport · Housing · Utilities · Health · Education · Entertainment · Shopping · Travel · Business · Investments · Personal Care · Taxes · Miscellaneous


☁️ Deploying to FastMCP Cloud (Optional)

The local setup above only works on your machine. To make the server available remotely, you can deploy it to FastMCP Cloud, as done in expense-tracker-mcp-cloud.

Once deployed you get a remote endpoint like:

https://<your-project-name>.fastmcp.app/mcp

To use it from Claude Desktop, create a small local proxy (proxy.py):

from fastmcp import FastMCP

mcp = FastMCP.as_proxy(
    "https://<your-project-name>.fastmcp.app/mcp",  # get your URL from FastMCP Cloud
    name="Expense Tracker Proxy"
)

if __name__ == "__main__":
    mcp.run()

Then install it into Claude Desktop and restart:

uv run fastmcp install claude-desktop proxy.py

Other MCP Servers I Tried

While learning MCP I also set up a few community servers. Notes below for future me (and anyone else).

After adding any server, restart Claude Desktop.

Manim MCP Server (math animations)

Repo: abhiemj/manim-mcp-server

Setup

pip install manim
pip install mcp

cd ~/Desktop
git clone https://github.com/abhiemj/manim-mcp-server.git
cd manim-mcp-server

Find the paths you need

which python3        # path to your Python executable  -> "command"
which manim          # path to the manim executable    -> MANIM_EXECUTABLE
cd src && pwd        # folder containing manim_server.py

On Windows use where python and where manim instead of which.

Add to claude_desktop_config.json (Settings → Developer → Edit Config):

{
  "mcpServers": {
    "manim-server": {
      "command": "/absolute/path/to/python",
      "args": [
        "/absolute/path/to/manim-mcp-server/src/manim_server.py"
      ],
      "env": {
        "MANIM_EXECUTABLE": "/absolute/path/to/manim"
      }
    }
  }
}

Test prompt

Use the manim-server to create an animation showing the concept of vector
transformation in linear algebra.

- Start with a 2D coordinate grid.
- Show two basis vectors: i = (1,0) in red and j = (0,1) in blue.
- Animate a transformation by applying a matrix A = [[2,1],[1,1]] to the
  grid and the vectors.
- Show the grid warping and the basis vectors moving to their new
  transformed positions.
- Add a title above: 'Linear Algebra: Matrix Transformation Demo'.

Twitter / X MCP Server (local)

Repo: EnesCinr/twitter-mcp

Add this inside the mcpServers object of your Claude config:

{
  "mcpServers": {
    "twitter-mcp": {
      "command": "npx",
      "args": ["-y", "@enescinar/twitter-mcp"],
      "env": {
        "API_KEY": "your_api_key_here",
        "API_SECRET_KEY": "your_api_secret_key_here",
        "ACCESS_TOKEN": "your_access_token_here",
        "ACCESS_TOKEN_SECRET": "your_access_token_secret_here"
      }
    }
  }
}

You get the keys from the Twitter/X developer console.

Weather MCP Server (remote via uvx)

Repo: adhikasp/mcp-weather

Get a free API key from AccuWeather Developer, then add:

{
  "mcpServers": {
    "weather": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/adhikasp/mcp-weather.git",
        "mcp-weather"
      ],
      "env": {
        "ACCUWEATHER_API_KEY": "your_api_key_here"
      }
    }
  }
}

Finding more MCP servers

Browse the curated list: awesome-mcp-servers

Never commit real API keys. Keep them in your local config file only.


Troubleshooting

Problem

Fix

Server doesn't show up in Claude

Fully quit Claude Desktop (check the system tray) and reopen it

fastmcp command not found

Close and reopen VS Code / your terminal after installing

Config changes have no effect

Check the JSON is valid and paths are absolute

Not sure if the server works

Run uv run fastmcp dev main.py and test the tools in MCP Inspector first

Wrong Python or manim path

Re-run which python3 / which manim (or where on Windows)


What I Learned

  • FastMCP fundamentals: tools and resources

  • Building and debugging an MCP server with MCP Inspector

  • SQLite integration for persistent storage

  • Connecting MCP servers to Claude Desktop (via fastmcp install and manual config)

  • Setting up third-party MCP servers (Manim, Twitter/X, Weather)

  • Remote deployment and proxying with FastMCP Cloud


Credits


Available Tools

3 tools
add_expenseC

Add a new expense to DB

ParametersJSON Schema
NameRequiredDescriptionDefault
dateYes
noteNo
amountYes
categoryYes
subcategoryNo

TDQS

C2.6/5.0
Behavior2/5

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

With no annotations, the description must disclose behavioral traits itself. It states this is a DB insert, but does not mention permissions, idempotency, validation, side effects, or return value.

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 a single, front-loaded sentence with no filler. It is concise, though it sacrifices useful detail in favor of brevity.

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?

Given 5 undocumented parameters, no annotations, and no output schema, the description is not complete enough for an agent to invoke the tool confidently. It conveys the high-level action but omits required input semantics and behavior.

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?

The input schema has 5 parameters with 0% description coverage, and the description adds no parameter-level meaning. The agent must infer semantics solely from parameter names like 'amount' and 'category'.

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 uses a specific verb and resource ('Add a new expense') that clearly identifies the operation. It is distinct from the sibling tools by nature, but it does not explicitly call out the differentiation.

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 versus list_expenses or summarize. The verb 'Add' implies creation, but no context, prerequisites, or exclusions are provided.

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

list_expensesA

Listing all expense entries between startdate to enddate

ParametersJSON Schema
NameRequiredDescriptionDefault
enddateYes
startdateYes

TDQS

A3.9/5.0
Behavior3/5

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

With no annotations provided, the description must carry the behavioral disclosure burden. It discloses that this is a read-only listing operation and that it returns all entries rather than a filtered or aggregated subset, but it does not clarify date inclusivity, ordering, pagination, or the output structure.

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 a single concise sentence with no redundant wording or repeated schema information. Every phrase contributes: the action, the resource scope, and the date constraint.

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

Completeness3/5

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

For a simple two-parameter list tool, the description gives the core invocation intent, but there is no output schema and no annotation safety information. An agent would still need to infer the return format and the accepted date representation, so the description is adequate but not fully complete.

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?

The input schema provides no property descriptions, so the description is the only semantic source. It names both startdate and enddate and states that they define the range boundaries, which adds real meaning beyond the empty schema entries. However, it does not specify date format or whether the bounds are inclusive/exclusive.

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 uses a specific verb ('Listing') with a clear resource ('all expense entries') and a date-range constraint, so an agent immediately knows what the tool does. It is also distinguishable from the sibling tools add_expense and summarize, which are write/aggregation actions rather than retrieval.

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 phrasing 'Listing all expense entries between startdate to enddate' clearly implies the tool is for retrieving every expense record in a specified range. It does not explicitly name alternatives or exclusion criteria, but the sibling tools are so different in purpose that the intended context is still obvious.

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

summarizeC

Summarize expenses by category for that date range.

ParametersJSON Schema
NameRequiredDescriptionDefault
enddateYes
categoryNo
startdateYes

TDQS

C2.9/5.0
Behavior2/5

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

With no annotations, the description carries the full burden of behavioral disclosure. It reveals that the tool summarizes expense data by category, but it does not clarify whether the category parameter filters or groups results, what happens when category is null, whether the operation is read-only, or what the returned summary looks like.

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 a single, compact sentence with no filler. It front-loads the operation and grouping dimension, though the word 'that' is slightly ambiguous and could have been replaced with 'specified' or 'given'.

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?

Given no annotations, no output schema, and 0% parameter coverage, the description is not complete enough for an agent to invoke the tool confidently. It leaves the category behavior ambiguous and omits date format and output-shape details.

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% and startdate/enddate have empty schemas, so the description must compensate. It adds only the notions of 'date range' and 'category', but it does not explain parameter formats, the meaning of the optional category default, or how the date range boundaries are handled.

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 states a specific verb ('summarize'), a resource ('expenses'), and the grouping dimension ('by category') with a date range, which clearly conveys an aggregation purpose. It is distinct from list_expenses and add_expense by its verb, though it does not explicitly name those alternatives.

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 this tool is for aggregate reporting on expenses within a date range, rather than listing individual expenses or adding them. However, it gives no explicit when-to-use or when-not-to-use guidance and does not mention the sibling tools.

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. 3 tool updatesv0.1.0
    • First observedadd_expense
    • First observedlist_expenses
    • First observedsummarize

TDQS

B3.3/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: adding an expense, listing expenses in a date range, and summarizing expenses by category. There is no meaningful overlap or confusion between them.

Naming Consistency4/5

add_expense and list_expenses follow a clear verb_noun pattern, though one uses singular and the other plural. summarize is readable but omits a noun object, creating a minor inconsistency.

Tool Count5/5

Three tools is a well-scoped set for a focused expense tracker. Each tool serves a distinct and necessary part of the basic workflow: recording, viewing, and summarizing expenses.

Completeness3/5

The core add/list/summarize workflow is covered, but there are no update or delete expense operations. This is a notable gap because users cannot correct or remove mistaken entries without direct database access.

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.
    -
  • A
    license
    A
    quality
    D
    maintenance
    Personal expense tracker MCP server that enables tracking expenses, income, budgets, and savings goals through natural language.
    10
    29 PyPI
    1
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP server for tracking expenses with local SQLite storage. Provides tools to add, list, and summarize expenses by category.
    -
  • 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