Skip to main content
Glama
Expense Tracker

Expense Tracker

by amxn18

Expense Tracker MCP Server

An expense tracking application built with FastMCP, PostgreSQL, and Claude Desktop.

The project was initially developed and tested locally, with Claude Desktop acting as the MCP client and FastMCP handling tool execution and communication with PostgreSQL.

The project was later converted to use async/await and the FastMCP server was deployed remotely. The remote MCP server was successfully connected to Claude as a custom connector, but the PostgreSQL database is currently running locally, so the deployed server cannot access it.

The next step is to move PostgreSQL to a hosted environment and connect it to the deployed MCP server.


Architecture

Local Version

Claude Desktop
      |
      | MCP over stdio
      v
FastMCP Server
      |
      v
Async Python Tools
      |
      v
PostgreSQL
      |
      v
localhost:5432

Remote Version

Claude / MCP Client
        |
        | MCP over HTTP
        v
FastMCP Cloud
        |
        v
Async Python Tools
        |
        v
PostgreSQL

The remote architecture is not fully operational yet because PostgreSQL is still running on the local development machine.


Related MCP server: expense-tracker

Features

The MCP server currently provides six tools:

  • add_expense — Add a new expense

  • list_expenses — List expenses within a date range

  • summarize_expenses — Get an expense summary and category-wise breakdown

  • edit_expense — Update an existing expense

  • delete_expense — Delete an expense by transaction ID

  • credit — Add an income or credit transaction


Tech Stack

  • Python

  • FastMCP

  • PostgreSQL

  • Psycopg 3

  • async/await

  • python-dotenv

  • uv

  • Claude Desktop

  • FastMCP Cloud


Project Structure

expense-tracker-mcp-server/
│
├── db/
│   ├── __init__.py
│   └── connection.py
│
├── server.py
├── .env
├── .gitignore
├── pyproject.toml
└── uv.lock

Database

The application uses PostgreSQL for persistent storage.

A single transactions table stores both expenses and credits. The transaction_type column determines whether a transaction represents an expense or a credit.

Transactions Table

