Skip to main content
Glama
splitwise-mcp

splitwise-mcp

by prakhar083

splitwise-mcp

CI License: MIT

An MCP server for Splitwise. Claude Desktop, Claude Code, Cursor and any other MCP client can use it to read balances, log expenses, split bills and record settle-ups, all from a plain-language request.

"Add the 86.40 dinner to Lisbon Trip. Sam paid, split it between me, Sam and Alex Kim."

It does three things carefully:

  • Money is exact. Amounts are parsed and split in integer minor units (cents, paise, yen), never floats. Shares always add up to the cost, to the cent, and rounding is deterministic.

  • People are named, not numbered. Tools take "Sam", "alex kim" or "me" as well as Splitwise ids. When a name is ambiguous, the tool returns the candidates and the model asks you which one you meant. It never guesses.

  • Writes are guarded. SPLITWISE_READ_ONLY=true removes every mutating tool from the server. Mutating tools carry MCP destructiveHint / idempotentHint annotations so clients can prompt before running them.

Example

You: What do people owe me, and settle up Alex Kim's balance, he paid me back in cash.

The model calls:

  1. get_balances →

    {
      "owes_you": [
        { "friend": "Alex Kim", "friend_id": 2, "amount": "42.50", "currency": "USD" },
        { "friend": "Sam Patel", "friend_id": 4, "amount": "10.00", "currency": "USD" }
      ],
      "you_owe": [{ "friend": "Alex Wu", "friend_id": 3, "amount": "12.25", "currency": "USD" }],
      "totals": [{ "currency": "USD", "owed_to_you": "52.50", "you_owe": "12.25", "net": "40.25" }]
    }
  2. settle_up { "from": "Alex Kim", "to": "me" }. With no amount, it settles the full outstanding balance →

    { "recorded": "Alex Kim paid Riya Sharma 42.50 USD", "payment": { "id": 9999, "payment": true, "...": "..." } }

Claude: Alex Kim owes you $42.50 and Sam Patel owes you $10.00; you owe Alex Wu $12.25, so you're up $40.25 overall. I've recorded Alex Kim's $42.50 cash payment, so he's settled.

And when a name is ambiguous:

You: Split the $30 cab with Alex.

create_expense → error: "Alex" matches more than one person: Alex Kim (id 2), Alex Wu (id 3). Ask which one is meant, then pass the id or a fuller name.

Claude: You have two friends named Alex, Alex Kim and Alex Wu. Which one shared the cab?

Related MCP server: splitwise-mcp

Install

You need Node.js 20 or newer and a Splitwise API key.

Get an API key: sign in at secure.splitwise.com/apps, register an app (any name and URL will do for personal use), and copy the API key from the app page. The key acts as your account, so treat it like a password.

Claude Desktop

Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\):

{
  "mcpServers": {
    "splitwise": {
      "command": "npx",
      "args": ["-y", "github:prakhar083/splitwise-mcp"],
      "env": {
        "SPLITWISE_API_KEY": "your-api-key"
      }
    }
  }
}

Restart Claude Desktop.

Claude Code

claude mcp add --transport stdio --env SPLITWISE_API_KEY=your-api-key splitwise -- npx -y github:prakhar083/splitwise-mcp

Add --scope user to make it available in every project.

Cursor

Add to ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project):

{
  "mcpServers": {
    "splitwise": {
      "command": "npx",
      "args": ["-y", "github:prakhar083/splitwise-mcp"],
      "env": {
        "SPLITWISE_API_KEY": "your-api-key"
      }
    }
  }
}

Streamable HTTP

For clients that connect over HTTP instead of stdio:

SPLITWISE_API_KEY=your-api-key npx -y github:prakhar083/splitwise-mcp --http --port 3000
# MCP endpoint: http://127.0.0.1:3000/mcp

The HTTP server is stateless and binds to 127.0.0.1 by default, rejecting requests whose Host header is not loopback (DNS-rebinding defence). Set SPLITWISE_MCP_HTTP_TOKEN to require Authorization: Bearer <token>. The server refuses to bind to a non-loopback address such as --host 0.0.0.0 unless a token is set.

