Expense Tracker MCP
Click on "Deploy 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 Tracker MCP add a $45 lunch expense under food"
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
A local MCP server that lets an LLM (Claude Desktop, the FastMCP Inspector, or any MCP client) track your expenses and credits in a SQLite database on your machine.
Built with FastMCP.
Features
Add, list, update, and delete expenses
Track credits (money received) separately from expenses
Category / subcategory enforcement — the LLM can only use categories and subcategories you've defined, so entries stay clean and consistent
Per-category expense summary
Running balance (
total credited − total spent)All data stored locally in SQLite — nothing leaves your machine
Related MCP server: ExpenseTracker MCP Server
Project structure
expence-tracker-mcp/
├── server.py # entry point used by Claude Desktop / fastmcp CLI
├── src/expence_tracker_mcp/
│ ├── __init__.py # server: tools, resource, DB logic
│ ├── category.json # editable category → subcategory map
│ └── expenses.db # SQLite DB (auto-created on first run, gitignored)
├── pyproject.toml
└── uv.lockRequirements
Python >= 3.13
Setup
git clone <this-repo>
cd expence-tracker-mcp
uv syncuv sync creates a .venv and installs fastmcp and its dependencies.
Running the server standalone
uv run server.pyRunning the MCP Inspector (debugger)
Use this to interactively call the tools/resource in a browser before wiring it up to an LLM client.
uv run fastmcp dev inspector server.pyThis prints a local URL (with an auth token) — open it in your browser, click Connect, then try the tools from the Tools tab.
Connecting to Claude Desktop
Add an entry to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"ExpenseTracker": {
"command": "uv",
"args": [
"run",
"--directory",
"/absolute/path/to/expence-tracker-mcp",
"fastmcp",
"run",
"server.py"
]
}
}
}Replace the path with the absolute path to this project on your machine, then fully quit and reopen Claude Desktop (Cmd+Q, not just close the window) to pick up the change.
Tools
Tool | Description |
| Add a new expense. |
| List expenses, optionally filtered by category and/or date range ( |
| Update an existing expense. Only the fields you pass are changed. |
| Delete an expense by id. |
| Add credit (money received) to the tracker. |
| List credits, optionally filtered by date range. |
| Totals grouped by category, plus overall |
| Returns |
Every write tool returns {"status": "ok", ...} on success or {"status": "error", "message": "..."} on failure (e.g. invalid category, record not found) instead of raising — so the calling LLM can see what went wrong and retry.
Resource
Resource | Description |
| The full category → subcategory map from |
Customizing categories
Edit src/expence_tracker_mcp/category.json — it's read fresh on every tool call, so changes take effect immediately without restarting the server:
{
"food": ["dining out", "snacks"],
"travel": ["cab", "flight", "train", "fuel"],
"rent": ["house rent", "office rent"],
"groceries": []
}A category must be a top-level key in this file, or
add_expense/update_expensewill reject it.subcategoryis required onadd_expense.If a category's subcategory list is non-empty, the subcategory must be one of those exact values.
If a category's subcategory list is empty (e.g.
"groceries": []), any non-blank subcategory text is accepted — useful for categories too varied to enumerate.
This enforcement happens server-side in add_expense/update_expense, so invalid entries are rejected even if the LLM ignores the data://categories resource.
Database
SQLite database at src/expence_tracker_mcp/expenses.db, auto-created on first run with two tables:
CREATE TABLE expenses(
id INTEGER PRIMARY KEY AUTOINCREMENT,
date TEXT NOT NULL,
amount REAL NOT NULL,
category TEXT NOT NULL,
subcategory TEXT DEFAULT '',
note TEXT DEFAULT ''
);
CREATE TABLE credits(
id INTEGER PRIMARY KEY AUTOINCREMENT,
date TEXT NOT NULL,
amount REAL NOT NULL,
source TEXT DEFAULT '',
note TEXT DEFAULT ''
);The .db file is gitignored — each machine gets its own local data.
Inspecting the server
Check tool/resource counts without starting a full client:
uv run fastmcp inspect server.pyAvailable Tools
8 toolsadd_creditAdd CreditC
Add credit (money received) to the tracker.
Inputs: date (required), amount (required), note, source. Returns: object
add_expenseAdd ExpenseA
Add a new expense. category and subcategory are required and must come from the data://categories resource. If a category's subcategory list is empty, any descriptive subcategory text is acceptable, but it must not be left blank.
Inputs: date (required), amount (required), category (required), subcategory (required), +1 more. Returns: object
delete_expenseDelete ExpenseB
Delete an expense by id.
Inputs: id (required). Returns: object
get_balanceGet BalanceA
Get total credited, total spent, and remaining balance.
Inputs: no named parameters. Returns: object
list_creditsList CreditsB
List credits, optionally filtered by date range (YYYY-MM-DD).
Inputs: end_date, start_date. Returns: result
list_expensesList ExpensesA
List expenses, optionally filtered by category and/or date range (YYYY-MM-DD).
Inputs: category, end_date, start_date. Returns: result
summarize_expensesSummarize ExpensesB
Summarize expenses by category, optionally filtered by date range (YYYY-MM-DD).
Inputs: end_date, start_date. Returns: object
update_expenseUpdate ExpenseA
Update an existing expense. Only provided fields are changed. category and subcategory must come from the data://categories resource.
Inputs: id (required), date, note, amount, +2 more. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 8 tools
Each tool targets a distinct resource and action: expenses have add/list/update/delete, credits have add/list, and summarize/get_balance provide reporting. There is no meaningful overlap or ambiguity between tools.
All tools follow a clear verb_noun snake_case pattern. List operations use plural nouns (list_expenses, list_credits) while singular entity operations use singular nouns, which is a predictable and consistent convention.
Eight tools is well-scoped for an expense tracker: full CRUD for expenses, credit tracking, and balance/summary reporting. Each tool earns its place without redundancy or bloat.
Expenses have complete CRUD coverage and reporting is solid, but credits only support add and list with no update or delete. This is a minor gap that agents can work around by re-adding corrected credits, but it is a slight lifecycle gap.
Maintenance
Related MCP Connectors
Track expenses from your AI chat: log, categorize, monthly CSV reports. All data is local.
Personal finance tracker — log transactions, view summaries, and browse a dashboard
Personal finance ledger for AI agents — query spending, track bills, forecast cash flow.
Log, query, and edit expenses, budgets, and accounts in Manilo (formerly Ledgy) from any MCP-compatible AI assistant.
Related MCP Servers
- FlicenseCqualityDmaintenanceEnables personal expense management with SQLite storage, allowing users to add, update, delete, list, and summarize expenses by category through natural language interactions.5-
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage personal expenses by adding, querying, and summarizing expense data through a SQLite database and configurable categories.1GPL 3.0
- FlicenseNot gradedqualityDmaintenanceEnables management of expenses via SQLite database, including adding, listing, updating, deleting, filtering, and summing expenses through natural language.-
- FlicenseAqualityDmaintenanceEnables AI assistants to track, query, summarize, and delete personal expenses stored in a local SQLite database via natural language.4-