Skip to main content
Glama
amxn18

Expense Tracker

by amxn18

Expense Tracker MCP Server

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

The project allows users to manage expenses and income through natural language. Claude Desktop acts as the MCP client, while the FastMCP server handles tool execution and communicates with PostgreSQL.

Architecture

Claude Desktop
      |
      | MCP over stdio
      v
FastMCP Server
      |
      v
Python Tools
      |
      v
PostgreSQL

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

  • python-dotenv

  • uv

  • Claude Desktop

Project Structure

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

Database

The application uses PostgreSQL as the database.

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

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:

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

Install the project dependencies:

uv sync

If the dependencies have not been added yet:

uv add fastmcp
uv add psycopg[binary]
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 the password of your PostgreSQL user.

Do not commit the .env file to Git.

Running the Server

From the project directory:

uv run fastmcp run server.py

The server uses the stdio transport so that Claude Desktop can communicate with it locally.

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

{
  "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.

Usage

The tools can be used directly 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 all 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 is handled separately in:

db/connection.py

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

The application uses psycopg to communicate with PostgreSQL.

Transaction Handling

Database write operations use explicit transaction handling.

On successful operations:

SQL operation
      |
      v
   commit()

If an error occurs:

SQL operation
      |
      v
  rollback()

This prevents incomplete 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.

Current Status

The first functional version of the project is complete.

Implemented:

  • FastMCP server

  • PostgreSQL database

  • PostgreSQL connection layer

  • Expense creation

  • Expense listing

  • Expense summaries

  • Expense editing

  • Expense deletion

  • Credit creation

  • Claude Desktop MCP integration

Future Improvements

Planned improvements include:

  • Repository layer

  • Service layer

  • Better input validation

  • Improved error handling

  • Balance calculation

  • More detailed financial reports

  • Automated tests

  • Logging

  • Database migrations

  • Docker support

  • CI/CD

  • Improved project architecture

License

This project is built for learning and personal development.

Available Tools

6 tools
add_expenseAdd ExpenseC

Add an expense to the expense tracker

ParametersJSON Schema
NameRequiredDescriptionDefault
amountYes
categoryYes
descriptionYes
transaction_dateNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.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 must disclose behavioral context such as validation rules, required vs optional fields, date handling, or side effects. It only restates the operation and discloses nothing beyond the tool name.

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 description is short and front-loaded, with no filler. However, it adds little information beyond the title 'Add Expense', so its brevity comes at the expense of usefulness.

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 4-parameter mutation tool with zero schema coverage and no annotations, this description is radically incomplete. It lacks required/optional field guidance, defaults, behavioral effects, and any differentiation from sibling tools.

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%, and the description mentions no parameter details. Amount, category, description, and transaction_date receive no semantic guidance, leaving an agent without information about formats, constraints, or optionality.

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 ('Add') and resource ('an expense to the expense tracker'), which clearly communicates the operation. It also distinguishes this tool from its siblings like edit_expense, delete_expense, and list_expenses by naming a distinct action.

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?

Usage is only implied: an agent would infer this tool is for adding expenses, but there is no explicit guidance about when to use it versus alternatives. With siblings including 'credit', the description provides no routing cues or exclusions.

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

creditCreditB

Add a credit/income transaction to the expense tracker.

ParametersJSON Schema
NameRequiredDescriptionDefault
amountYes
categoryYes
descriptionYes
transaction_dateNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.1/5.0
Behavior2/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 says 'Add' which implies a create/write operation, but it does not disclose effects on existing data, whether amounts must be positive, validation behavior, or any side effects. This is minimally transparent for a mutating tool.

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, front-loaded sentence with no filler. It communicates the core action and resource type efficiently and earns its place.

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?

The tool is simple and the output schema exists, so return-value details are not necessary. The core purpose is clear, and the schema covers required parameters. However, the lack of annotations, behavioral details, and explicit usage guidance leaves meaningful gaps for an agent deciding whether and how to invoke this tool.

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 for undocumented parameters. It does not explain the meaning of amount, category, description, or transaction_date beyond the general credit/income context. The field names are somewhat self-explanatory, but the description adds little specific parameter value.

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 specifies a verb ('Add'), a resource ('credit/income transaction'), and the target system ('expense tracker'). It distinguishes itself from the sibling add_expense by explicitly labeling the transaction as credit/income, though it does not name the sibling directly.

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?

Usage context is implied: this tool is for income/credit transactions, while add_expense is presumably for expenses. However, the description provides no explicit when-to-use or when-not-to-use guidance, nor does it mention alternatives by name.

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

delete_expenseDelete ExpenseB

Delete an existing expense by transaction ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
transaction_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.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 must carry the full behavioral burden. It communicates that the operation is destructive ('Delete'), but it does not disclose whether deletion is permanent, what happens if the transaction_id does not exist, or any side effects. This is a meaningful gap for a deletion tool.

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, front-loaded sentence with no filler or repeated information. It efficiently communicates the essential action and parameter in eight words.

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?

Given the tool has only one parameter and an output schema, the description is minimally viable for invocation. However, since there are no annotations and this is a destructive operation, it leaves gaps around error behavior, permanence, and whether deletion cascades to related data.

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 for the schema's lack of parameter documentation. It mentions 'transaction ID', which echoes the parameter name but adds only minimal meaning; it does not explain where to obtain the ID or how to handle invalid or missing IDs.

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 states a specific action ('Delete'), a specific resource ('an existing expense'), and the exact identifier used ('by transaction ID'). This clearly distinguishes it from siblings like add_expense, edit_expense, or list_expenses.

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?

No guidance is given about when to use this tool versus alternatives, when deletion is appropriate, or what prerequisites must be met (e.g., the expense must already exist and have a known transaction_id). The description only states the action without contextual routing.

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

edit_expenseEdit ExpenseB

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

ParametersJSON Schema
NameRequiredDescriptionDefault
amountNo
categoryNo
descriptionNo
transaction_idYes
transaction_dateNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior3/5

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

No annotations are provided, so the description must carry the burden alone. It usefully discloses patch-like partial-update behavior ('Only the fields provided... will be updated') but omits other behavioral details such as required identifiers, validation, permissions, or error behavior.

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?

Two concise sentences with no filler; the action is front-loaded and the partial-update caveat earns its place.

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?

Because an output schema exists, return-value documentation is not required from the description. The schema plus partial-update note give a minimally usable picture, but with no annotations and no parameter explanations the definition is not rich enough for full autonomy.

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 the description adds no meanings for transaction_id, amount, category, description, or transaction_date. It only says fields provided will be updated, which is a behavior note rather than parameter-level guidance.

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 action (edit) and target (existing expense), and the partial-update note differentiates it from add/delete. It doesn't name sibling tools or enumerate editable fields, so it stops short of a 5.

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 phrase 'existing expense' implies the tool is for modifying records already created, which gives some selection context. However, it does not explicitly state when to prefer add_expense, delete_expense, or credit, nor any exclusions.

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

list_expensesList ExpensesB

List all the expenses between given 2 dates

ParametersJSON Schema
NameRequiredDescriptionDefault
to_dateYes
from_dateYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3/5.0
Behavior3/5

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

With no annotations, the description carries the behavioral disclosure burden. It conveys that this is a read-only listing operation over a date range and uses 'all' to indicate no filtering beyond the dates, but it does not mention ordering, pagination, or whether the dates are inclusive.

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 sentence with no wasted words and front-loads the main action. It is concise, though slightly under-specified in ways covered by other dimensions.

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 listing tool with an output schema, this is minimally viable: it states the resource and the date-range filter. However, it lacks sibling differentiation and explicit parameter semantics, so it is not fully complete for an agent making a confident selection.

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, but it only says 'between given 2 dates' without mapping from_date and to_date to the range boundaries or explaining inclusivity. It adds minimal meaning beyond the parameter names themselves.

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 ('List') and resource ('all the expenses') plus a date-range constraint, so an agent can tell this is a retrieval tool. It is distinct from add_expense, edit_expense, and delete_expense, though it does not explicitly differentiate itself from summarize_expenses.

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?

The description gives no explicit guidance on when to use this tool versus alternatives like summarize_expenses. It implies a date-range listing use case, but it never states exclusions or directs the agent to another sibling for aggregated summaries.

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

summarize_expensesSummarize ExpensesB

Summarize expenses between two dates.

ParametersJSON Schema
NameRequiredDescriptionDefault
to_dateYes
from_dateYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.1/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 burden of disclosing behavior. 'Summarize' implies an aggregate/read-only operation, but the description does not state whether it mutates data, what kind of summary is produced, or any operational caveats. It is minimally transparent but leaves important traits unstated.

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 clear sentence with no filler. It front-loads the verb and resource and immediately states the date-range scope. Every word earns its place.

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 tool with an output schema present, the description is nearly adequate: an agent can infer the tool takes a date range and produces a summary. However, it does not clarify what kind of summary is produced or how this differs from the sibling list_expenses, leaving a meaningful completeness gap.

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 0%, so the description must compensate. It adds the meaning that from_date and to_date form a date range ('between two dates'), which is useful, but it does not clarify inclusivity, format expectations beyond the schema, or any additional constraints. This is partial compensation, not full.

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 ('summarize') and resource ('expenses') and specifies a date-range scope, making the operation clear. It does not, however, explicitly distinguish itself from list_expenses, which is the closest sibling and could also be interpreted as covering date-filtered expense 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 guidance on when to use summarize_expenses versus list_expenses or other siblings. The date-range phrasing implies a use case, but no explicit condition, exclusion, or alternative routing is provided.

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. Dates show when Glama detected each change.

  1. 6 tool updatesv0.1.0
    • First observedadd_expense
    • First observedcredit
    • First observeddelete_expense
    • First observededit_expense
    • First observedlist_expenses
    • First observedsummarize_expenses

TDQS

B3.2/5.0
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

ActivityMaintained
ResponsivenessNo issues

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

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

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/amxn18/expense-tracker-mcp-server'

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