Skip to main content
Glama
youssefaltai

Finance App

by youssefaltai
README.md
# Finance App

Double-entry accounting service for personal finance with MCP (Model Context Protocol) tools. Provides a ledger, budgets, and analytics over PostgreSQL, exposed as an MCP server for use by AI agents and the central chat agent.

## Features

- **Double-entry ledger**: Accounts (ASSET, LIABILITY, EQUITY, EXPENSE, REVENUE) with enforced balance invariants
- **MCP tools** (exposed via SSE for agent use):
  - **Accounts**: create account, list accounts, get account balance
  - **Transactions**: transfer between accounts, record expense, record income
  - **Budgets**: create budget for an expense account over a date range, get available-to-spend
  - **Analytics**: net worth, expense breakdown, cashflow
- **Health endpoint** for load balancers and orchestration
- **Docker Compose** with PostgreSQL; runs on a shared `web` network for Caddy and chat-agent integration

## Prerequisites

- Docker and Docker Compose
- An existing Docker network named `web` (e.g. `docker network create web`)

## Quick Start

1. **Clone and enter the repo**
   ```bash
   git clone https://github.com/youssefaltai/finance-app.git
   cd finance-app
   ```

2. **Configure environment**
   ```bash
   cp .env.example .env
   ```
   Edit `.env` and set at least:
   - `SERVICE_NAME=finance`
   - `SERVICE_PORT=3000`
   - `DATABASE_URL` — PostgreSQL connection URL (default in code: `postgresql+psycopg2://finance:finance@postgres:5432/finance`)

3. **Run with Docker**
   ```bash
   docker compose up -d --build
   ```

4. **Verify**
   - `GET http://localhost:3000/health` → `{"status": "ok", "service": "finance"}`
   - MCP SSE endpoint: `GET http://localhost:3000/mcp/sse` (for agent connections)

## Configuration

| Variable        | Description                          | Default |
|----------------|--------------------------------------|---------|
| `SERVICE_NAME` | Service name in health response      | `finance` |
| `SERVICE_PORT` | Port the app listens on              | `3000` |
| `DATABASE_URL` | PostgreSQL URL (SQLAlchemy style)    | `postgresql+psycopg2://finance:finance@postgres:5432/finance` |
| `MCP_ENABLED`  | Mount MCP at `/mcp`                  | `true` |
| `OPENAI_API_KEY` | Not used by this service; optional | — |
| `REDIS_URL`    | Not used by this service; optional    | — |

## Integration (Caddy + Chat Agent)

- **Caddy**: Add a route so the service is reachable, e.g.  
  `handle_path /finance/* { reverse_proxy finance_app:3000 }`
- **Chat agent**: Add this service’s MCP SSE URL to `MCP_SERVER_URLS`, e.g.  
  `MCP_SERVER_URLS=http://finance_app:3000/mcp/sse`

Then the chat agent can use the finance tools (accounts, transactions, budgets, analytics) in conversation.

## Project Structure

```
app/
  main.py       # FastAPI app: /health, MCP mounted at /mcp
  config.py     # Pydantic settings from .env
  mcp.py        # FastMCP instance, tool discovery, SSE sub-app
  db/           # SQLAlchemy models and session
  services/     # Ledger, finance, analytics business logic
  tools/        # MCP tool wrappers (account_tools, transaction_tools, budget_tools, analytics_tools)
```

## MCP Endpoints

- **SSE (agent connects here):** `GET /mcp/sse`
- **Messages (used by MCP client):** `/mcp/messages/`

## Validation Checklist

- **GET /health** returns `{"status": "ok", "service": "finance"}`
- MCP tools are available at `GET /mcp/sse`
- Double-entry invariant is enforced; balances and analytics are computed from journal entries

## License

MIT

Maintenance

ActivityInactive
ResponsivenessNo issues