๐Ÿ’ฐ expense-mcp

March 4, 2026 ยท View on GitHub

Personal Expense Tracker as an MCP Server โ€” works with Claude Desktop, Cursor, nanobot, Windsurf, and any MCP-compatible client.

Python MCP SDK License


Features

  • ๐Ÿ“ Track expenses & income with categories and descriptions
  • ๐Ÿ“Š Spending summaries โ€” today, week, month, year
  • ๐Ÿ’ณ Budget management โ€” set limits per category, get alerts at 80%/100%
  • ๐ŸŽฏ Savings goals โ€” create goals, track progress with visual bars
  • ๐Ÿ“ˆ Spending insights โ€” top categories, daily averages, biggest days
  • ๐Ÿ—‘๏ธ Safe deletion โ€” Pydantic-based elicitation for confirmation
  • ๐Ÿ”„ Dual transport โ€” stdio (local) + streamable HTTP (remote)

Install

# with uv (recommended)
uv pip install git+https://github.com/justfsl50/expense-mcp.git

# with pip
pip install git+https://github.com/justfsl50/expense-mcp.git

# from source
git clone https://github.com/justfsl50/expense-mcp.git
cd expense-mcp
pip install -e .

Quick Start

Claude Desktop

Add to %APPDATA%\Claude\claude_desktop_config.json (Windows) or ~/Library/Application Support/Claude/claude_desktop_config.json (Mac):

{
  "mcpServers": {
    "expense-mcp": {
      "command": "uv",
      "args": ["run", "expense-mcp"],
      "env": {
        "DATABASE_URL": "sqlite:///expenses.db",
        "CURRENCY": "โ‚น",
        "DEFAULT_USER": "me"
      }
    }
  }
}

Cursor / Windsurf

Same config โ€” paste into MCP settings under the respective app.

nanobot

{
  "mcp": {
    "servers": [{
      "name": "expense-mcp",
      "command": "uv run expense-mcp"
    }]
  }
}

HTTP mode (remote / multi-client)

python server.py http
# Server runs at http://127.0.0.1:8000/mcp

Environment Variables

VariableDefaultDescription
DATABASE_URLsqlite:///expenses.dbSQLite or PostgreSQL URL
CURRENCYโ‚นCurrency symbol
DEFAULT_USERdefaultUser ID for multi-user setups

PostgreSQL example:

DATABASE_URL=postgresql://user:pass@localhost:5432/expenses

Tools

ToolDescriptionRead-only
expense_addSave expense or incomeโŒ
expense_searchFilter by text, date, category, amountโœ…
expense_summarytoday / week / month / year totalsโœ…
expense_deleteDelete with Pydantic confirmation promptโŒ
expense_insightsSpending patterns and top categoriesโœ…
budget_setSet monthly category budgetโŒ
budget_listView budgets with usage %โœ…
goal_createCreate savings goalโŒ
goal_updateAdd money toward goalโŒ
goal_listView goals with progress barsโœ…

Resources

URIDescription
expense://summary/monthCurrent month summary
expense://budgets/currentThis month's budgets
expense://goals/allAll savings goals

Prompts

PromptTitleDescription
monthly_reviewMonthly ReviewStart a full month spending review
budget_setupBudget SetupAuto-suggest budgets from history
savings_planSavings PlanCreate a plan for a savings goal

Usage Examples

Just talk naturally in any MCP client:

"spent 500 on groceries"
"show food expenses this week"
"how much did I spend last month?"
"set food budget to 5000"
"am I within budget?"
"save 1000 toward my iPhone goal"
"give me spending insights"
"delete expense #12"

Architecture

  • MCP SDK v1.26.0 with FastMCP + json_response=True
  • Typed lifespan โ€” DB engine managed via AppContext dataclass
  • SQLAlchemy 2.0 โ€” DeclarativeBase, sessionmaker
  • Pydantic v2 โ€” input validation, elicitation schemas
  • Tool annotations โ€” readOnlyHint, destructiveHint, idempotentHint
  • Context logging โ€” ctx.info(), ctx.warning() in tools

Database Schema

expenses  โ€” id, user_id, amount, category, description, type, date, source, created_at
budgets   โ€” id, user_id, category, amount, month
goals     โ€” id, user_id, name, target, saved, deadline

License

MIT โ€” free to use, modify, and distribute.