settleup
Wraps Settle Up's Firebase Realtime Database API, providing operations for authenticating and managing shared expenses, groups, members, transfers, and debts through a typed client.
Click on "Deploy 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., "@settleupWho owes whom in the Japan group?"
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.
settleup-kit
Unofficial Settle Up client, CLI and MCP server. Groups, members, expenses, transfers and debts — from your email and password, with nothing else to set up.
Not affiliated with Settle Up or Step Up Labs. Settle Up publishes a public API; this is a typed client for it.
Why this exists
Settle Up's API is a raw Firebase Realtime Database. That is a fine thing to
publish, but it means every caller re-derives the same handful of facts: that
the amount lives inside items[] rather than on the transaction, that member
ids are per-group, that an empty description is refused as Permission denied,
and that exchange rates divide rather than multiply.
This wraps that into named operations — "split 3200 yen between everyone" — and writes down what cost time to work out. See docs/traps.md.
Related MCP server: open-splitwise
Install
npm install -g @notsuhas/settleup-kitFrom source:
git clone https://github.com/notsuhas/settleup-kit && cd settleup-kit
npm ci && npm run build && npm install -g .Then:
export SETTLEUP_EMAIL="you@example.com"
export SETTLEUP_PASSWORD="…"CLI
settleup login # once — signs in and caches the token
settleup groups # every group, with its members
settleup balances --group Lisbon # who owes whomRecording a shared cost. It defaults to you paying, split equally between every active member:
settleup add --group Lisbon --amount 3200 --purpose "Dinner" --currency EUR --category 🍽added
2026-09-11 3200 EUR 🍽 Dinner paid by Alice for Alice, Bob
id -Nq7xR2vK9mBpL4dTfWcOverride either side when it wasn't an even split:
settleup add --group Lisbon --amount 8000 --purpose "Hotel" --paid-by Bob
settleup add --group Lisbon --amount 1400 --purpose "Taxi" --for "Alice,Bob"Paying someone back, which settles a debt rather than adding a shared cost:
settleup pay --group Lisbon --amount 1000 --to Alice --from BobEditing and deleting take the id printed under each row:
settleup edit -Nq7xR2vK9mBpL4dTfWc --group Lisbon --amount 2900
settleup rm -Nq7xR2vK9mBpL4dTfWc --group LisbonAn edit changes only what you pass. The category, the split and any tip or tax lines survive an amount-only edit.
Groups and members:
settleup new-group --name "Lisbon 2026" --currency EUR --members "Alice,Bob"
settleup add-member --group "Lisbon 2026" --name Carol
settleup edit-group --group "Lisbon 2026" --name "Lisbon trip"
settleup rm-group --group "Lisbon 2026" # and every transaction in itThe first member is you — it is the one expenses default to being paid by.
--json on any command gives machine-readable output. --sandbox points at
Settle Up's sandbox project instead of your real account.
MCP server
Seven tools: list_groups, group_balances, search_transactions,
add_expense, add_transfer, edit_transaction, delete_transaction. For
unequal splits, pass shares as exact amounts by member name or id:
{
"group": "Trip",
"amount": 120,
"purpose": "Dinner",
"paidBy": ["Alice"],
"shares": { "Alice": 45, "Bob": 75 }
}Shares must sum exactly to the total; do not combine them with forWhom. This
creates one expense with native weighted shares. edit_transaction also accepts
shares for single-item expenses. It refuses to replace a multi-item split,
preserving separate tip or tax allocations. Search and write results include
item amounts and member weights under split for verification.
For equal splits use forWhom and let Settle Up round the amounts; a rounding
penny should not turn an equal split into custom weights. Custom decimal
allocations stay as decimal weights, matching the official app's amount-entry
conversion. Settle Up does not persist a separate exact-amount display mode.
Creating groups and members is opt-in behind SETTLEUP_MCP_ALLOW_STRUCTURE=1;
delete_group needs SETTLEUP_MCP_ALLOW_DELETE=1 on top, because it takes
every transaction in the group with it.
{
"mcpServers": {
"settleup": {
"command": "npx",
"args": ["-y", "-p", "@notsuhas/settleup-kit", "settleup-mcp"],
"env": {
"SETTLEUP_EMAIL": "you@example.com",
"SETTLEUP_PASSWORD": "…"
}
}
}
}There is an HTTP transport too, for running it somewhere and pointing a client
at it. It requires MCP_TOKEN and refuses to start without one.
Full notes: docs/mcp.md.
Library
import { createClient } from "@notsuhas/settleup-kit";
const su = createClient();
await su.groups();
await su.addExpense({
group: "Lisbon",
amount: 3200,
purpose: "Dinner",
currencyCode: "EUR",
});
await su.addTransfer({
group: "Lisbon",
amount: 1000,
to: "Alice",
from: "Bob",
});
await su.balances("Lisbon");The CLI and the MCP server are both thin layers over this, so they cannot do anything the library can't.
Everything hangs off a group
Settle Up has no global notion of a person. Members, transactions and debts all belong to one group, and the same friend is a different member id in each — so every call names a group, and members are named within it.
Which member you are is read from the account, which is what lets "who paid" default to you.
Money
Amounts are always positive. Direction comes from the operation: add records
money spent for the group, pay records one member paying another back.
A row carries its own currency, which need not be the group's. Settle Up converts on the server and reports debts in the group currency. Totals are summed as decimal strings rather than floats, because an expense splits into items and repeated float addition drifts.
The one thing to know before you start
A description is required. Settle Up's security rules reject a transaction
whose purpose is empty, and the error is a bare Permission denied with HTTP
401 — which reads like an auth problem and sends you debugging the wrong thing.
This kit refuses an empty description locally, before the request goes out.
Environment
| credentials |
| use this token instead of signing in |
|
|
| where the token cache lives |
| HTTP MCP transport |
| MCP: group and member writes |
| MCP: |
The token cache is written 0600 under ~/.config/settleup-kit/.
Docs
docs/api.md — auth, paths, the transaction shape
docs/traps.md — everything that cost time to work out
docs/mcp.md — wiring the MCP server into a client
Licence
MIT. Use it against your own account.
Transaction times
Write tools accept optional dateTime instead of date, for example
"2026-10-19T11:10:00+09:00" for a receipt printed at 11:10 in Japan. Use a
full ISO timestamp with seconds and either Z or an explicit UTC offset. Do not
send both fields. Date-only calls keep their existing behavior; omitted fields
on edits preserve the saved time. The CLI equivalent is
--date-time '2026-10-19T11:10:00+09:00'. MCP transaction results include
dateTime when a timestamp is available.
npm trusted publishing setup
The release workflow uses GitHub OIDC rather than NPM_TOKEN. Configure a
trusted publisher on the npm package for this exact GitHub repository and
release.yml, with direct publishing allowed and no environment restriction.
Keep repository.url aligned with the repository. A newly configured publisher
must complete a successful publish within two days or npm expires it.
If publishing returns E404 while package reads work, check the package's trusted publisher configuration and repository metadata before replacing tokens. Passing CI does not verify npm publish authorization; verify the release job itself.
Verified receipt recording
Prefer the MCP record_expense tool for a new receipt. It accepts a stable
receiptId, the usual expense fields and an explicit dateTime. It checks
existing rows before writing and returns the server readback with
verified: true; no follow-up search is necessary. shares retains exact
unequal amounts, while forWhom uses the app's normal equal split. Optional
original retains original-currency receipt details in the private journal;
amount and currencyCode remain the actual charged amount and currency.
The private journal lives under the existing config directory. Reuse the same ID
and identical inputs on retries. If a timed-out write is visible, it is reused.
A missing uncertain write, edited or deleted indexed row, conflicting input or
duplicate match stops without another write. After a process crash, reconcile
the journal before an operator removes a stale writer.lock.
This server cannot be deployed
Maintenance
Related MCP Connectors
Manage Splitwise balances, expenses, and groups from your workspace. Fetch friends and recent acti…
Split bills from your AI: read bills & balances, create equal splits, request settlements.
- LoanItOAuthapp.loan-it
Track shared expenses, balances, reminders and records. OAuth required; no money transfers.
1 - TriphetuOAuthcom.triphetu
Plan group trips with your AI: itineraries, checklists, shopping, expenses and who owes whom.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables conversational control of Splitwise accounts through Claude AI, allowing users to add expenses, check group balances, record settlements, and manage payment splits using natural language commands. Supports multiple currencies and flexible splitting methods including equal, exact, and percentage-based divisions.1MIT
- AlicenseAqualityBmaintenanceEnables AI agents to manage Splitwise expenses through natural language, including reading balances, splitting costs, and handling authentication and rate limits automatically.7MIT
- AlicenseAqualityCmaintenanceEnables MCP-compatible AI hosts to manage Splitwise accounts, including expenses, groups, friends, and balances, with built-in guards against duplicate charges and unconfirmed destructive actions.1718 PyPI1MIT
- AlicenseAqualityBmaintenanceEnables natural-language interaction with Splitwise to explain balances, find missing or duplicate expenses, plan settlements, and safely add expenses with confirmation.103 npmMIT