Tools

Tool

What it does

Writes

get_current_user

Your account: id, name, email, default currency.

list_groups

Groups with member names and your balance in each.

get_group

One group's members, their balances, and who owes whom inside it.

list_friends

Friends with your overall balance with each, per currency.

get_balances

Net who-owes-whom: friends who owe you, friends you owe, totals per currency. With group, the debts inside that group.

list_expenses

Expenses and payments, newest first. Filter by group, friend, dated_after, dated_before; page with limit / offset.

get_expense

One expense with every person's paid and owed share.

search_expenses

Finds expenses whose description or notes contain every query word (case- and accent-insensitive).

create_expense

Adds an expense. Group or non-group, any payer, split equal, exact or percentage.

yes

update_expense

Edits fields you pass. Changing only the cost rescales everyone's shares proportionally.

yes (destructive, idempotent)

delete_expense

Deletes an expense or payment.

yes (destructive, idempotent)

settle_up

Records a payment between two people. Omit amount to settle the full outstanding balance.

yes

Wherever a tool takes a person or group, it accepts an id or a name. Names match case- and accent-insensitively, in tiers: exact full name or email, then an exact first or last name, then prefixes ("alex k"), then substrings, then small typos for names longer than three letters ("jonathon", "patle"). The first tier with any match wins. If that tier has several matches, the tool returns an error listing them instead of picking one.

create_expense splits look like this:

{ "type": "equal" }                                   // all group members
{ "type": "equal", "participants": ["me", "Sam"] }    // just these people
{ "type": "exact", "shares": [{ "user": "me", "amount": "12.40" }, { "user": "Sam", "amount": "7.60" }] }
{ "type": "percentage", "shares": [{ "user": "me", "percent": 60 }, { "user": "Sam", "percent": 40 }] }

The payer (paid_by, default me) does not need to be one of the people sharing the cost.

Read-only mode

"env": { "SPLITWISE_API_KEY": "your-api-key", "SPLITWISE_READ_ONLY": "true" }

In read-only mode create_expense, update_expense, delete_expense and settle_up are never registered. The model cannot see them or call them, whatever the prompt says. Use this when you only want questions answered, or while you evaluate the server.

How split rounding works

A $100.00 bill split three ways cannot be $33.33 each: that totals $99.99. Splitwise rejects shares that don't add up to the cost, and silently fudging a cent is how ledgers drift. This server:

  1. Parses amounts as decimal strings into integer minor units ("100.00" USD → 10000n), using the currency's real precision from ICU: 2 decimals for USD and EUR, 0 for JPY and KRW, 3 for KWD and BHD. Input with more precision than the currency allows (10.005 USD) is an error, not a silent rounding. Ambiguous input like 1,5 is rejected rather than read as 1.5 or 15.

  2. Allocates with the largest-remainder method. Each person gets floor(total × weight / Σweights). The few leftover units go one each to the largest fractional remainders, with ties going to whoever is listed first.

So:

Split

Result

$100.00 equally, 3 people

33.34, 33.33, 33.33 (first listed absorbs the cent)

$10.01 equally, 3 people

3.34, 3.34, 3.33

$9.99 at 60% / 40%

5.99, 4.00 (40% has the larger remainder, 0.6 vs 0.4)

$100.00 at 33.3333 / 33.3333 / 33.3334 %

33.33, 33.33, 33.34

¥1000 equally, 3 people

334, 333, 333

Percentages must total exactly 100 (up to four decimal places); exact shares must total the cost to the minor unit, and the error says how far off they are (short by 0.50 USD). Editing only an expense's cost re-runs the same allocation using the existing shares as weights, so a 25/75 split stays 25/75.

The test suite checks these invariants with seeded, property-style tests over thousands of random totals, party sizes and weights: shares always sum to the total, equal shares never differ by more than one unit, and every share is within one unit of its exact proportion.

