budget-mcp
MCP server scaffold for budget tooling, currently only provides a placeholder ping tool returning 'pong' to confirm plumbing works. No real budget functionality yet.
README
budget-mcp
MCP server for budget tooling, built on the official MCP Python SDK.
Project layout
budget-mcp/
├── pyproject.toml
├── budget.db # SQLite db, created by init_db.py (gitignored)
├── src/
│ └── budget_mcp/
│ ├── __init__.py
│ ├── server.py # MCPServer instance + tools
│ ├── db.py # schema DDL + connection helper
│ ├── init_db.py # resets budget.db and seeds example rows
│ ├── money.py # dollars <-> integer-cents conversion
│ ├── dates.py # date validation + period resolution
│ ├── categorizer.py # LLM-based transaction categorizer
│ └── eval_categorizer.py # accuracy check against a labeled set
├── tests/
│ ├── conftest.py # puts src/ on sys.path for test collection
│ └── test_tools.py # end-to-end tool tests, see "Tests" below
└── .venv/ # local virtualenv (gitignored)
Requirements
- Python 3.10+ (this project was set up with Python 3.12 via Homebrew:
brew install python@3.12)
Setup
cd budget-mcp
/opt/homebrew/bin/python3.12 -m venv .venv
.venv/bin/pip install -e ".[dev]"
PYTHONPATH=src .venv/bin/python -m budget_mcp.init_db # creates + seeds budget.db
macOS + iCloud Drive gotcha: if
~/Desktopis synced via iCloud Drive, the editable install's_editable_impl_budget_mcp.pthfile in.venv/lib/python3.12/site-packages/can end up with the macOS "hidden" file flag set, which makes Python 3.12 skip it — a bareimport budget_mcp(e.g. in a REPL or test) will fail withModuleNotFoundErroreven though the install "succeeded". If that happens, run:chflags nohidden .venv/lib/python3.12/site-packages/_editable_impl_budget_mcp.pthThis doesn't affect running the server or the init script below — both are invoked with
PYTHONPATH=src, which sidesteps the editable-install mechanism entirely.
categorize_transaction calls the Anthropic API, so it needs a key:
export ANTHROPIC_API_KEY=sk-ant-...
Add the same variable to the env block in the Claude Desktop config below so
it's available when Claude Desktop launches the server.
Database
Three tables (see src/budget_mcp/db.py for the full DDL):
budgets(category PK, monthly_limit)transactions(id, date, amount, category -> budgets.category, source, note)savings_goals(id, name, target_amount, current_amount, account_type)
All money columns are integer cents (e.g. 50000 == $500.00) to avoid
float rounding — SQLite has no real DECIMAL type. transactions.amount is
signed: negative = expense, positive = income.
Re-run PYTHONPATH=src .venv/bin/python -m budget_mcp.init_db any time to
wipe budget.db and reset it to the seed data.
Tools
ping()— placeholder, returns"pong".add_transaction(date, amount, category, source, note=None)— inserts a transaction and returns it plus the category's running total for that transaction's calendar month.amountis dollars (e.g.-45.67);datemust beYYYY-MM-DD;categorymust already exist inbudgets. Rejects bad dates, zero/non-finite/sub-cent amounts, unknown categories, and emptysourcewith a clear error message (no stack traces).get_spending_summary(period, group_by, start_date=None, end_date=None)— sums expense transactions (amount < 0) overperiod("this_month","last_month", or"custom"withstart_date/end_date), grouped by"category"or"source", and returns each group's total plus % of total spend. Rejects unknownperiod/group_byvalues and missing/invalid custom-range dates.categorize_transaction(description)— classifies a raw statement line (e.g."TESCO STORES 3421 LONDON") into one ofrent,food,transport,savings,business_expense,entertainment,other, via a Claude Haiku 4.5 call with structured JSON output (category,confidence,reasoning). The returned category is checked against the fixed list before being returned — an invalid category from the model surfaces as an error rather than being trusted. RequiresANTHROPIC_API_KEY(see Setup above).
Tests
.venv/bin/pytest tests/ -v
Each test spawns a real server subprocess and drives it through the actual
MCP protocol (same path Claude Desktop uses), against a fresh throwaway
SQLite db (via BUDGET_MCP_DB_PATH) — your real budget.db is never
touched. Covers both tools' happy paths (including that running totals and
spend percentages come out exact, not float-drifted) and every validation
rejection (bad dates, zero/non-finite/sub-cent amounts, unknown categories,
empty source, bad period/group_by, missing custom-range dates).
categorize_transaction isn't in this suite — LLM output isn't deterministic,
so it doesn't belong in a pass/fail unit test. Instead, check its accuracy
against 15 hand-labeled realistic statement lines:
PYTHONPATH=src .venv/bin/python -m budget_mcp.eval_categorizer
This calls the live API (needs ANTHROPIC_API_KEY) and prints a pass/fail
per example plus overall accuracy.
Running locally
Run the server directly (it speaks MCP over stdio):
PYTHONPATH=src .venv/bin/python -m budget_mcp.server
It will sit waiting for an MCP client to talk to it over stdin/stdout — that's expected, it's not meant to be run interactively.
To poke at it with the official inspector UI instead:
PYTHONPATH=src .venv/bin/mcp dev src/budget_mcp/server.py
Connecting to Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json and add
an mcpServers entry:
{
"mcpServers": {
"budget-mcp": {
"command": "/Users/hamza/Desktop/projects/budget-mcp/.venv/bin/python",
"args": ["-m", "budget_mcp.server"],
"env": {
"PYTHONPATH": "/Users/hamza/Desktop/projects/budget-mcp/src",
"ANTHROPIC_API_KEY": "sk-ant-..."
}
}
}
}
Then fully quit and reopen Claude Desktop. In a new conversation, the tools
should be available (look for the tools/hammer icon) — try asking Claude to
call ping, then to add a transaction or get a spending summary.
Notes
- Uses MCP Python SDK v2 (
mcp.server.MCPServer, formerlyFastMCPin v1.x). Requiresmcp>=1.2.0perpyproject.toml, but what's actually installed here is the current 2.x line. - Tool validation errors are raised as
mcp.server.mcpserver.exceptions.ToolError, which the framework returns to the client as a plain error message — never a Python traceback.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
Neon Database
MCP server for interacting with Neon Management API and databases
E2B
Using MCP to run code via e2b.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.