Expense Tracker
Provides expense and income tracking by storing transactions in a PostgreSQL database, with tools for adding, listing, summarizing, editing, and deleting expenses, and adding credits.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Expense TrackerAdd an expense of ₹500 for Entertainment with the description Movie."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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
PostgreSQLRelated MCP server: expense-tracker
Features
The MCP server currently provides six tools:
add_expense- Add a new expenselist_expenses- List expenses within a date rangesummarize_expenses- Get an expense summary and category-wise breakdownedit_expense- Update an existing expensedelete_expense- Delete an expense by transaction IDcredit- 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.lockDatabase
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-serverInstall the project dependencies:
uv syncIf the dependencies have not been added yet:
uv add fastmcp
uv add psycopg[binary]
uv add python-dotenvEnvironment 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_PASSWORDReplace 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.pyThe 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.pyDatabase 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__/
*.pycNever 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 toolsadd_expenseAdd ExpenseC
Add an expense to the expense tracker
| Name | Required | Description | Default |
|---|---|---|---|
| amount | Yes | ||
| category | Yes | ||
| description | Yes | ||
| transaction_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| amount | Yes | ||
| category | Yes | ||
| description | Yes | ||
| transaction_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| transaction_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| amount | No | ||
| category | No | ||
| description | No | ||
| transaction_id | Yes | ||
| transaction_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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
| Name | Required | Description | Default |
|---|---|---|---|
| to_date | Yes | ||
| from_date | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| to_date | Yes | ||
| from_date | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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.
6 tool updates
v0.1.0- First observed
add_expense - First observed
credit - First observed
delete_expense - First observed
edit_expense - First observed
list_expenses - First observed
summarize_expenses
TDQS
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.
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.
Six tools is a reasonable, focused size for an expense tracker. Each tool covers a necessary core operation without unnecessary bloat.
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
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
Personal finance tracker — log transactions, view summaries, and browse a dashboard
- ManiloOAuthapp.ledgy.api
Log, query, and edit expenses, budgets, and accounts in Manilo (formerly Ledgy) from any MCP-compatible AI assistant.
Personal finance by conversation: expenses, receipts, statement import, budgets, net worth.
Personal finance ledger for AI agents — query spending, track bills, forecast cash flow.
Related MCP Servers
- FlicenseCqualityDmaintenanceEnables 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-
- FlicenseNot gradedqualityCmaintenanceManages personal expenses through natural language with tools for adding, updating, searching, and summarizing expenses, backed by Supabase.-
- FlicenseNot gradedqualityDmaintenanceEnables management of expenses via SQLite database, including adding, listing, updating, deleting, filtering, and summing expenses through natural language.-
- FlicenseNot gradedqualityDmaintenanceEnables 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
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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