Errors

Splitwise failures come back as tool results the model can explain:

  • 401: the API key is wrong or revoked.

  • 403 with "Pro subscription": Splitwise requires an active Splitwise Pro subscription on the account that registered the API key for some API access. The error says so plainly, and confirms nothing was changed.

  • 403 otherwise: you are probably not a member of that group or expense.

  • 429: rate limited. Reads are retried once automatically when Retry-After is 10 seconds or less; otherwise the error includes the wait time. Writes are never retried automatically.

  • Validation errors: Splitwise often answers HTTP 200 with an errors object. These are surfaced field by field (Splitwise rejected the request: date: is not a date).

Configuration

Variable

Default

Purpose

SPLITWISE_API_KEY

(required)

Personal API key from secure.splitwise.com/apps.

SPLITWISE_READ_ONLY

false

true registers read tools only.

SPLITWISE_MCP_HTTP_TOKEN

(unset)

Bearer token required by --http. Mandatory for non-loopback binds.

SPLITWISE_BASE_URL

https://secure.splitwise.com/api/v3.0

Override the API base, e.g. for a proxy.

CLI flags: --http, --port <n> (default 3000 or $PORT), --host <addr> (default 127.0.0.1), --help, --version.

Security

  • The API key grants full access to your Splitwise account. Keep it in your MCP client's env config, not in prompts, repositories or shared dotfiles. If it leaks, delete the app at secure.splitwise.com/apps to revoke it.

  • The server only ever sends the key to Splitwise, as an Authorization: Bearer header over HTTPS. It does not log it and stores nothing on disk.

  • Tool results contain your financial data and go to whichever model your client uses. Use read-only mode if you don't want a model able to change anything.

  • In HTTP mode, anyone who can reach the endpoint acts as you. Keep it on loopback or set SPLITWISE_MCP_HTTP_TOKEN.

Development

git clone https://github.com/prakhar083/splitwise-mcp.git
cd splitwise-mcp
npm install
npm test            # vitest: unit tests plus an in-memory MCP client/server suite
npm run typecheck
npm run build       # emits dist/

The tests never touch the real Splitwise API: test/fixtures.ts serves a small fictional dataset through a mocked fetch.

To try a local build in a client, point it at node /absolute/path/to/splitwise-mcp/dist/index.js, or inspect it with the MCP Inspector:

SPLITWISE_API_KEY=your-api-key npx @modelcontextprotocol/inspector node dist/index.js

Layout:

src/
  index.ts          CLI: stdio or --http
  server.ts         createServer(): registers tools, honours read-only mode
  http.ts           Streamable HTTP transport with host and token checks
  money.ts          minor-unit parsing, formatting, largest-remainder allocation
  resolve.ts        fuzzy name resolution with disambiguation
  expenses.ts       split specs to Splitwise users__N__ shares
  format.ts         compact, model-friendly views of API objects
  tools/            read and write tool definitions
  splitwise/        typed v3.0 client and error mapping

License

MIT © 2026 Prakhar Vijay

Available Tools

12 tools
create_expenseCreate expenseA

Adds an expense to Splitwise. Choose a group (or omit it for an expense between you and friends), who paid (default: you), and how to split: equally, by exact amounts, or by percentages. People can be given by name or id. Amounts are computed in whole cents, so the shares always add up exactly to the cost. If a name is ambiguous the tool returns the candidates instead of guessing: ask the user which one.