CREATE TABLE transactions (
    id SERIAL PRIMARY KEY,
    amount NUMERIC(12, 2) NOT NULL,
    category VARCHAR(100) NOT NULL,
    description TEXT,
    transaction_type VARCHAR(20) NOT NULL
        CHECK (transaction_type IN ('expense', 'credit')),
    transaction_date DATE NOT NULL DEFAULT CURRENT_DATE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

Requirements

Make sure the following are installed:

  • Python 3.11+

  • PostgreSQL

  • uv

  • Claude Desktop


Installation

Clone the repository and move into the project directory:

git clone <repository-url>
cd expense-tracker-mcp-server

On Windows, if the repository is already cloned:

cd C:\Github\expense-tracker-mcp-server

Install Dependencies

uv sync

If the dependencies have not been added yet:

uv add fastmcp
uv add "psycopg[binary,pool]"
uv add python-dotenv

Environment Variables

Create a .env file in the project root:

DB_HOST=localhost
DB_PORT=5432
DB_NAME=expense-tracker
DB_USER=postgres
DB_PASSWORD=YOUR_POSTGRES_PASSWORD

Replace YOUR_POSTGRES_PASSWORD with your PostgreSQL password.

Do not commit the .env file to Git.


Async PostgreSQL Connection

The project was initially implemented using synchronous PostgreSQL connections.

It was later converted to use asynchronous PostgreSQL connections with Psycopg 3.

The connection layer uses:

psycopg.AsyncConnection

This allows database I/O to be awaited instead of blocking the execution flow while waiting for PostgreSQL.

The project is also prepared for connection pooling using Psycopg's async pooling support.


Running the Local Server

From the project directory:

uv run fastmcp run server.py

The local server uses the stdio transport so Claude Desktop can communicate with it directly.

A successful startup should display a message similar to:

Starting MCP server 'Expense Tracker' with transport 'stdio'

Claude Desktop Configuration

Add the MCP server to the Claude Desktop configuration.

Example:

{
  "mcpServers": {
    "Expense Tracker": {
      "command": "C:\\Users\\Dell\\AppData\\Local\\Programs\\Python\\Python311\\Scripts\\uv.exe",
      "args": [
        "run",
        "fastmcp",
        "run",
        "server.py"
      ],
      "env": {},
      "transport": "stdio",
      "type": null,
      "cwd": "C:\\Github\\expense-tracker-mcp-server"
    }
  }
}

The cwd should point to the location of the project on your machine.

After updating the configuration, restart Claude Desktop and verify that the Expense Tracker MCP server is connected.


Remote Deployment

The FastMCP server was also deployed to FastMCP Cloud.

The remote MCP endpoint was successfully connected to Claude as a custom connector.

The remote MCP communication follows:

Claude
   |
   | MCP over HTTP
   v
FastMCP Cloud
   |
   v
Python Tools
   |
   v
PostgreSQL

However, the PostgreSQL database is currently running on the local development machine.

The deployed server cannot access:

localhost:5432

because localhost from the remote server refers to the remote server itself, not the developer's local machine.

Therefore, the remote version currently requires a hosted PostgreSQL database.


Usage

The tools can be used through natural language in Claude Desktop.

Add Expense

Example:

Add an expense of ₹500 for Entertainment with the description Movie.

The server stores the transaction in PostgreSQL and returns the transaction ID.


List Expenses

Example:

List my expenses from September 1, 2026 to September 5, 2026.

The tool returns expenses within the specified date range along with the total expense amount.


Summarize Expenses

Example:

Summarize my expenses from September 1, 2026 to September 5, 2026.

The summary includes:

  • Total expenses

  • Number of expenses

  • Category-wise spending


Edit Expense

Example:

Change expense ID 2 to ₹650.

Individual fields can be updated without changing the remaining fields.


Delete Expense

Example:

Delete expense ID 2.

The server checks that the transaction exists and is an expense before deleting it.


Add Credit

Example:

Add a credit of ₹50,000 with category Salary and description September salary.

Credits are stored in the same transactions table with:

transaction_type = 'credit'

Database Connection

The PostgreSQL connection logic is separated into:

db/connection.py

Database credentials are loaded from environment variables using python-dotenv.

Psycopg 3 is used for communication with PostgreSQL.

The project uses asynchronous PostgreSQL connections for the async version of the server.


Transaction Handling

Database write operations use explicit transaction handling.

Successful operations are committed:

SQL operation
      |
      v
   commit()

If an error occurs:

SQL operation
      |
      v
  rollback()

This prevents failed database operations from being committed.


Security

Database credentials are stored in .env rather than directly in the source code.

The .gitignore file includes:

.env
.venv/
__pycache__/
*.pyc

Never commit database credentials or other secrets to the repository.


Development Progress

The project was developed incrementally:

1. MCP Concepts

Covered the fundamentals of:

  • MCP architecture

  • MCP clients and servers

  • Tools

  • Resources

  • Prompts

  • Tool calling

  • MCP communication

2. Basic Local MCP Server

Created a basic FastMCP server and tested MCP tool execution locally.

3. Local Expense Tracker

Extended the server into an Expense Tracker using:

  • FastMCP

  • Python

  • PostgreSQL

  • Claude Desktop

The local version worked successfully with Claude Desktop as the MCP client.

4. Async Conversion

Converted the server from synchronous functions to async/await and moved towards asynchronous PostgreSQL operations.

5. Remote Deployment

Deployed the FastMCP server to FastMCP Cloud.

6. Custom Connector

Connected the deployed MCP server to Claude using a custom connector.

7. Current Deployment Limitation

The remote server cannot access the PostgreSQL instance running on the local machine.

The next step is to move PostgreSQL to a hosted environment and connect it to the deployed FastMCP server.

8. Next Phase

After completing the remote database setup, the project will move towards building an MCP client to understand and implement the client side of the MCP architecture.


Current Status

Completed

  • MCP fundamentals

  • Basic FastMCP server

  • Local Expense Tracker

  • PostgreSQL integration

  • Six MCP tools

  • Claude Desktop integration

  • Async/await conversion

  • FastMCP Cloud deployment

  • Claude custom connector integration

In Progress

  • Move PostgreSQL to a hosted environment

  • Connect remote FastMCP server to hosted PostgreSQL

  • Production-ready connection pooling

  • Improved project architecture

  • MCP client implementation


Future Improvements

Planned improvements include:

  • Hosted PostgreSQL

  • Repository layer

  • Service layer

  • Connection pooling

  • Better input validation

  • Improved error handling

  • Balance calculation

  • Detailed financial reports

  • Automated tests

  • Logging

  • Database migrations

  • Docker support

  • CI/CD

  • MCP client implementation

  • Multi-client testing


License

This project is built for learning and personal development.

Available Tools

6 tools
add_expenseAdd ExpenseC

Add an expense to the expense tracker

Inputs: amount (required), category (required), description (required), transaction_date. Returns: result

creditCreditB

Add a credit/income transaction to the expense tracker.

Inputs: amount (required), category (required), description (required), transaction_date. Returns: result

delete_expenseDelete ExpenseB

Delete an existing expense by transaction ID.

Inputs: transaction_id (required). Returns: result

edit_expenseEdit ExpenseB

Edit an existing expense. Only the fields provided by the user will be updated.

Inputs: transaction_id (required), amount, category, description, +1 more. Returns: result

list_expensesList ExpensesB

List all the expenses between given 2 dates

Inputs: to_date (required), from_date (required). Returns: result

summarize_expensesSummarize ExpensesB

Summarize expenses between two dates.

Inputs: to_date (required), from_date (required). Returns: result

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    B3.2/5.0

    Scored across 6 tools

    Disambiguation5/5

    Each tool targets a distinct action: adding, listing, summarizing, editing, deleting expenses, or adding credits. The only potential overlap is between list_expenses and summarize_expenses, but one returns detailed entries while the other aggregates totals.

    Naming Consistency4/5

    Most tools follow a consistent verb_noun pattern like add_expense, list_expenses, and delete_expense. The outlier is 'credit', which breaks the pattern and would be clearer as add_credit or add_income.

    Tool Count5/5

    Six tools is a reasonable, focused size for an expense tracker. Each tool covers a necessary core operation without unnecessary bloat.

    Completeness2/5

    Expenses have full CRUD coverage, but credits/income can only be added—there is no way to list, summarize, edit, or delete credits. This creates a significant gap for a tracker that accepts income transactions, since users cannot manage or verify those records.

    Maintenance

    ActivityStale
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      C
      quality
      D
      maintenance
      Enables AI assistants to manage personal finances by storing, analyzing, and exporting expense data using a persistent PostgreSQL database. Supports adding/editing expenses, generating spending summaries, detecting top categories, and creating monthly reports.
      12
      -
    • F
      license
      Not graded
      quality
      D
      maintenance
      Manages personal expenses through natural language with tools for adding, updating, searching, and summarizing expenses, backed by Supabase.
      -
    • 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.
      -
    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables Claude Desktop to manage personal expenses through natural language, providing tools to add, retrieve, delete, and summarize expenses stored in a PostgreSQL database.
      1
      -