Skip to main content
Glama
kanya-simform

money-split-mcp

README.md
# money-split-mcp

A remote, multi-user [MCP](https://modelcontextprotocol.io) server for splitting group expenses (Splitwise-lite). Each
user registers an account by email, gets an API key, and uses that key to create groups, add members by email, log
expenses, and see who owes whom — all through an MCP client (Claude Desktop, claude.ai connectors, etc.).

## How it works

- `POST /register` is a plain REST endpoint (not an MCP tool) that creates a user and returns a one-time API key.
- Every other call goes through `POST /mcp` (MCP Streamable HTTP) with `Authorization: Bearer <api_key>`. The server
  is stateless: each request resolves the caller from their API key and builds a fresh, user-scoped set of tools.
- Data (users, groups, expenses, shares, settlements) lives in Postgres via Prisma.

## Local setup

1. Copy `.env.example` to `.env` and adjust `DATABASE_URL` if needed.
2. Get a local Postgres running, matching `.env`'s `DATABASE_URL` (`moneysplit`/`moneysplit`/db `moneysplit` on
   `localhost:5432`):
   - **Native install**: `sudo apt-get install -y postgresql postgresql-contrib`, then:
     ```
     sudo -u postgres psql -c "CREATE USER moneysplit WITH PASSWORD 'moneysplit';"
     sudo -u postgres psql -c "CREATE DATABASE moneysplit OWNER moneysplit;"
     ```
   - **Docker** (if available): `docker compose up -d`
3. Install deps and run the first migration:
   ```
   npm install
   npm run prisma:migrate
   ```
4. Start the dev server: `npm run dev` (listens on `http://localhost:3000` by default).
5. Run the unit tests any time: `npm test` (covers the split/balance math, no DB needed).

## Manually testing the full flow

Register two users:

```bash
curl -s localhost:3000/register -H 'content-type: application/json' \
  -d '{"email":"alice@example.com","name":"Alice"}'
curl -s localhost:3000/register -H 'content-type: application/json' \
  -d '{"email":"bob@example.com","name":"Bob"}'
```

Each response includes an `apiKey` — save both, they're never shown again.

Then drive the MCP tools with the [MCP Inspector](https://github.com/modelcontextprotocol/inspector):

```bash
npx @modelcontextprotocol/inspector
```

Connect it to `http://localhost:3000/mcp` (Streamable HTTP transport) with header
`Authorization: Bearer <alice's apiKey>`, then call tools in order:

1. `create_group` `{ "name": "Trip to Goa" }` → note the returned group `id`
2. `add_member_to_group` `{ "group_id": "...", "email": "bob@example.com" }`
3. `add_expense` `{ "group_id": "...", "description": "Hotel", "amount": 100 }` (defaults: paid by Alice, split
   evenly across all members)
4. `get_balances` `{ "group_id": "..." }` → Alice should show `+50`, Bob `-50`, with a suggested settlement of Bob
   paying Alice 50.
5. Reconnect the Inspector with Bob's API key and call `settle_up` `{ "group_id": "...", "to_email":
   "alice@example.com", "amount": 50 }`, then `get_balances` again to confirm both are back to `0`.

## Deploying to Render

This repo includes a `render.yaml` Blueprint that provisions a Postgres database and a Node web service together.

1. Push this repo to GitHub.
2. In the Render dashboard: **New > Blueprint**, point it at the repo — it will read `render.yaml` and create both
   the `money-split-db` database and the `money-split-mcp` web service, wiring `DATABASE_URL` automatically.
3. The web service's build command runs `npx prisma migrate deploy` after compiling, keeping the schema in sync on
   every deploy. (Render's free plan doesn't support the separate `preDeployCommand` step, so it's folded into the
   build instead.)
4. Once deployed, verify:
   ```
   curl https://<your-service>.onrender.com/health
   ```

Note: Render's free Postgres plan expires after a fixed trial period — check current Render pricing before relying
on it long-term; swap in any external Postgres (e.g. Neon, Supabase) by just changing `DATABASE_URL` if needed.

## Using it from an MCP client

1. Register a real account against the deployed URL:
   ```bash
   curl -s https://<your-service>.onrender.com/register -H 'content-type: application/json' \
     -d '{"email":"you@example.com","name":"Your Name"}'
   ```
2. Add it as a remote MCP server in your client.

   **Claude Code (CLI)** — add it at local scope (not committed to git) with the key pulled from an env var, since
   `.mcp.json` would otherwise be shared/committed:
   ```bash
   export MONEY_SPLIT_API_KEY=<your apiKey>

   claude mcp add --transport http money-split https://<your-service>.onrender.com/mcp \
     --header "Authorization: Bearer \${MONEY_SPLIT_API_KEY}"
   ```

   **Claude Desktop** — add to its config:
   ```json
   {
     "mcpServers": {
       "money-split": {
         "url": "https://<your-service>.onrender.com/mcp",
         "headers": { "Authorization": "Bearer <your apiKey>" }
       }
     }
   }
   ```
   (Check your specific client's docs for the exact key names it expects for a remote Streamable HTTP server with
   custom headers — some clients configure this through a UI instead of raw JSON.)
3. Each group member registers their own account and adds the server with their own key — that's what ties MCP
   activity back to "their" groups and balances.
4. From inside the client: "create a group called Goa Trip", "add bob@example.com to it", "log a ₹3000 hotel
   expense split evenly", "who owes whom in the Goa Trip group?".