NameRequiredDescriptionDefault
costYesTotal cost, e.g. "86.40".
dateNoWhen it happened. Defaults to now.
groupNoGroup to add the expense to. Omit for a non-group expense with friends.
notesNoOptional longer notes, stored as the expense details.
splitNoHow to divide the cost. "equal": among participants; leftover cents go to the first participants listed. "exact": explicit amounts per person. "percentage": percent per person; rounding goes to the largest remainders. Defaults to an equal split among all group members.
paid_byNoWho paid the whole cost. Defaults to "me".
descriptionYesWhat the expense was for, e.g. "Dinner at Nopa".
currency_codeNoISO 4217 code. Defaults to the user's default currency.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare a non-read-only, non-idempotent, non-destructive write, so the safety profile is covered. The description adds genuinely useful behavior the annotations cannot express: rounding is deterministic in whole cents so shares sum exactly, and ambiguous names return candidate matches instead of guessing, with an instruction to ask the user. It omits auth/permission requirements and whether other members are notified.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Five short sentences, front-loaded with the action, then the three main choices, then behavioral caveats. Nothing is padded, though the split-mode enumeration partially restates the schema's own enum descriptions.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an eight-parameter write tool with a nested split union schema and no output schema, the description covers what matters most: defaults, the group-vs-non-group branch, and the candidate-list return on ambiguous names. Currency and date defaults are left to the schema, which is acceptable given full schema coverage, but a note on whether repeated calls create duplicates would close the remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3 and the description does not have to compensate. It reinforces the group-omission case, the paid_by default, and the three split modes, but the detailed semantics (percent must total 100, exact shares must equal cost, leftover-cent allocation) already live in the schema, so the added value is marginal.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence gives a specific verb and resource ("Adds an expense to Splitwise"), which is enough to distinguish this from update_expense or delete_expense. It never names those siblings explicitly, so the differentiation rests on the verb alone rather than on stated contrast.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It resolves the main decision points an agent faces: include a group or omit it for a friend-to-friend expense, who paid (defaults to you), and which of three split modes to use. It stops short of saying when to prefer this over alternatives such as settle_up or update_expense, so it is clear context without exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_expenseDelete expenseA
DestructiveIdempotent

Deletes an expense or payment. Balances change immediately. Confirm with the user before calling; Splitwise can restore it from the web app if needed.

NameRequiredDescriptionDefault
expense_idYesThe Splitwise expense id.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint, idempotentHint and openWorldHint, so the safety profile is covered; the description goes further by disclosing the immediate balance recalculation side effect and the fact that Splitwise can restore a deleted record from the web app. That recovery path is genuinely useful context an agent cannot infer from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the action, then the side effect, then the confirmation requirement. No filler or redundant restatement of the name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter destructive tool with rich annotations and no output schema, this covers the essential risk information: immediate balance impact, user confirmation, and recoverability. The only mild ambiguity is whether expense_id also identifies a payment, given the description mentions both.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter, and the schema documents expense_id fully at 100% coverage, so the baseline is 3. The description adds no format or source hints beyond what the schema already says, but nothing is missing either.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Deletes an expense or payment") so the agent knows exactly what operation is performed. It doesn't explicitly contrast with the sibling update_expense, but the destructive framing separates it clearly enough in practice.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete precondition — "Confirm with the user before calling" — which is the key gating rule for this tool. It does not name alternatives such as update_expense for reversibility-preserving edits, so the routing guidance is clear but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_balancesGet balancesA
Read-only

Summarises who owes whom. Without a group: every friend with a non-zero balance, split into "owes_you" and "you_owe", plus net totals per currency. With a group: the debts between group members. Use this before settle_up to find the amount to settle.

NameRequiredDescriptionDefault
groupNoLimit to the debts inside this group (id or name).

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds real behavioral detail the annotations cannot: the response is split into "owes_you" and "you_owe", includes net totals per currency, and changes shape entirely when a group is supplied — important since there is no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core purpose, then the two modes, then the workflow cue. No filler and nothing redundant with the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-optional-parameter read tool with no output schema, the description covers both invocation modes and describes the returned structure well enough that an agent knows what it will get. Nothing needed to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaning beyond the schema by explaining the behavioral consequence of supplying vs. omitting the group parameter (per-friend net view vs. intra-group debts). It does not restate the id-or-name union, which the schema already documents.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Summarises who owes whom" gives a specific verb and resource, and the description then defines the exact two modes (all friends vs. inside one group). An agent can distinguish this from list_expenses, get_group, or settle_up without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: "Use this before settle_up to find the amount to settle," naming both the trigger and the downstream sibling. It lacks explicit when-not guidance or comparison to the list_* tools, which keeps it below a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_current_userGet current userA
Read-only

