Family Expense MCP
Provides persistent storage and querying for family expense, income, budget, and report data, acting as the single source of truth for the MCP server's tools.
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., "@Family Expense MCPAdd ₹350 for groceries and show this month's summary"
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.
Family Expense AI — MCP-Based Expense Assistant
A real, working family expense/income/budget assistant whose financial capabilities are exposed as MCP (Model Context Protocol) tools through a FastMCP server, backed by PostgreSQL. This is not a chatbot with a database bolted on — MCP is the core of the architecture: any MCP-compatible LLM client (Claude Desktop, or Claude via a remote connector) discovers and invokes these tools directly.
Architecture
User
|
AI / LLM (e.g. Claude)
|
MCP Protocol
|
FastMCP Server (main.py)
|
MCP Tools (23 tools)
+----------+----------+-----------+
| | | |
Family Expenses Income Reports/Budgets/Insights
| | | |
+----------+----------+-----------+
|
PostgreSQLRemote usage (Claude connecting to a deployed server):
Claude -> MCP Connector -> HTTPS -> Remote MCP Server (Render)
-> FastMCP -> MCP Tools -> PostgreSQLThe LLM only ever understands the request, selects a tool, and
generates parameters. Validation, business logic, calculations, and all
persistence happen in app/services/*, with PostgreSQL as the single
source of truth.
Related MCP server: budget-mcp
Multi-user family usage (one shared database, many Claude accounts)
Each family member can run their own Claude account/client connected to
the same deployed MCP server (https://<your-app>.onrender.com/mcp).
When someone says "I spent ₹500 on lunch," their Claude calls add_expense
with member_name set to that person — the server resolves the name to a
member_id and writes it into the one shared Postgres database. So the
whole family's spending naturally converges into a single source of truth,
per person, without needing separate databases per user.
Tips for this setup:
Register everyone once with
add_family_member(e.g. Praneeth → Self, Rahul → Brother, Mom → Mother).Give each person's Claude a system/custom instruction like "My name is Rahul — when using Family Expense tools, use member_name='Rahul' unless I say otherwise." so they don't have to repeat their name every time.
Every report/insight/budget tool accepts an optional
member_nameto scope results to one person, or omit it for the whole family.
Project structure
mcp-famil/
├── main.py # FastMCP server: 23 MCP tools, thin wrappers
├── chatbot.py # Local NL test harness (no MCP client needed)
├── tool_router.py # Dispatches tool name + params -> service call
├── formatter.py # Raw results -> clean, INR-formatted text
├── requirements.txt
├── .env.example
├── .gitignore
├── render.yaml # One-file Render deployment config
│
├── app/
│ ├── db/
│ │ ├── connection.py # psycopg2 pool + init_db()
│ │ └── schema.sql # Table definitions
│ ├── services/ # Business logic + validation (DB access only here)
│ │ ├── errors.py
│ │ ├── validators.py
│ │ ├── date_utils.py
│ │ ├── family_service.py
│ │ ├── expense_service.py
│ │ ├── income_service.py
│ │ ├── summary_service.py
│ │ ├── report_service.py
│ │ ├── budget_service.py
│ │ └── insight_service.py
│ └── ai/
│ ├── schemas.py # Anthropic tool-use schemas (mirrors main.py)
│ ├── intent_parser.py # NL -> (tool, params) via Claude tool-use
│ ├── category_detector.py # Keyword-based expense category guesser
│ ├── reports.py # Rule-based report phrase parsing
│ ├── budget.py # Rule-based budget phrase parsing
│ └── insights.py # Suggestion generation from real DB numbers
│
└── tests/Database schema
family_members(id, name, relationship, created_at)
expenses(id, member_id → family_members, amount, category, expense_date, description, created_at, updated_at)
income(id, member_id → family_members, amount, source, income_date, notes, created_at, updated_at)
budgets(id, category, amount, created_at, updated_at)
Applied automatically on startup via init_db() (idempotent
CREATE TABLE IF NOT EXISTS), so there's no separate migration step to run.
MCP tools (23)
Area | Tools |
Family |
|
Expenses |
|
Income |
|
Summary |
|
Reports |
|
Budgets |
|
Insights |
|
Every tool is a thin wrapper: it calls tool_router.route() (which calls
into app/services/*) and formats the result with formatter.py before
returning it — so the response an LLM/user sees is already a clean,
₹-formatted message, not a raw JSON blob.
Currency
Everything is INR (₹), formatted with Indian digit grouping
(e.g. ₹12,34,567.00, not ₹1,234,567.00). Amounts are stored as
NUMERIC(12,2) in Postgres and only formatted at the presentation layer.
Setup
Install dependencies
pip install -r requirements.txtConfigure environment
cp .env.example .env # edit .env: set DATABASE_URL to your PostgreSQL connection string # (LLM_API_KEY is only needed for chatbot.py, not for the MCP server itself)Run the MCP server
python main.py # Tables are created automatically. MCP endpoint: http://localhost:8000/mcp(Optional) Try the local natural-language chatbot
python chatbot.pyExample session:
You: Rahul spent ₹700 on petrol today. AI: ✅ Expense Added 👤 Rahul 💸 ₹700.00 📂 Petrol 📅 2026-09-06
Local testing with an MCP client
With python main.py running, point any MCP-compatible client at
http://localhost:8000/mcp (Streamable HTTP transport) and confirm all 23
tools are discoverable. For example, using the FastMCP CLI:
fastmcp dev main.pyNote: depending on your installed
fastmcpversion, the transport name passed tomcp.run()inmain.pymay need to be"streamable-http"instead of"http". Checkfastmcp --version/ release notes if the server fails to start.
Using Supabase as the database
Supabase's database is plain PostgreSQL, so no code changes are
needed — just point DATABASE_URL at it:
Create a project at supabase.com.
Go to Project Settings → Database → Connection string → URI. Use the Session pooler (or Transaction pooler) connection string, not the direct connection — it's the one meant for long-running apps and works fine with this project's connection pool.
Copy it into
DATABASE_URLin your.env(or your host's environment variables), replacing[YOUR-PASSWORD]with your actual DB password:DATABASE_URL=postgresql://postgres.xxxxxxxxxxxx:[YOUR-PASSWORD]@aws-0-xx-xxxx-x.pooler.supabase.com:5432/postgresRun
python main.py(or redeploy your host) —init_db()creates thefamily_members,expenses,income, andbudgetstables on Supabase automatically on first boot.SUPABASE_URL/SUPABASE_KEYare not needed for this — those are only for the Supabase client SDK, which this project doesn't use.
Deployment
You need somewhere to run the always-on Python process — Supabase only hosts the database, not the app. Any host that gives you a public HTTPS URL works (Claude's remote connector requires HTTPS, not plain HTTP). Whatever you choose, the server just needs:
DATABASE_URLset to your Supabase connection stringTo listen on
0.0.0.0:$PORT(already handled bymain.py)The
/mcppath reachable over HTTPS at the root of your public URL
render.yaml is included for a one-file Render deploy if you want it:
Build command:
pip install -r requirements.txtStart command:
python main.pyEnvironment variables:
DATABASE_URL,LLM_API_KEY(optional),ANTHROPIC_MODEL(optional)
If you're self-hosting on your own server/VPS instead, make sure a
reverse proxy (Caddy, nginx + certbot, etc.) terminates TLS in front of
main.py and forwards to it — Claude cannot connect to a bare http://
URL or a self-signed certificate.
Verify the deployed server before adding it to Claude
curl -s -D - -o /dev/null -X POST https://<your-domain>/mcp \
-H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'You should get HTTP/1.1 200 back with a serverInfo block naming
"Family Expense MCP". If this fails, fix it before adding the connector —
Claude will hit the same URL.
Add it to Claude as a custom connector
On claude.ai, go to Settings → Connectors.
Click Add custom connector.
Enter a name (e.g. "Family Expense AI") and the URL:
https://<your-domain>/mcpSave, then enable the connector in a chat (the tool/connector picker below the message box).
Test it: ask Claude something like "Add a family member named Praneeth, relationship Self" or "I spent ₹500 on lunch today" — Claude should call the corresponding MCP tool and show the formatted result.
Every family member can add the same URL as their own custom connector from their own claude.ai account — they all talk to the same hosted server and the same Supabase database, so everyone's expenses land in one shared, per-person-tracked source of truth (see "Multi-user family usage" above).
Example natural-language flow
User: "Rahul spent ₹700 on petrol today."
LLM determines intent:
add_expense,member_name=Rahul,amount=700,category=Petrol,expense_date=todayadd_expensetool →tool_router.route()→expense_service.add_expense()Resolves "Rahul" →
member_id, validates the amount, inserts the rowResult formatted and returned:
✅ Expense Added 👤 Rahul 💸 ₹700.00 📂 Petrol
Error handling
Every tool call is wrapped so it never crashes the server. Domain errors
(ValidationError, NotFoundError) are caught and returned as a friendly
⚠️ ... message — covering: unknown family member, invalid/negative
amount, missing required parameter, unparseable date, expense/income not
found, no budget set for a category, unknown tool, and any unexpected
exception (❌ Unexpected error: ...).
Security
No credentials are hardcoded anywhere. DATABASE_URL and LLM_API_KEY
are read from the environment (.env, gitignored). .env.example
documents every variable without real values.
Running tests
pytestUnit tests (formatter, validators, date parsing, category detection,
rule-based NL parsing, tool routing) run with no external services.
tests/test_integration.py exercises real database round-trips and is
skipped automatically unless DATABASE_URL points at a database.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
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 for AI agents — onboard, import statements, categorize & budget over MCP.
Household finance memory, budgets, transactions, and monthly reviews for AI assistants.
- ManiloOAuthapp.manilo
Log, query, and edit expenses, budgets, and accounts in Manilo from any MCP-compatible AI assistant.
Personal finance ledger for AI agents — query spending, track bills, forecast cash flow.
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceA lightweight MCP server that lets LLM clients track, query, and summarize personal expenses using a local SQLite database.-
- FlicenseAqualityBmaintenanceA lightweight MCP server for managing personal finances locally. It allows users to log transactions, view summaries, manage categories, and interact with their budget via any MCP-compatible LLM client.12-
- FlicenseNot gradedqualityBmaintenanceSelf-hosted household finance app for shared expenses, budgets, investments, loans, and zakat, exposing MCP tools for AI agents to manage finances via natural language.3-
- FlicenseNot gradedqualityCmaintenanceAI-powered expense tracking MCP server that connects LLM clients to PostgreSQL for natural language expense management.-
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/Praneeth2383/mcp-famil'
If you have feedback or need assistance with the MCP directory API, please join our Discord server