Skip to main content
Glama
splitwise-mcp

splitwise-mcp

by chrischall

sw_create_expense

Destructive

Creates a Splitwise expense with equal or custom per-person splits, an optional receipt, and a confirmation preview before charges are posted.

Instructions

Create a Splitwise expense. Splits: split_equally:true (you paid, everyone in the group owes an equal part); split:"equal" with paid_by (someone — e.g. the other parent — paid, split equally among split_among or the whole group); or a users array for custom per-person splits (paid_share and owed_share as decimal strings like "25.00"). cost must be a decimal string. Pass category by name (or category_id); with neither, the most common category of similar expenses in the group is used and shown in the preview as inferred_category. The preview also lists possible_duplicates — expenses in the group, live or deleted, with the same cost, a similar description and a date within a day; check them before confirming. Pass receipt to attach an image or PDF in the same call. This puts charges on every participant's balance and notifies them. In sw_batch it produces expense_id. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

Input Schema

NameRequiredDescriptionDefault
costYesTotal cost as decimal string, e.g. "25.00"
dateNoISO 8601 datetime
splitNo"equal": paid_by paid the whole cost and everyone in split_among owes an equal part (odd cents go to the first participants). Use instead of split_equally (which always makes YOU the payer) or users.
usersNoCustom split (mutually exclusive with split_equally). Full list of participants required.
detailsNoNotes
paid_byNoWith split:"equal" — who paid: a user id, or a group member's name or email
receiptNoReceipt to attach: PNG, JPEG, GIF or PDF, up to 10 MiB. Give exactly one of upload_id, path or base64. The type is detected from the file contents. Replaces any receipt already on the expense.
categoryNoCategory by name, e.g. "Education" or "Medical expenses" (any case). Mutually exclusive with category_id. Omit both and the most common category of similar expenses in the group is used.
group_idYesGroup to add expense to (use 0 for no group)
category_idNoCategory id from sw_get_categories
descriptionYesShort description of the expense
split_amongNoWith split:"equal" — who shares the cost (ids, names or emails). Default: every group member.
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.
currency_codeNoCurrency code, e.g. "USD". Defaults to group/user default.
split_equallyNoSplit equally among group members (mutually exclusive with users)

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv3.7.0
    • changedInput schema / properties / receipt / properties / upload_id / description
      Previous value: -"The upload_id from sw_get_upload_url, after the file was PUT to its upload_url. The way to send a full-size file to the hosted server without base64."New value: +"The upload_id from sw_get_upload_url, after the file was PUT to its upload_url. The way to send a full-size file to the hosted server without base64. Single use: the upload is deleted once Splitwise has the receipt (the reply says upload_deleted); a failed or declined write keeps it, so the same upload_id can be retried."
  2. Changed8 schema fields changedv3.5.1
    • addedInput schema / properties / category
      Added value: +{
      +  "description": "Category by name, e.g. \"Education\" or \"Medical expenses\" (any case). Mutually exclusive with category_id. Omit both and the most common category of similar expenses in the group is used.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / paid_by
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "number"
      +    },
      +    {
      +      "minLength": 1,
      +      "type": "string"
      +    }
      +  ],
      +  "description": "With split:\"equal\" — who paid: a user id, or a group member's name or email"
      +}
    • changedInput schema / properties / receipt / description
      Previous value: -"Receipt to attach: PNG, JPEG, GIF or PDF, up to 10 MiB. Give exactly one of base64 or path. The type is detected from the file contents. Replaces any receipt already on the expense."New value: +"Receipt to attach: PNG, JPEG, GIF or PDF, up to 10 MiB. Give exactly one of upload_id, path or base64. The type is detected from the file contents. Replaces any receipt already on the expense."
    • changedInput schema / properties / receipt / properties / base64 / description
      Previous value: -"The file bytes, base64-encoded (a data: URL prefix is accepted and stripped). The normal way to pass a receipt."New value: +"The file bytes, base64-encoded (a data: URL prefix is accepted and stripped). Costs context for every byte — on the hosted server prefer upload_id."
    • changedInput schema / properties / receipt / properties / path / description
      Previous value: -"A file inside SPLITWISE_INPUT_DIR on the machine running this server (relative to it, or absolute). Only works when that variable is set — never on a hosted server; use base64 there."New value: +"A file inside SPLITWISE_INPUT_DIR on the machine running this server (relative to it, or absolute). Only works when that variable is set — never on a hosted server; use upload_id (or base64) there."
    • addedInput schema / properties / receipt / properties / upload_id
      Added value: +{
      +  "description": "The upload_id from sw_get_upload_url, after the file was PUT to its upload_url. The way to send a full-size file to the hosted server without base64.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / split
      Added value: +{
      +  "const": "equal",
      +  "description": "\"equal\": paid_by paid the whole cost and everyone in split_among owes an equal part (odd cents go to the first participants). Use instead of split_equally (which always makes YOU the payer) or users.",
      +  "type": "string"
      +}
    • addedInput schema / properties / split_among
      Added value: +{
      +  "description": "With split:\"equal\" — who shares the cost (ids, names or emails). Default: every group member.",
      +  "items": {
      +    "anyOf": [
      +      {
      +        "type": "number"
      +      },
      +      {
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    ]
      +  },
      +  "minItems": 1,
      +  "type": "array"
      +}
  3. Changed1 schema field changedv3.4.0
    • addedInput schema / properties / receipt
      Added value: +{
      +  "description": "Receipt to attach: PNG, JPEG, GIF or PDF, up to 10 MiB. Give exactly one of base64 or path. The type is detected from the file contents. Replaces any receipt already on the expense.",
      +  "properties": {
      +    "base64": {
      +      "description": "The file bytes, base64-encoded (a data: URL prefix is accepted and stripped). The normal way to pass a receipt.",
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "filename": {
      +      "description": "Name to store the file under, e.g. \"receipt.pdf\".",
      +      "maxLength": 200,
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "mime_type": {
      +      "description": "Optional. If given, it must match the type detected from the file contents.",
      +      "type": "string"
      +    },
      +    "path": {
      +      "description": "A file inside SPLITWISE_INPUT_DIR on the machine running this server (relative to it, or absolute). Only works when that variable is set — never on a hosted server; use base64 there.",
      +      "minLength": 1,
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "filename"
      +  ],
      +  "type": "object"
      +}
  4. Changed2 schema fields changedv3.2.0
    • removedInput schema / properties / confirm
      Removed value: -{
      -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
      -  "type": "boolean"
      -}
    • addedInput schema / properties / confirmToken
      Added value: +{
      +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
      +  "type": "string"
      +}
  5. Changed1 schema field changedv3.0.0
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
  6. First observedv2.1.5

TDQS

A4.6/5.0
Behavior5/5

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

Annotations declare destructive/openWorld, and the description adds the consequences that matter: charges land on every participant's balance and notify them, duplicates are surfaced before confirming, and the two-step confirmToken flow is spelled out. It also covers the sw_batch return value (expense_id) and the receipt-replace side effect.

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?

Front-loaded with the core action and split modes, then previews, then confirmation — a logical order with no filler sentences. It is dense to the point of being slightly run-on, and a clause or two (cost as decimal string, description) merely restates 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 15-parameter, nested-object mutation with no output schema, this covers what the caller needs: how splits compute, what the preview returns (inferred_category, possible_duplicates), receipt format and size limits, and the confirmation fallback. Nothing material about invoking it correctly is left undefined.

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 cross-field meaning the schema cannot express: the payer/splitter model behind split:'equal' with paid_by and split_among, the category-inference fallback when neither category nor category_id is given, and the confirmToken lifecycle. It does not add much on date, currency_code, or details beyond what the schema says.

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?

Opens with a specific verb+resource ('Create a Splitwise expense') and immediately enumerates the three split modes, which is what actually differentiates this call from a plain create. An agent can tell this apart from sw_update_expense or sw_create_group 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?

Gives explicit selection rules among the three split strategies and states mutual exclusivity ('Use instead of split_equally ... or users'), plus when to use path vs upload_id for receipts. It does not contrast with the sibling sw_update_expense or say when to attach a receipt in a separate call via sw_attach_receipt instead.

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