Returns the Splitwise account this server acts as: id, name, email and default currency. "me" in other tools refers to this user.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds value beyond them by naming the exact fields returned and by explaining the identity mapping that other tools depend on. It does not mention failure behavior when the server is unauthenticated, which keeps it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with what is returned, followed by the one piece of cross-tool context an agent actually needs. No filler or restatement of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-value burden and does so by enumerating the account fields. For a trivial read-only zero-argument tool this is nearly complete; only error/authentication edge cases are unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes no parameters, so the baseline is 4 and there is nothing for the description to compensate for. No misleading parameter language is present.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource ("Returns the Splitwise account this server acts as") and immediately enumerates what comes back: id, name, email, default currency. The second sentence ties the tool to the other siblings by defining that "me" in other tools resolves to this user, so an agent can place it precisely.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly signals when the tool is needed: whenever another tool's "me" identifier must be resolved to a concrete account. There are no explicit exclusions, but with zero parameters and no overlapping sibling (none of list_groups, get_expense, etc. return the acting account), there is little ambiguity left to resolve.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_expenseGet expenseA
Read-only

Returns one expense or payment by id, with every person's paid and owed share.

NameRequiredDescriptionDefault
expense_idYesThe Splitwise expense id.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds useful return content (each person's paid and owed share), which matters since there is no output schema, but it omits not-found behavior and any auth/permission context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the verb and resource, with the return-content clause appended. No redundant or filler wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read tool with no output schema, the description covers both the input (by id) and the shape of the response (per-person paid/owed shares). Only error/edge-case behavior is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single expense_id parameter is fully documented as the Splitwise expense id. The description's only added nuance is that a payment id may also be passed, which is a marginal gain over the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Returns one expense or payment by id") and the singular/id-based framing implicitly distinguishes it from list_expenses and search_expenses. It stops short of naming a sibling or exclusion explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: fetch a single record when you already have an id. There is no explicit statement of when to prefer this over list_expenses or search_expenses, and no mention of what happens for an unknown id.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_groupGet groupA
Read-only

Returns one group's members with their balances, plus the debts between members (simplified if the group has debt simplification on). Accepts a group id or name.

NameRequiredDescriptionDefault
groupYesA group: its Splitwise id or its name (case-insensitive, partial names work).

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds useful behavior beyond them: the result includes debts between members and these are simplified when the group has debt simplification enabled, meaning output shape varies per group. It says nothing about permissions, lookup failure behavior for unknown names, or ambiguities when a name matches multiple groups.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with the return content front-loaded and the conditional debt simplification in a parenthetical. The trailing 'Accepts a group id or name' is mild redundancy against the schema, but nothing else is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description carries the return-value explanation and does so well by enumerating members, balances, and debts. For a single-parameter read tool this is nearly sufficient; only the no-match/ambiguous-name behavior is left unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already documents that the group parameter accepts an id or case-insensitive partial name. The description's 'Accepts a group id or name' merely restates that, adding no extra meaning. Baseline 3 applies when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: it returns one group's members with balances plus inter-member debts, and notes the debt-simplification variation. The phrase 'one group's' signals it is the single-group counterpart to list_groups, though no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied — the description makes clear this is a single-group lookup, from which an agent can infer it follows list_groups. It gives no explicit when-to-use, when-not-to-use, or named alternative such as get_balances for cross-group balances.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_expensesList expensesA
Read-only

Lists expenses and payments, newest first. Filter by group, friend and date range. Each expense shows what every person paid and owes. Deleted expenses are hidden unless include_deleted is true.

NameRequiredDescriptionDefault
groupNoOnly expenses in this group (id or name).
limitNoMaximum number of expenses to return (1-100).
friendNoOnly expenses shared with this friend (id or name).
offsetNoSkip this many expenses, for paging.
dated_afterNoOnly expenses dated on or after this date (YYYY-MM-DD).
dated_beforeNoOnly expenses dated before this date (YYYY-MM-DD).
include_deletedNoInclude expenses that were deleted.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description goes beyond them by disclosing sort order ('newest first'), the content of each returned record ('what every person paid and owes'), and the default hiding of deleted records — genuine behavioral context an agent needs before calling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences with purpose front-loaded, then filters, then return content, then the one important default. No filler, no restatement of the name, and the most surprising behavior (hidden deleted records) is called out explicitly rather than buried.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with full schema coverage and annotations covering safety, this is close to complete: it covers purpose, filters, ordering, hidden-by-default semantics, and a sketch of the return shape in lieu of an output schema. Only the relationship to search_expenses is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so every parameter including limit/offset and the date formats is already documented, making 3 the baseline. The description adds only the default-hidden semantics of include_deleted, which is partly redundant with its schema description ('Include expenses that were deleted'), and says nothing extra about group/friend accepting either id or name.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource plus a behavioral detail ('Lists expenses and payments, newest first'), which distinguishes it from get_expense (single item) and create/update/delete siblings. It stops short of naming or contrasting with search_expenses, which is the closest alternative, so the differentiation is incomplete.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The filter set ('Filter by group, friend and date range') implies the browse/list use case, but there is no explicit statement of when to choose this over search_expenses or get_expense. The one true conditional it does give is 'Deleted expenses are hidden unless include_deleted is true', which is useful but does not double as usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_friendsList friendsA
Read-only

Lists the user's Splitwise friends with their overall balance with the user, per currency. A positive amount means the friend owes the user; negative means the user owes the friend.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds real semantic value beyond that: balances are aggregated per currency and the sign convention (positive = friend owes user, negative = user owes friend) is spelled out, which the agent cannot get from any structured field. It does not mention pagination, ordering, or rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the purpose and followed by the one piece of interpretation guidance an agent actually needs. Every sentence earns its place with no filler or restatement of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description is the only source of return-value information, and it covers only the balance figures and their sign. It says nothing about the other likely fields (friend id, name, email) that an agent would need to chain into create_expense or settle_up, leaving a meaningful gap for a zero-parameter listing tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, which is the baseline-4 case; there is nothing for the description to disambiguate. The description does not waste space re-explaining schema details and instead spends its words on output semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb+resource ("Lists the user's Splitwise friends") and names the payload (overall balance per currency), which clearly separates it from siblings like list_groups, list_expenses, and settle_up. It stops short of the 5 mark because it never distinguishes itself from get_balances, which plausibly overlaps on balance data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer this is the way to enumerate friends and obtain their balances, but the description never says when to prefer it over get_balances or when friend data is a prerequisite for other calls. No exclusions or alternatives are named, so routing depends on inference from the tool name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_groupsList groupsA
Read-only

Lists the user's Splitwise groups with member names and the user's own balance in each. A positive balance means the group owes the user; negative means the user owes the group.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds genuinely useful behavioral context beyond that: it discloses that member names accompany each group and, critically, the sign convention for balances (positive = group owes user, negative = user owes group). It omits nothing major for a zero-argument read, though it does not say whether all groups are always returned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero waste. The resource and returned fields come first, and the balance-sign interpretation follows because it is the one detail an agent could otherwise misread. No restatement of the name or title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no input schema and no output schema, the description carries the burden of explaining the return shape, and it does so at a useful level: groups, member names, per-user balance, and sign semantics. Only minor gaps remain, such as ordering or whether an empty list is possible.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes no parameters, so the baseline is 4; there is no parameter semantics to compensate for. The description correctly spends no words on inputs and instead explains output meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Lists the user's Splitwise groups") and enumerates the returned content: member names and the user's balance in each group. This implicitly separates it from the singular get_group sibling, though no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer this is the entry point for enumerating groups before calling get_group or list_expenses. There is no explicit when-to-use, when-not, or pointer to alternatives such as get_balances for aggregate totals.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_expensesSearch expensesA
Read-only

Finds expenses whose description or notes contain every word of the query (case- and accent-insensitive), e.g. "pizza" or "airbnb lisbon". Splitwise has no server-side search, so this scans recent expenses (newest first) up to scan_limit; narrow with group, friend or dates to search further back.

NameRequiredDescriptionDefault
groupNoOnly expenses in this group (id or name).
limitNoMaximum number of matches to return.
queryYesWords to look for in the description or notes.
friendNoOnly expenses shared with this friend (id or name).
scan_limitNoHow many recent expenses to scan before giving up.
dated_afterNoOnly expenses dated on or after this date (YYYY-MM-DD).
dated_beforeNoOnly expenses dated before this date (YYYY-MM-DD).

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond readOnlyHint and openWorldHint, it discloses client-side scanning, newest-first order, the scan_limit bound, and case- and accent-insensitive matching. This makes the potentially incomplete historical coverage and the reason for it visible before invocation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences front-load the purpose and matching behavior, then explain the non-obvious implementation constraint and its mitigation. The examples and operational details earn their space without filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a seven-parameter read-only search, it covers the essential matching, ordering, scope, and scan-bound behavior while the schema supplies defaults and formats. It would be slightly more complete if it explained how scan_limit exhaustion is represented in results, particularly because there is no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Despite 100% schema coverage, the description adds substantial meaning: query is an all-words normalized match with examples, scan_limit bounds a newest-first client-side scan, and filters help extend effective historical reach. It adds operational semantics rather than merely repeating schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

It specifies the verb, resource, searched fields, and all-word matching rule, clearly distinguishing keyword search from list_expenses and get_expense. The examples make the intended query style concrete.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly advises narrowing with group, friend, or dates when searching further back, providing actionable guidance for the scan limitation. It does not explicitly route unfiltered browsing or listing needs to list_expenses, so sibling-selection guidance is not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

settle_upSettle upA

Records a payment from one person to another (e.g. "Alex paid me back"). This does not move money; it records that money changed hands. Omit amount to settle the full outstanding balance: within the group if one is given, otherwise the overall balance between you and a friend.

NameRequiredDescriptionDefault
toYesWho received the money.
dateNoA date as YYYY-MM-DD, or an ISO 8601 timestamp.
fromYesWho paid (the person who owed money).
groupNoRecord the payment in this group.
notesNo
amountNoAmount paid. Omit to settle the whole outstanding balance.
currency_codeNoRequired if the balance spans several currencies.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this is a non-read-only, non-destructive, non-idempotent, open-world write. The description adds real value by clarifying the operation is record-only and does not transfer funds, plus the balance-settling semantics. It stops short of describing what happens if no outstanding balance exists, whether the record is reversible, or how identities are resolved.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core purpose, then the key caveat, then the balance-omission rule. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter mutation tool with no output schema, the description covers the essential behavioral nuance (record-only, full-balance settlement) that an agent needs to invoke it correctly. Minor gaps remain around error behavior and multi-currency requirements, which live partly in the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 86%, so the baseline is 3, but the description goes further by explaining the interaction between omitting 'amount' and the presence of 'group' — meaning that is not expressed in the schema. It does not clarify accepted identifier forms for 'from'/'to' beyond what the schema already says.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource ('Records a payment from one person to another') and disambiguates the concept with 'This does not move money; it records that money changed hands.' It does not explicitly name the nearest sibling (create_expense) as a contrasting option, so it falls short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives useful conditional guidance for the amount parameter: omit it to settle the full balance, scoped to a group if supplied, otherwise the overall friend balance. However, there is no guidance on when to choose settle_up versus create_expense or get_balances, and no stated preconditions or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_expenseUpdate expenseA
DestructiveIdempotent

Edits an existing expense. Only the fields you pass change. Changing the cost alone rescales everyone's shares proportionally; pass split to redistribute, or paid_by to change who paid. Read the expense with get_expense first so you can confirm the change with the user.

NameRequiredDescriptionDefault
costNoNew total cost.
dateNoA date as YYYY-MM-DD, or an ISO 8601 timestamp.
notesNoReplaces the expense notes.
splitNoHow to divide the cost. "equal": among participants; leftover cents go to the first participants listed. "exact": explicit amounts per person. "percentage": percent per person; rounding goes to the largest remainders. Omit to keep the current proportions.
paid_byNoWho paid the whole cost.
expense_idYesThe Splitwise expense id.
descriptionNo
currency_codeNo3-letter ISO 4217 currency code, e.g. USD, EUR, INR, JPY.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare this as a destructive, idempotent, open-world mutation. The description adds non-obvious behavioral context: partial updates, proportional share rescaling when cost changes alone, redistribution via split, payer changes via paid_by, and the recommended read-before-update flow.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences are front-loaded with the core behavior and parameter consequences. Every sentence provides useful guidance without unnecessary repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an eight-parameter mutation tool with no output schema, the description covers the key side effects, prerequisite read, and update semantics. It leaves return-value details and some less risky fields to the schema, which is adequate but not exhaustive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is high at 88%, so the schema carries most parameter detail. The description still adds meaningful cross-parameter semantics not captured in individual schema fields, especially that changing cost alone rescales shares and that split or paid_by must be used to redistribute or change the payer.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Edits an existing expense.' The word 'existing' distinguishes it from create_expense and delete_expense, and 'Only the fields you pass change' clarifies the update scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly tells the agent to 'Read the expense with get_expense first so you can confirm the change with the user,' which is a clear prerequisite. It also explains when to pass split versus paid_by, though it does not state explicit exclusions or when not to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 12 tool updatesv0.1.0
    • First observedcreate_expense
    • First observeddelete_expense
    • First observedget_balances
    • First observedget_current_user
    • First observedget_expense
    • First observedget_group
    • First observedlist_expenses
    • First observedlist_friends
    • First observedlist_groups
    • First observedsearch_expenses
    • First observedsettle_up
    • First observedupdate_expense

TDQS

A4/5.0

Scored across 12 tools

Disambiguation4/5

Each tool targets a distinct resource and action, and the descriptions actively steer usage (e.g. get_balances before settle_up, search_expenses for text lookup). There is mild overlap between list_expenses/search_expenses and between the balance information returned by list_groups, get_group and get_balances, but the boundaries remain clear enough to choose correctly.

Naming Consistency5/5

Eleven of twelve tools follow a strict verb_noun snake_case pattern (get_current_user, list_groups, get_group, list_friends, get_balances, list_expenses, get_expense, search_expenses, create_expense, update_expense, delete_expense). The single outlier, settle_up, is still a recognizable verb phrase and fits the domain naturally.

Tool Count5/5

Twelve tools is well within the sweet spot and each one has a clear job: identity, three read views of the social graph, three expense readers, full expense CRUD, and settle_up. Nothing feels redundant or padded.

Completeness4/5

The core lifecycle is covered end to end: read groups/friends/balances, search and read expenses, create/update/delete expenses, and record settlements. Gaps are secondary — there is no way to create a group, add or remove group members, add friends, or comment on an expense, so some workflows dead-end at the web app.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    A standalone MCP server that provides complete access to the Splitwise API, enabling natural language management of expenses, groups, friends, and notifications in MCP-compatible clients like Claude Desktop and VS Code Copilot.
    9
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables natural language management of Splitwise expenses, groups, and friends via the Model Context Protocol, with dual authentication and fuzzy name resolution.
    18
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    A lightweight MCP server that lets LLM clients track, query, and summarize personal expenses using a local SQLite database.
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Read-only MCP server for querying group expense splits and balances from a self-hosted receipt splitting app.
    -