{"id":"380d2b30-5992-45cc-873e-a814ac9ab909","entityType":"agent","slug":"clawhub-chrischall-splitwise-mcp","name":"splitwise-mcp","canonicalUrl":"https://www.xpersona.co/agent/clawhub-chrischall-splitwise-mcp","canonicalPath":"/agent/clawhub-chrischall-splitwise-mcp","generatedAt":"2026-10-10T04:07:52.603Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T11:56:13.528Z","emptyReason":null},"description":"Access Splitwise expense and group data via MCP. Use when the user asks about Splitwise expenses, groups, friends, or balances, or wants to add, edit, or delete expenses. Triggers on phrases like \"add that expense to Splitwise\", \"split this with the vacation group\", \"make sure Meredith is in that group\", \"what do I owe\", or any request involving shared expenses or group management in Splitwise. Requires splitwise-mcp installed and the splitwise server registered (see Setup below).","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 2.7K downloads reported by the source. Last updated 10/9/2026.","installCommand":"clawhub skill install s17cjx1a349nz5apaqp02vgz4h85728z:splitwise-mcp","sourceUrl":"https://clawhub.ai/chrischall/splitwise-mcp","homepage":"https://clawhub.ai/chrischall/skills/splitwise-mcp","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/chrischall/splitwise-mcp","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/chrischall/skills/splitwise-mcp","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":69,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"splitwise-mcp technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-09T11:56:13.528Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T11:56:13.528Z","emptyReason":null},"stars":null,"forks":null,"downloads":2725,"packageName":null,"latestVersion":"3.3.0","tractionLabel":"2.7K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T11:56:13.528Z","emptyReason":null},"lastUpdatedAt":"2026-10-09T11:56:13.528Z","lastCrawledAt":"2026-10-09T11:56:13.528Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-10T11:56:13.528Z","lastVerifiedAt":null,"highlights":[{"version":"3.3.0","createdAt":"2026-10-07T13:46:52.629Z","changelog":"splitwise-mcp 3.3.0 - Updated documentation in SKILL.md. - Removed the skill-card.md file. - No functional or API changes; this release is focused solely on documentation cleanup.","fileCount":3,"zipByteSize":6201},{"version":"3.2.3","createdAt":"2026-10-05T02:51:23.472Z","changelog":"- Removed the file: skill-card.md - No changes to functionality or features; documentation update only.","fileCount":3,"zipByteSize":6118},{"version":"3.2.2","createdAt":"2026-10-03T01:45:00.935Z","changelog":"- Removed the file: skill-card.md - No functional changes to the skill or its documentation.","fileCount":3,"zipByteSize":6262},{"version":"3.2.1","createdAt":"2026-09-25T15:52:32.467Z","changelog":"- Removed the skill-card.md file. - No functionality, API, or user-facing changes.","fileCount":3,"zipByteSize":6212},{"version":"3.2.0","createdAt":"2026-09-24T15:12:07.481Z","changelog":"splitwise-mcp 3.2.0 - Removed the redundant skill-card.md file to reduce duplication. - No user-facing changes to functionality or setup. - Documentation remains detailed in SKILL.md, which is still present.","fileCount":3,"zipByteSize":6433},{"version":"3.1.2","createdAt":"2026-09-23T21:46:26.484Z","changelog":"- Removed the file skill-card.md. - No changes to functionality or configuration.","fileCount":3,"zipByteSize":6077},{"version":"3.1.1","createdAt":"2026-09-23T15:41:12.122Z","changelog":"- Removed the file skill-card.md. - No other changes to code or user-facing features.","fileCount":3,"zipByteSize":6013},{"version":"3.1.0","createdAt":"2026-09-20T03:00:50.296Z","changelog":"- Removed the file: skill-card.md - No user-facing functionality changes—this update only removes a documentation file.","fileCount":3,"zipByteSize":6143}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17cjx1a349nz5apaqp02vgz4h85728z:splitwise-mcp","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s17cjx1a349nz5apaqp02vgz4h85728z:splitwise-mcp` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/chrischall/splitwise-mcp before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-splitwise-mcp/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-splitwise-mcp/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-splitwise-mcp/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-splitwise-mcp/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-splitwise-mcp/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-splitwise-mcp/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T04:07:52.599Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-splitwise-mcp/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-splitwise-mcp/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-splitwise-mcp/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-splitwise-mcp/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T11:56:13.528Z","emptyReason":null},"readme":"Skill: splitwise-mcp\n\nOwner: chrischall\n\nSummary: Access Splitwise expense and group data via MCP. Use when the user asks about Splitwise expenses, groups, friends, or balances, or wants to add, edit, or delete expenses. Triggers on phrases like \"add that expense to Splitwise\", \"split this with the vacation group\", \"make sure Meredith is in that group\", \"what do I owe\", or any request involving shared expenses or group management in Splitwise. Requires splitwise-mcp installed and the splitwise server registered (see Setup below).\n\nTags: latest:3.3.0\n\nVersion history:\n\nv3.3.0 | 2026-10-07T13:46:52.629Z | auto\n\nsplitwise-mcp 3.3.0\n\n- Updated documentation in SKILL.md.\n- Removed the skill-card.md file.\n- No functional or API changes; this release is focused solely on documentation cleanup.\n\nv3.2.3 | 2026-10-05T02:51:23.472Z | auto\n\n- Removed the file: skill-card.md\n- No changes to functionality or features; documentation update only.\n\nv3.2.2 | 2026-10-03T01:45:00.935Z | auto\n\n- Removed the file: skill-card.md\n- No functional changes to the skill or its documentation.\n\nv3.2.1 | 2026-09-25T15:52:32.467Z | auto\n\n- Removed the skill-card.md file.\n- No functionality, API, or user-facing changes.\n\nv3.2.0 | 2026-09-24T15:12:07.481Z | auto\n\nsplitwise-mcp 3.2.0\n\n- Removed the redundant skill-card.md file to reduce duplication.\n- No user-facing changes to functionality or setup.\n- Documentation remains detailed in SKILL.md, which is still present.\n\nv3.1.2 | 2026-09-23T21:46:26.484Z | auto\n\n- Removed the file skill-card.md.\n- No changes to functionality or configuration.\n\nv3.1.1 | 2026-09-23T15:41:12.122Z | auto\n\n- Removed the file skill-card.md.\n- No other changes to code or user-facing features.\n\nv3.1.0 | 2026-09-20T03:00:50.296Z | auto\n\n- Removed the file: skill-card.md\n- No user-facing functionality changes—this update only removes a documentation file.\n\nv3.0.0 | 2026-09-17T23:38:20.367Z | auto\n\nsplitwise-mcp 3.0.0\n\n- Removed the skill-card.md file.\n- No functional or interface changes otherwise.\n\nv2.4.2 | 2026-09-10T17:58:24.273Z | auto\n\n- Removed the unused or redundant file: skill-card.md.\n- No changes to features or functionality.\n\nv2.4.1 | 2026-09-05T00:53:02.476Z | auto\n\n**Changelog for splitwise-mcp v2.4.1**\n\n- Added `view` parameter support to many tools, with `compact` as the default for leaner responses and improved usability.\n- Updated tools documentation to clarify default and full projection shapes, especially for person, group, and expense objects.\n- Added a new section explaining response shape handling (`view`) for all relevant tools.\n- Removed unused or redundant media/image fields from default responses to reduce large payload sizes.\n- Removed the `skill-card.md` file.\n\nv2.4.0 | 2026-09-04T22:24:56.430Z | auto\n\n- Removed sample skill card documentation file (skill-card.md).\n- No changes to functionality or CLI/API; update is documentation-related only.\n- All usage instructions, workflows, and tool descriptions remain up to date in SKILL.md.\n\nv2.3.0 | 2026-08-31T00:22:43.398Z | auto\n\n- Removed the `skill-card.md` file.\n- No changes to functionality or documentation other than file removal.\n\nv2.2.3 | 2026-08-28T21:07:59.307Z | auto\n\n- Removed sample file: skill-card.md\n- No functional changes to the skill or documentation content\n- Version 2.2.3 is a maintenance release with minor file cleanup\n\nv2.2.2 | 2026-08-28T11:35:05.438Z | auto\n\n- Removed the skill-card.md file from the project.\n- No user-facing changes to functionality or documentation.\n- Version bump to 2.2.2.\n\nv2.2.1 | 2026-08-22T21:56:29.408Z | auto\n\n- The `sw_get_receipt` tool now supports new options: `inline: true` returns receipt bytes for images and PDFs; `extract_text: true` extracts PDF text; default behavior writes the file and returns the path.\n- Updated documentation for `sw_get_receipt` and clarified that file paths returned are on the server's filesystem, with recommendations for hosted/containerised setups.\n- Removed redundant or outdated documentation file (`skill-card.md`).\n\nv2.2.0 | 2026-08-22T20:59:11.279Z | auto\n\n### splitwise-mcp 2.2.0\n\n- Added new tools: `sw_undelete_expense` to restore deleted expenses, and `sw_get_receipt` to download attached receipts for expenses.\n- Updated documentation to describe the new receipt and undeletion features, usage, and file handling details.\n- Removed the `skill-card.md` file.\n\nv2.1.6 | 2026-08-09T21:03:00.171Z | auto\n\n- Removed the file: skill-card.md\n- No changes to code or functionality; this update is documentation-only.\n\nv2.1.5 | 2026-07-27T21:15:48.047Z | auto\n\n- Removed the file: skill-card.md\n- No changes to functionality or documentation beyond file removal\n\nv2.1.4 | 2026-07-27T02:57:02.852Z | auto\n\n- Removed the file skill-card.md.\n- No changes to features or functionality.\n\nv2.1.3 | 2026-07-20T15:31:16.295Z | auto\n\n- Removed the file: skill-card.md\n- No other feature or documentation changes included in this version.\n\nv2.1.2 | 2026-07-19T14:55:20.281Z | auto\n\n- Removed the sample file skill-card.md.\n- No changes to functionality or documentation.\n\nv2.1.1 | 2026-07-19T12:46:49.848Z | auto\n\n- Removed the skill-card.md file.\n- No changes to functionality or APIs.\n- Documentation and setup instructions remain unchanged.\n\nv2.1.0 | 2026-07-14T17:53:58.981Z | auto\n\n- Removed the file: skill-card.md\n- No changes to the functionality or documentation in SKILL.md\n\nv2.0.12 | 2026-07-14T10:41:06.926Z | auto\n\n- Removed the file: skill-card.md.\n- No changes to functionality or documentation.\n\nv2.0.11 | 2026-07-07T23:41:14.801Z | auto\n\n- Removed the file: skill-card.md\n- No changes to functionality or documentation content.\n\nv2.0.10 | 2026-07-05T22:38:36.245Z | auto\n\n- Removed the file: skill-card.md\n- No changes to core functionality or documentation in SKILL.md\n\nv2.0.9 | 2026-06-13T00:54:40.774Z | auto\n\n- Removed the file \"skill-card.md\".\n- No changes to skill functionality, code, or documentation content.\n\nv2.0.8 | 2026-05-29T21:36:54.877Z | auto\n\n- Removed the file: skill-card.md\n- No changes to functionality or documentation.\n\nv2.0.7 | 2026-05-26T17:09:55.116Z | auto\n\nVersion 2.0.7 of splitwise-mcp\n\n- No functional or documentation changes detected in this release.\n- All previous features, setup instructions, and workflows remain unchanged.\n\nv2.0.3 | 2026-05-22T01:11:01.847Z | auto\n\n- Update: Expanded and clarified the documentation in SKILL.md, with new setup instructions, tool descriptions, and usage workflows.\n- Added clear trigger descriptions and use cases for Splitwise integration via MCP.\n- Detailed all available tools for managing users, groups, friends, and expenses.\n- Included practical examples for common workflows like adding expenses, managing groups, and custom splits.\n- Provided setup guidance for both npx and source installations, with API key authentication notes.\n\nArchive index:\n\nArchive v3.3.0: 3 files, 6201 bytes\n\nFiles: skill-card.md (1945b), SKILL.md (11498b), _meta.json (132b)\n\nFile v3.3.0:SKILL.md\n\n---\nname: splitwise-mcp\ndescription: Access Splitwise expense and group data via MCP. Use when the user asks about Splitwise expenses, groups, friends, or balances, or wants to add, edit, or delete expenses. Triggers on phrases like \"add that expense to Splitwise\", \"split this with the vacation group\", \"make sure Meredith is in that group\", \"what do I owe\", or any request involving shared expenses or group management in Splitwise. Requires splitwise-mcp installed and the splitwise server registered (see Setup below).\n---\n\n# splitwise-mcp\n\nMCP server for Splitwise — natural-language expense and group management via the Splitwise API.\n\n- **npm:** [npmjs.com/package/splitwise-mcp](https://www.npmjs.com/package/splitwise-mcp)\n- **Source:** [github.com/chrischall/splitwise-mcp](https://github.com/chrischall/splitwise-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"splitwise-mcp\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/splitwise-mcp\ncd splitwise-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/splitwise-mcp/dist/index.js\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `SPLITWISE_API_KEY=<value>`.\n\n### Getting your API key\n\n1. Go to [splitwise.com/apps/register](https://secure.splitwise.com/apps/register)\n2. Register an app (name and description can be anything)\n3. Copy the **API key** from the app detail page\n\n## Authentication\n\nAPI key auth — no login flow or token rotation. The key is attached to every request as `Authorization: Bearer <key>`.\n\n## Tools\n\n### User\n| Tool | Description |\n|------|-------------|\n| `sw_get_current_user(view?)` | Get the authenticated user's profile. On the default `compact` rung that is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; `first_name` / `last_name` separately are on `view: \"full\"` |\n\n### Groups\n| Tool | Description |\n|------|-------------|\n| `sw_list_groups(view?)` | List all groups with `id`, `name`, `group_type`, `members[]`, `simplified_debts` and `invite_link`. See [Response shape](#response-shape-view) — this is the response that does not fit at all on `full` |\n| `sw_get_group(id, view?)` | Get a single group's details including members and balances |\n| `sw_create_group(name, group_type?, simplify_by_default?)` | Create a new group (`group_type`: `apartment`, `house`, `trip`, `other`) |\n| `sw_add_user_to_group(group_id, user_id?)` | Add a user by `user_id` (preferred) or `first_name` + `last_name` + `email` |\n| `sw_remove_user_from_group(group_id, user_id)` | Remove a user from a group |\n\n### Friends\n| Tool | Description |\n|------|-------------|\n| `sw_list_friends(view?)` | List all friends. On the default `compact` rung each is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; the separate name fields are on `view: \"full\"` |\n\n### Expenses\n| Tool | Description |\n|------|-------------|\n| `sw_list_expenses(group_id?, friend_id?, dated_after?, dated_before?, limit?, offset?, view?)` | List or search expenses |\n| `sw_get_expense(id, view?)` | Get full details of a single expense |\n| `sw_create_expense(group_id, description, cost, split_equally? \\| users?)` | Create an expense — equal split or custom per-person split |\n| `sw_update_expense(expense_id, ...)` | Edit an existing expense (custom split requires full `users` array) |\n| `sw_delete_expense(id)` | Soft-delete an expense |\n| `sw_undelete_expense(id)` | Restore a soft-deleted expense |\n\n### Receipts\n| Tool | Description |\n|------|-------------|\n| `sw_get_receipt(id, size?, inline?, extract_text?, output_dir?, write?)` | Download the receipt attached to an expense. `inline: true` returns the bytes in the result (images **and** PDFs); `extract_text: true` returns a PDF's text layer; by default it also writes the file and returns the path |\n\n### Utilities\n| Tool | Description |\n|------|-------------|\n| `sw_get_notifications(view?)` | Recent activity feed for the current user |\n| `sw_get_categories` | Hierarchical list of expense categories (use `id` as `category_id`) |\n| `sw_get_currencies` | List of supported currency codes |\n\n## Response shape (`view`)\n\nNine read tools take `view: \"compact\" | \"full\"`, and **`compact` is the\ndefault** — you get the slim rung without asking. Two of them are not in the\ntable above: `sw_get_user(id, view?)` and `sw_get_comments(expense_id, view?)`.\n\nThis is not a nicety. A live `sw_list_groups` on a 51-group account came back\nas **192,123 characters and was REFUSED by the host before the model saw a byte\nof it** — the tool was not expensive, it was unusable. 60% of that response was\nimage URLs: `avatar` + `tall_avatar` + `cover_photo` (51.7 KB) and a `picture`\nobject per member across 51 groups (37.7 KB). Stripping media alone takes it to\n51.4 KB (−73%); the field projections below take it to 29.3 KB.\n\n**Compact means two different things here, depending on the tool.**\n\n**A hand-written field projection** — `sw_list_groups`, `sw_get_group`,\n`sw_list_friends`, `sw_get_current_user`, `sw_get_user`, `sw_list_expenses`,\n`sw_get_expense`:\n\n- **A person becomes `{id, name, email, registration_status, balance}`, and\n  `name` is `first_name` + `last_name` JOINED.** This is the one that will trip\n  you: reach for `last_name` on the default rung and it is not there. `balance`\n  survives because it is the whole reason to look a person up, and\n  `registration_status` because it is how you know an invite was never\n  accepted.\n- **A group keeps** `{id, name, group_type, updated_at, members[],\n  simplified_debts, invite_link}`. The whiteboard fields and the\n  `simplify_by_default` / `custom_avatar` / `group_reminders` settings go —\n  nothing here reads them. `original_debts` goes because `simplified_debts`\n  answers \"who owes whom\", and the two differ only when simplification is on;\n  `full` has both.\n- **An expense keeps the share breakdown**, as `{id, name, paid_share,\n  owed_share, net_balance}` per person rather than Splitwise's nested `user`\n  object, plus `repayments`, `comments_count` and `category` as a name. Two\n  details matter: `deleted_at` is kept **only when set**, because a deleted\n  expense still comes back from the list endpoint and a caller who cannot see\n  it will count it; and the receipt becomes `has_receipt: true` — the bytes\n  come from `sw_get_receipt`. The eleven-field repeat/reminder/transaction\n  block goes (`repeats`, `next_repeat`, `transaction_status`, …) — it was\n  `false` / `null` / `\"offline\"` on every expense in a live account.\n\n**Media stripping, with no field projection claimed** — `sw_get_notifications`\nand `sw_get_comments`. Compact drops the avatar URLs and touches nothing else.\nDo not expect a named field set from these two; expect the same records minus\nthe pictures.\n\n`view: \"full\"` returns Splitwise's records untouched, everywhere. There is **no\n`raw` rung**: `full` already IS the upstream payload, so a third value could\nonly alias it.\n\n**A projection that trips returns the rows WHOLE**, and for the entire array\nrather than per record — one odd record projected to nothing among fifty good\nones is a hole in the middle of an answer, and indistinguishable from an\nexpense with no content. So a fat response is a possible outcome; a quietly\ngappy one is not.\n\nThe other eighteen tools take no `view`, each for its own reason:\n\n- **`sw_get_receipt`** is the one tool the media rung is documented never to\n  touch: its PRODUCT is the image. Stripping there would not shrink the answer,\n  it would delete it.\n- **`sw_get_categories` and `sw_get_currencies`** are static reference lists —\n  already narrow, no media, and every field on them is the answer.\n- **`sw_healthcheck`** answers reachability and auth.\n- **The fourteen writes** (`sw_create_expense`, `sw_update_expense`,\n  `sw_delete_expense`, `sw_undelete_expense`, `sw_create_group`,\n  `sw_delete_group`, `sw_undelete_group`, `sw_add_user_to_group`,\n  `sw_remove_user_from_group`, `sw_create_friend`, `sw_delete_friend`,\n  `sw_create_comment`, `sw_delete_comment`, `sw_update_user`) return receipts —\n  an id, a status — with nothing to strip and everything to keep.\n\n## Workflows\n\n**Add an expense to a group:**\n```\nsw_list_groups → find group ID for \"vacation\"\nsw_create_expense(group_id, \"Dinner\", \"80.00\", split_equally: true)\n```\n\n**Add someone to a group:**\n```\nsw_list_friends → find Meredith's user_id\nsw_get_group(id) → check if Meredith is already in members[]\nsw_add_user_to_group(group_id, user_id) → if not\n```\n\n**Custom split (you paid, split 60/40):**\n```\nsw_get_current_user → your user_id\nsw_list_friends → other person's user_id\nsw_create_expense(group_id, \"Hotel\", \"200.00\", users: [\n  { user_id: yours, paid_share: \"200.00\", owed_share: \"120.00\" },\n  { user_id: theirs, paid_share: \"0.00\", owed_share: \"80.00\" }\n])\n```\n\n**Get the receipt for an expense:**\n```\nsw_list_expenses(...) → find expense ID\nsw_get_receipt(id, extract_text: true) → line items and totals as text\nsw_get_receipt(id, inline: true)       → the actual bytes, when you need to see it\nsw_get_receipt(id)                     → writes e.g. ./splitwise-receipt-4644814211.pdf\n```\n\n**Search and edit an expense:**\n```\nsw_list_expenses(group_id, dated_after: \"2026-01-01\") → find expense ID\nsw_update_expense(expense_id, description: \"Corrected description\", cost: \"95.00\")\n```\n\n## Notes\n\n- Every write except `sw_undelete_expense` / `sw_undelete_group` asks the user to confirm first. Where the client can show a prompt, it does (unless the server sets `MCP_CONFIRM_ELICITATION=off`). Otherwise the first call changes nothing and returns `status: \"confirmation-required\"` with a `preview` (method, path, `willSend`) and a `confirmToken`: show the preview to the user, get their approval in chat, then repeat the same call with the same arguments plus `confirmToken` (see `MCP_CONFIRM_MODE`). A token acts once, expires, and is refused (`DRAFT_CHANGED`) if any argument changed\n- `cost` is always a decimal string (e.g. `\"25.00\"`)\n- `split_equally: true` and `users` array are mutually exclusive\n- For custom split updates, the **full `users` array is required** — the API replaces the entire split\n- `sw_delete_expense` is a soft delete — restore with `sw_undelete_expense`\n- The `receipt.original` / `receipt.large` URLs on an expense are **not public** — fetching them without the API key returns 401. Always use `sw_get_receipt`, which fetches them with the server's own credentials\n- `sw_get_receipt` writes into `output_dir`, else `$SPLITWISE_OUTPUT_DIR`, else the working directory, and never overwrites an existing file\n- That path is on the **server's** filesystem. If you can't read it — a hosted or containerised server — use `inline: true` (bytes) or `extract_text: true` (PDF text) instead of the path\n- `extract_text` only works on PDFs, and only when the PDF has a text layer; a scanned or photographed receipt returns `text_note` instead, and needs `inline: true` to read\n- API default for `sw_list_expenses` is 20 results when `limit` is omitted\n\nFile v3.3.0:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"splitwise-mcp\",\n  \"version\": \"3.3.0\",\n  \"publishedAt\": 1791380812629\n}\n\nFile v3.3.0:skill-card.md\n\n## Description:\n\nHelps agents use Splitwise to check balances, groups, friends, and expenses and manage shared-expense records through MCP.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nPeople and agents managing shared expenses use this skill to review Splitwise balances and records, add or edit expenses, manage groups and friends, and retrieve receipts.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The installed package receives a Splitwise API key and can read account balances, friends, expenses, and receipts.\n\nMitigation: Confirm that you trust the package before providing it with your Splitwise API key.\n\nRisk: Approved write actions can create, change, delete, or restore Splitwise records.\n\nMitigation: Review the proposed changes and approve writes only when they match your intent.\n\nRisk: Receipt retrieval can save files to the server filesystem.\n\nMitigation: Use inline receipt or text extraction modes when you do not want receipt files saved on the server.\n\n## Reference(s):\n\n- [ClawHub skill listing](https://clawhub.ai/chrischall/skills/splitwise-mcp)\n- [splitwise-mcp npm package](https://www.npmjs.com/package/splitwise-mcp)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, Configuration instructions, Shell commands, MCP tool calls]\n\n**Output Format:** [Markdown with JSON and shell examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Tool results can include Splitwise account data and receipts.]\n\n## Skill Version(s):\n\n3.3.0 (source: ClawHub release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.2.3: 3 files, 6118 bytes\n\nFiles: skill-card.md (1810b), SKILL.md (11443b), _meta.json (132b)\n\nFile v3.2.3:SKILL.md\n\n---\nname: splitwise-mcp\ndescription: Access Splitwise expense and group data via MCP. Use when the user asks about Splitwise expenses, groups, friends, or balances, or wants to add, edit, or delete expenses. Triggers on phrases like \"add that expense to Splitwise\", \"split this with the vacation group\", \"make sure Meredith is in that group\", \"what do I owe\", or any request involving shared expenses or group management in Splitwise. Requires splitwise-mcp installed and the splitwise server registered (see Setup below).\n---\n\n# splitwise-mcp\n\nMCP server for Splitwise — natural-language expense and group management via the Splitwise API.\n\n- **npm:** [npmjs.com/package/splitwise-mcp](https://www.npmjs.com/package/splitwise-mcp)\n- **Source:** [github.com/chrischall/splitwise-mcp](https://github.com/chrischall/splitwise-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"splitwise-mcp\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/splitwise-mcp\ncd splitwise-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/splitwise-mcp/dist/index.js\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `SPLITWISE_API_KEY=<value>`.\n\n### Getting your API key\n\n1. Go to [splitwise.com/apps/register](https://secure.splitwise.com/apps/register)\n2. Register an app (name and description can be anything)\n3. Copy the **API key** from the app detail page\n\n## Authentication\n\nAPI key auth — no login flow or token rotation. The key is attached to every request as `Authorization: Bearer <key>`.\n\n## Tools\n\n### User\n| Tool | Description |\n|------|-------------|\n| `sw_get_current_user(view?)` | Get the authenticated user's profile. On the default `compact` rung that is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; `first_name` / `last_name` separately are on `view: \"full\"` |\n\n### Groups\n| Tool | Description |\n|------|-------------|\n| `sw_list_groups(view?)` | List all groups with `id`, `name`, `group_type`, `members[]`, `simplified_debts` and `invite_link`. See [Response shape](#response-shape-view) — this is the response that does not fit at all on `full` |\n| `sw_get_group(id, view?)` | Get a single group's details including members and balances |\n| `sw_create_group(name, group_type?, simplify_by_default?)` | Create a new group (`group_type`: `apartment`, `house`, `trip`, `other`) |\n| `sw_add_user_to_group(group_id, user_id?)` | Add a user by `user_id` (preferred) or `first_name` + `last_name` + `email` |\n| `sw_remove_user_from_group(group_id, user_id)` | Remove a user from a group |\n\n### Friends\n| Tool | Description |\n|------|-------------|\n| `sw_list_friends(view?)` | List all friends. On the default `compact` rung each is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; the separate name fields are on `view: \"full\"` |\n\n### Expenses\n| Tool | Description |\n|------|-------------|\n| `sw_list_expenses(group_id?, friend_id?, dated_after?, dated_before?, limit?, offset?, view?)` | List or search expenses |\n| `sw_get_expense(id, view?)` | Get full details of a single expense |\n| `sw_create_expense(group_id, description, cost, split_equally? \\| users?)` | Create an expense — equal split or custom per-person split |\n| `sw_update_expense(expense_id, ...)` | Edit an existing expense (custom split requires full `users` array) |\n| `sw_delete_expense(id)` | Soft-delete an expense |\n| `sw_undelete_expense(id)` | Restore a soft-deleted expense |\n\n### Receipts\n| Tool | Description |\n|------|-------------|\n| `sw_get_receipt(id, size?, inline?, extract_text?, output_dir?, write?)` | Download the receipt attached to an expense. `inline: true` returns the bytes in the result (images **and** PDFs); `extract_text: true` returns a PDF's text layer; by default it also writes the file and returns the path |\n\n### Utilities\n| Tool | Description |\n|------|-------------|\n| `sw_get_notifications(view?)` | Recent activity feed for the current user |\n| `sw_get_categories` | Hierarchical list of expense categories (use `id` as `category_id`) |\n| `sw_get_currencies` | List of supported currency codes |\n\n## Response shape (`view`)\n\nNine read tools take `view: \"compact\" | \"full\"`, and **`compact` is the\ndefault** — you get the slim rung without asking. Two of them are not in the\ntable above: `sw_get_user(id, view?)` and `sw_get_comments(expense_id, view?)`.\n\nThis is not a nicety. A live `sw_list_groups` on a 51-group account came back\nas **192,123 characters and was REFUSED by the host before the model saw a byte\nof it** — the tool was not expensive, it was unusable. 60% of that response was\nimage URLs: `avatar` + `tall_avatar` + `cover_photo` (51.7 KB) and a `picture`\nobject per member across 51 groups (37.7 KB). Stripping media alone takes it to\n51.4 KB (−73%); the field projections below take it to 29.3 KB.\n\n**Compact means two different things here, depending on the tool.**\n\n**A hand-written field projection** — `sw_list_groups`, `sw_get_group`,\n`sw_list_friends`, `sw_get_current_user`, `sw_get_user`, `sw_list_expenses`,\n`sw_get_expense`:\n\n- **A person becomes `{id, name, email, registration_status, balance}`, and\n  `name` is `first_name` + `last_name` JOINED.** This is the one that will trip\n  you: reach for `last_name` on the default rung and it is not there. `balance`\n  survives because it is the whole reason to look a person up, and\n  `registration_status` because it is how you know an invite was never\n  accepted.\n- **A group keeps** `{id, name, group_type, updated_at, members[],\n  simplified_debts, invite_link}`. The whiteboard fields and the\n  `simplify_by_default` / `custom_avatar` / `group_reminders` settings go —\n  nothing here reads them. `original_debts` goes because `simplified_debts`\n  answers \"who owes whom\", and the two differ only when simplification is on;\n  `full` has both.\n- **An expense keeps the share breakdown**, as `{id, name, paid_share,\n  owed_share, net_balance}` per person rather than Splitwise's nested `user`\n  object, plus `repayments`, `comments_count` and `category` as a name. Two\n  details matter: `deleted_at` is kept **only when set**, because a deleted\n  expense still comes back from the list endpoint and a caller who cannot see\n  it will count it; and the receipt becomes `has_receipt: true` — the bytes\n  come from `sw_get_receipt`. The eleven-field repeat/reminder/transaction\n  block goes (`repeats`, `next_repeat`, `transaction_status`, …) — it was\n  `false` / `null` / `\"offline\"` on every expense in a live account.\n\n**Media stripping, with no field projection claimed** — `sw_get_notifications`\nand `sw_get_comments`. Compact drops the avatar URLs and touches nothing else.\nDo not expect a named field set from these two; expect the same records minus\nthe pictures.\n\n`view: \"full\"` returns Splitwise's records untouched, everywhere. There is **no\n`raw` rung**: `full` already IS the upstream payload, so a third value could\nonly alias it.\n\n**A projection that trips returns the rows WHOLE**, and for the entire array\nrather than per record — one odd record projected to nothing among fifty good\nones is a hole in the middle of an answer, and indistinguishable from an\nexpense with no content. So a fat response is a possible outcome; a quietly\ngappy one is not.\n\nThe other eighteen tools take no `view`, each for its own reason:\n\n- **`sw_get_receipt`** is the one tool the media rung is documented never to\n  touch: its PRODUCT is the image. Stripping there would not shrink the answer,\n  it would delete it.\n- **`sw_get_categories` and `sw_get_currencies`** are static reference lists —\n  already narrow, no media, and every field on them is the answer.\n- **`sw_healthcheck`** answers reachability and auth.\n- **The fourteen writes** (`sw_create_expense`, `sw_update_expense`,\n  `sw_delete_expense`, `sw_undelete_expense`, `sw_create_group`,\n  `sw_delete_group`, `sw_undelete_group`, `sw_add_user_to_group`,\n  `sw_remove_user_from_group`, `sw_create_friend`, `sw_delete_friend`,\n  `sw_create_comment`, `sw_delete_comment`, `sw_update_user`) return receipts —\n  an id, a status — with nothing to strip and everything to keep.\n\n## Workflows\n\n**Add an expense to a group:**\n```\nsw_list_groups → find group ID for \"vacation\"\nsw_create_expense(group_id, \"Dinner\", \"80.00\", split_equally: true)\n```\n\n**Add someone to a group:**\n```\nsw_list_friends → find Meredith's user_id\nsw_get_group(id) → check if Meredith is already in members[]\nsw_add_user_to_group(group_id, user_id) → if not\n```\n\n**Custom split (you paid, split 60/40):**\n```\nsw_get_current_user → your user_id\nsw_list_friends → other person's user_id\nsw_create_expense(group_id, \"Hotel\", \"200.00\", users: [\n  { user_id: yours, paid_share: \"200.00\", owed_share: \"120.00\" },\n  { user_id: theirs, paid_share: \"0.00\", owed_share: \"80.00\" }\n])\n```\n\n**Get the receipt for an expense:**\n```\nsw_list_expenses(...) → find expense ID\nsw_get_receipt(id, extract_text: true) → line items and totals as text\nsw_get_receipt(id, inline: true)       → the actual bytes, when you need to see it\nsw_get_receipt(id)                     → writes e.g. ./splitwise-receipt-4644814211.pdf\n```\n\n**Search and edit an expense:**\n```\nsw_list_expenses(group_id, dated_after: \"2026-01-01\") → find expense ID\nsw_update_expense(expense_id, description: \"Corrected description\", cost: \"95.00\")\n```\n\n## Notes\n\n- Every write except `sw_undelete_expense` / `sw_undelete_group` asks the user to confirm first. Where the client can show a prompt, it does. Otherwise the first call changes nothing and returns `status: \"confirmation-required\"` with a `preview` (method, path, `willSend`) and a `confirmToken`: show the preview to the user, get their approval in chat, then repeat the same call with the same arguments plus `confirmToken` (see `MCP_CONFIRM_MODE`). A token acts once, expires, and is refused (`DRAFT_CHANGED`) if any argument changed\n- `cost` is always a decimal string (e.g. `\"25.00\"`)\n- `split_equally: true` and `users` array are mutually exclusive\n- For custom split updates, the **full `users` array is required** — the API replaces the entire split\n- `sw_delete_expense` is a soft delete — restore with `sw_undelete_expense`\n- The `receipt.original` / `receipt.large` URLs on an expense are **not public** — fetching them without the API key returns 401. Always use `sw_get_receipt`, which fetches them with the server's own credentials\n- `sw_get_receipt` writes into `output_dir`, else `$SPLITWISE_OUTPUT_DIR`, else the working directory, and never overwrites an existing file\n- That path is on the **server's** filesystem. If you can't read it — a hosted or containerised server — use `inline: true` (bytes) or `extract_text: true` (PDF text) instead of the path\n- `extract_text` only works on PDFs, and only when the PDF has a text layer; a scanned or photographed receipt returns `text_note` instead, and needs `inline: true` to read\n- API default for `sw_list_expenses` is 20 results when `limit` is omitted\n\nFile v3.2.3:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"splitwise-mcp\",\n  \"version\": \"3.2.3\",\n  \"publishedAt\": 1791168683472\n}\n\nFile v3.2.3:skill-card.md\n\n## Description:\n\nHelps agents read and manage Splitwise expenses, groups, friends, and balances through MCP.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nPeople and teams using Splitwise can ask an agent to review balances and shared expenses, manage groups and friends, and make approved changes to expense records.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Access to sensitive Splitwise financial data and account credentials.\n\nMitigation: Install only for intended account access, review the package, and safeguard the Splitwise API key.\n\nRisk: Expense, group, friend, comment, or user changes may alter shared records.\n\nMitigation: Review the proposed changes with the user and obtain confirmation before approving writes.\n\n## Reference(s):\n\n- [ClawHub skill release](https://clawhub.ai/chrischall/skills/splitwise-mcp)\n- [splitwise-mcp npm package](https://www.npmjs.com/package/splitwise-mcp)\n- [Splitwise API key registration](https://secure.splitwise.com/apps/register)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Configuration instructions, Shell commands]\n\n**Output Format:** [Markdown with optional JSON configuration and Splitwise tool results]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May include expense details, balances, group information, and receipts on request.]\n\n## Skill Version(s):\n\n3.2.3 (source: server-resolved release)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.2.2: 3 files, 6262 bytes\n\nFiles: skill-card.md (2193b), SKILL.md (11443b), _meta.json (132b)\n\nFile v3.2.2:SKILL.md\n\n---\nname: splitwise-mcp\ndescription: Access Splitwise expense and group data via MCP. Use when the user asks about Splitwise expenses, groups, friends, or balances, or wants to add, edit, or delete expenses. Triggers on phrases like \"add that expense to Splitwise\", \"split this with the vacation group\", \"make sure Meredith is in that group\", \"what do I owe\", or any request involving shared expenses or group management in Splitwise. Requires splitwise-mcp installed and the splitwise server registered (see Setup below).\n---\n\n# splitwise-mcp\n\nMCP server for Splitwise — natural-language expense and group management via the Splitwise API.\n\n- **npm:** [npmjs.com/package/splitwise-mcp](https://www.npmjs.com/package/splitwise-mcp)\n- **Source:** [github.com/chrischall/splitwise-mcp](https://github.com/chrischall/splitwise-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"splitwise-mcp\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/splitwise-mcp\ncd splitwise-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/splitwise-mcp/dist/index.js\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `SPLITWISE_API_KEY=<value>`.\n\n### Getting your API key\n\n1. Go to [splitwise.com/apps/register](https://secure.splitwise.com/apps/register)\n2. Register an app (name and description can be anything)\n3. Copy the **API key** from the app detail page\n\n## Authentication\n\nAPI key auth — no login flow or token rotation. The key is attached to every request as `Authorization: Bearer <key>`.\n\n## Tools\n\n### User\n| Tool | Description |\n|------|-------------|\n| `sw_get_current_user(view?)` | Get the authenticated user's profile. On the default `compact` rung that is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; `first_name` / `last_name` separately are on `view: \"full\"` |\n\n### Groups\n| Tool | Description |\n|------|-------------|\n| `sw_list_groups(view?)` | List all groups with `id`, `name`, `group_type`, `members[]`, `simplified_debts` and `invite_link`. See [Response shape](#response-shape-view) — this is the response that does not fit at all on `full` |\n| `sw_get_group(id, view?)` | Get a single group's details including members and balances |\n| `sw_create_group(name, group_type?, simplify_by_default?)` | Create a new group (`group_type`: `apartment`, `house`, `trip`, `other`) |\n| `sw_add_user_to_group(group_id, user_id?)` | Add a user by `user_id` (preferred) or `first_name` + `last_name` + `email` |\n| `sw_remove_user_from_group(group_id, user_id)` | Remove a user from a group |\n\n### Friends\n| Tool | Description |\n|------|-------------|\n| `sw_list_friends(view?)` | List all friends. On the default `compact` rung each is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; the separate name fields are on `view: \"full\"` |\n\n### Expenses\n| Tool | Description |\n|------|-------------|\n| `sw_list_expenses(group_id?, friend_id?, dated_after?, dated_before?, limit?, offset?, view?)` | List or search expenses |\n| `sw_get_expense(id, view?)` | Get full details of a single expense |\n| `sw_create_expense(group_id, description, cost, split_equally? \\| users?)` | Create an expense — equal split or custom per-person split |\n| `sw_update_expense(expense_id, ...)` | Edit an existing expense (custom split requires full `users` array) |\n| `sw_delete_expense(id)` | Soft-delete an expense |\n| `sw_undelete_expense(id)` | Restore a soft-deleted expense |\n\n### Receipts\n| Tool | Description |\n|------|-------------|\n| `sw_get_receipt(id, size?, inline?, extract_text?, output_dir?, write?)` | Download the receipt attached to an expense. `inline: true` returns the bytes in the result (images **and** PDFs); `extract_text: true` returns a PDF's text layer; by default it also writes the file and returns the path |\n\n### Utilities\n| Tool | Description |\n|------|-------------|\n| `sw_get_notifications(view?)` | Recent activity feed for the current user |\n| `sw_get_categories` | Hierarchical list of expense categories (use `id` as `category_id`) |\n| `sw_get_currencies` | List of supported currency codes |\n\n## Response shape (`view`)\n\nNine read tools take `view: \"compact\" | \"full\"`, and **`compact` is the\ndefault** — you get the slim rung without asking. Two of them are not in the\ntable above: `sw_get_user(id, view?)` and `sw_get_comments(expense_id, view?)`.\n\nThis is not a nicety. A live `sw_list_groups` on a 51-group account came back\nas **192,123 characters and was REFUSED by the host before the model saw a byte\nof it** — the tool was not expensive, it was unusable. 60% of that response was\nimage URLs: `avatar` + `tall_avatar` + `cover_photo` (51.7 KB) and a `picture`\nobject per member across 51 groups (37.7 KB). Stripping media alone takes it to\n51.4 KB (−73%); the field projections below take it to 29.3 KB.\n\n**Compact means two different things here, depending on the tool.**\n\n**A hand-written field projection** — `sw_list_groups`, `sw_get_group`,\n`sw_list_friends`, `sw_get_current_user`, `sw_get_user`, `sw_list_expenses`,\n`sw_get_expense`:\n\n- **A person becomes `{id, name, email, registration_status, balance}`, and\n  `name` is `first_name` + `last_name` JOINED.** This is the one that will trip\n  you: reach for `last_name` on the default rung and it is not there. `balance`\n  survives because it is the whole reason to look a person up, and\n  `registration_status` because it is how you know an invite was never\n  accepted.\n- **A group keeps** `{id, name, group_type, updated_at, members[],\n  simplified_debts, invite_link}`. The whiteboard fields and the\n  `simplify_by_default` / `custom_avatar` / `group_reminders` settings go —\n  nothing here reads them. `original_debts` goes because `simplified_debts`\n  answers \"who owes whom\", and the two differ only when simplification is on;\n  `full` has both.\n- **An expense keeps the share breakdown**, as `{id, name, paid_share,\n  owed_share, net_balance}` per person rather than Splitwise's nested `user`\n  object, plus `repayments`, `comments_count` and `category` as a name. Two\n  details matter: `deleted_at` is kept **only when set**, because a deleted\n  expense still comes back from the list endpoint and a caller who cannot see\n  it will count it; and the receipt becomes `has_receipt: true` — the bytes\n  come from `sw_get_receipt`. The eleven-field repeat/reminder/transaction\n  block goes (`repeats`, `next_repeat`, `transaction_status`, …) — it was\n  `false` / `null` / `\"offline\"` on every expense in a live account.\n\n**Media stripping, with no field projection claimed** — `sw_get_notifications`\nand `sw_get_comments`. Compact drops the avatar URLs and touches nothing else.\nDo not expect a named field set from these two; expect the same records minus\nthe pictures.\n\n`view: \"full\"` returns Splitwise's records untouched, everywhere. There is **no\n`raw` rung**: `full` already IS the upstream payload, so a third value could\nonly alias it.\n\n**A projection that trips returns the rows WHOLE**, and for the entire array\nrather than per record — one odd record projected to nothing among fifty good\nones is a hole in the middle of an answer, and indistinguishable from an\nexpense with no content. So a fat response is a possible outcome; a quietly\ngappy one is not.\n\nThe other eighteen tools take no `view`, each for its own reason:\n\n- **`sw_get_receipt`** is the one tool the media rung is documented never to\n  touch: its PRODUCT is the image. Stripping there would not shrink the answer,\n  it would delete it.\n- **`sw_get_categories` and `sw_get_currencies`** are static reference lists —\n  already narrow, no media, and every field on them is the answer.\n- **`sw_healthcheck`** answers reachability and auth.\n- **The fourteen writes** (`sw_create_expense`, `sw_update_expense`,\n  `sw_delete_expense`, `sw_undelete_expense`, `sw_create_group`,\n  `sw_delete_group`, `sw_undelete_group`, `sw_add_user_to_group`,\n  `sw_remove_user_from_group`, `sw_create_friend`, `sw_delete_friend`,\n  `sw_create_comment`, `sw_delete_comment`, `sw_update_user`) return receipts —\n  an id, a status — with nothing to strip and everything to keep.\n\n## Workflows\n\n**Add an expense to a group:**\n```\nsw_list_groups → find group ID for \"vacation\"\nsw_create_expense(group_id, \"Dinner\", \"80.00\", split_equally: true)\n```\n\n**Add someone to a group:**\n```\nsw_list_friends → find Meredith's user_id\nsw_get_group(id) → check if Meredith is already in members[]\nsw_add_user_to_group(group_id, user_id) → if not\n```\n\n**Custom split (you paid, split 60/40):**\n```\nsw_get_current_user → your user_id\nsw_list_friends → other person's user_id\nsw_create_expense(group_id, \"Hotel\", \"200.00\", users: [\n  { user_id: yours, paid_share: \"200.00\", owed_share: \"120.00\" },\n  { user_id: theirs, paid_share: \"0.00\", owed_share: \"80.00\" }\n])\n```\n\n**Get the receipt for an expense:**\n```\nsw_list_expenses(...) → find expense ID\nsw_get_receipt(id, extract_text: true) → line items and totals as text\nsw_get_receipt(id, inline: true)       → the actual bytes, when you need to see it\nsw_get_receipt(id)                     → writes e.g. ./splitwise-receipt-4644814211.pdf\n```\n\n**Search and edit an expense:**\n```\nsw_list_expenses(group_id, dated_after: \"2026-01-01\") → find expense ID\nsw_update_expense(expense_id, description: \"Corrected description\", cost: \"95.00\")\n```\n\n## Notes\n\n- Every write except `sw_undelete_expense` / `sw_undelete_group` asks the user to confirm first. Where the client can show a prompt, it does. Otherwise the first call changes nothing and returns `status: \"confirmation-required\"` with a `preview` (method, path, `willSend`) and a `confirmToken`: show the preview to the user, get their approval in chat, then repeat the same call with the same arguments plus `confirmToken` (see `MCP_CONFIRM_MODE`). A token acts once, expires, and is refused (`DRAFT_CHANGED`) if any argument changed\n- `cost` is always a decimal string (e.g. `\"25.00\"`)\n- `split_equally: true` and `users` array are mutually exclusive\n- For custom split updates, the **full `users` array is required** — the API replaces the entire split\n- `sw_delete_expense` is a soft delete — restore with `sw_undelete_expense`\n- The `receipt.original` / `receipt.large` URLs on an expense are **not public** — fetching them without the API key returns 401. Always use `sw_get_receipt`, which fetches them with the server's own credentials\n- `sw_get_receipt` writes into `output_dir`, else `$SPLITWISE_OUTPUT_DIR`, else the working directory, and never overwrites an existing file\n- That path is on the **server's** filesystem. If you can't read it — a hosted or containerised server — use `inline: true` (bytes) or `extract_text: true` (PDF text) instead of the path\n- `extract_text` only works on PDFs, and only when the PDF has a text layer; a scanned or photographed receipt returns `text_note` instead, and needs `inline: true` to read\n- API default for `sw_list_expenses` is 20 results when `limit` is omitted\n\nFile v3.2.2:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"splitwise-mcp\",\n  \"version\": \"3.2.2\",\n  \"publishedAt\": 1790991900935\n}\n\nFile v3.2.2:skill-card.md\n\n## Description:\n\nHelps an agent retrieve Splitwise balances, expenses, groups, and friends and manage shared expenses through a configured Splitwise connection.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nSplitwise users can ask an agent to review balances and shared expenses, manage groups, and create, edit, or delete expenses after confirming account changes.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The Splitwise API key grants access to account data.\n\nMitigation: Keep the key out of shared files and chats, and install only if comfortable granting account access.\n\nRisk: Installing and running the external package executes software outside the skill instructions.\n\nMitigation: Review the package before installing or running it.\n\nRisk: Expense and group changes may affect other people or shared balances.\n\nMitigation: Review confirmation previews before creating, editing, or deleting records; use explicit Splitwise wording for ambiguous requests.\n\nRisk: Receipt downloads can leave sensitive files in the server's working directory.\n\nMitigation: Configure the receipt output location or use inline results when local files are not wanted.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/chrischall/skills/splitwise-mcp)\n- [splitwise-mcp npm package](https://www.npmjs.com/package/splitwise-mcp)\n- [Splitwise app registration](https://secure.splitwise.com/apps/register)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Files]\n\n**Output Format:** [Text or structured expense data; optional receipt files or inline receipt content]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Receipts may be written to the server's working directory by default.]\n\n## Skill Version(s):\n\n3.2.2 (source: ClawHub release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.2.1: 3 files, 6212 bytes\n\nFiles: skill-card.md (2037b), SKILL.md (11443b), _meta.json (132b)\n\nFile v3.2.1:SKILL.md\n\n---\nname: splitwise-mcp\ndescription: Access Splitwise expense and group data via MCP. Use when the user asks about Splitwise expenses, groups, friends, or balances, or wants to add, edit, or delete expenses. Triggers on phrases like \"add that expense to Splitwise\", \"split this with the vacation group\", \"make sure Meredith is in that group\", \"what do I owe\", or any request involving shared expenses or group management in Splitwise. Requires splitwise-mcp installed and the splitwise server registered (see Setup below).\n---\n\n# splitwise-mcp\n\nMCP server for Splitwise — natural-language expense and group management via the Splitwise API.\n\n- **npm:** [npmjs.com/package/splitwise-mcp](https://www.npmjs.com/package/splitwise-mcp)\n- **Source:** [github.com/chrischall/splitwise-mcp](https://github.com/chrischall/splitwise-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"splitwise-mcp\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/splitwise-mcp\ncd splitwise-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/splitwise-mcp/dist/index.js\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `SPLITWISE_API_KEY=<value>`.\n\n### Getting your API key\n\n1. Go to [splitwise.com/apps/register](https://secure.splitwise.com/apps/register)\n2. Register an app (name and description can be anything)\n3. Copy the **API key** from the app detail page\n\n## Authentication\n\nAPI key auth — no login flow or token rotation. The key is attached to every request as `Authorization: Bearer <key>`.\n\n## Tools\n\n### User\n| Tool | Description |\n|------|-------------|\n| `sw_get_current_user(view?)` | Get the authenticated user's profile. On the default `compact` rung that is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; `first_name` / `last_name` separately are on `view: \"full\"` |\n\n### Groups\n| Tool | Description |\n|------|-------------|\n| `sw_list_groups(view?)` | List all groups with `id`, `name`, `group_type`, `members[]`, `simplified_debts` and `invite_link`. See [Response shape](#response-shape-view) — this is the response that does not fit at all on `full` |\n| `sw_get_group(id, view?)` | Get a single group's details including members and balances |\n| `sw_create_group(name, group_type?, simplify_by_default?)` | Create a new group (`group_type`: `apartment`, `house`, `trip`, `other`) |\n| `sw_add_user_to_group(group_id, user_id?)` | Add a user by `user_id` (preferred) or `first_name` + `last_name` + `email` |\n| `sw_remove_user_from_group(group_id, user_id)` | Remove a user from a group |\n\n### Friends\n| Tool | Description |\n|------|-------------|\n| `sw_list_friends(view?)` | List all friends. On the default `compact` rung each is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; the separate name fields are on `view: \"full\"` |\n\n### Expenses\n| Tool | Description |\n|------|-------------|\n| `sw_list_expenses(group_id?, friend_id?, dated_after?, dated_before?, limit?, offset?, view?)` | List or search expenses |\n| `sw_get_expense(id, view?)` | Get full details of a single expense |\n| `sw_create_expense(group_id, description, cost, split_equally? \\| users?)` | Create an expense — equal split or custom per-person split |\n| `sw_update_expense(expense_id, ...)` | Edit an existing expense (custom split requires full `users` array) |\n| `sw_delete_expense(id)` | Soft-delete an expense |\n| `sw_undelete_expense(id)` | Restore a soft-deleted expense |\n\n### Receipts\n| Tool | Description |\n|------|-------------|\n| `sw_get_receipt(id, size?, inline?, extract_text?, output_dir?, write?)` | Download the receipt attached to an expense. `inline: true` returns the bytes in the result (images **and** PDFs); `extract_text: true` returns a PDF's text layer; by default it also writes the file and returns the path |\n\n### Utilities\n| Tool | Description |\n|------|-------------|\n| `sw_get_notifications(view?)` | Recent activity feed for the current user |\n| `sw_get_categories` | Hierarchical list of expense categories (use `id` as `category_id`) |\n| `sw_get_currencies` | List of supported currency codes |\n\n## Response shape (`view`)\n\nNine read tools take `view: \"compact\" | \"full\"`, and **`compact` is the\ndefault** — you get the slim rung without asking. Two of them are not in the\ntable above: `sw_get_user(id, view?)` and `sw_get_comments(expense_id, view?)`.\n\nThis is not a nicety. A live `sw_list_groups` on a 51-group account came back\nas **192,123 characters and was REFUSED by the host before the model saw a byte\nof it** — the tool was not expensive, it was unusable. 60% of that response was\nimage URLs: `avatar` + `tall_avatar` + `cover_photo` (51.7 KB) and a `picture`\nobject per member across 51 groups (37.7 KB). Stripping media alone takes it to\n51.4 KB (−73%); the field projections below take it to 29.3 KB.\n\n**Compact means two different things here, depending on the tool.**\n\n**A hand-written field projection** — `sw_list_groups`, `sw_get_group`,\n`sw_list_friends`, `sw_get_current_user`, `sw_get_user`, `sw_list_expenses`,\n`sw_get_expense`:\n\n- **A person becomes `{id, name, email, registration_status, balance}`, and\n  `name` is `first_name` + `last_name` JOINED.** This is the one that will trip\n  you: reach for `last_name` on the default rung and it is not there. `balance`\n  survives because it is the whole reason to look a person up, and\n  `registration_status` because it is how you know an invite was never\n  accepted.\n- **A group keeps** `{id, name, group_type, updated_at, members[],\n  simplified_debts, invite_link}`. The whiteboard fields and the\n  `simplify_by_default` / `custom_avatar` / `group_reminders` settings go —\n  nothing here reads them. `original_debts` goes because `simplified_debts`\n  answers \"who owes whom\", and the two differ only when simplification is on;\n  `full` has both.\n- **An expense keeps the share breakdown**, as `{id, name, paid_share,\n  owed_share, net_balance}` per person rather than Splitwise's nested `user`\n  object, plus `repayments`, `comments_count` and `category` as a name. Two\n  details matter: `deleted_at` is kept **only when set**, because a deleted\n  expense still comes back from the list endpoint and a caller who cannot see\n  it will count it; and the receipt becomes `has_receipt: true` — the bytes\n  come from `sw_get_receipt`. The eleven-field repeat/reminder/transaction\n  block goes (`repeats`, `next_repeat`, `transaction_status`, …) — it was\n  `false` / `null` / `\"offline\"` on every expense in a live account.\n\n**Media stripping, with no field projection claimed** — `sw_get_notifications`\nand `sw_get_comments`. Compact drops the avatar URLs and touches nothing else.\nDo not expect a named field set from these two; expect the same records minus\nthe pictures.\n\n`view: \"full\"` returns Splitwise's records untouched, everywhere. There is **no\n`raw` rung**: `full` already IS the upstream payload, so a third value could\nonly alias it.\n\n**A projection that trips returns the rows WHOLE**, and for the entire array\nrather than per record — one odd record projected to nothing among fifty good\nones is a hole in the middle of an answer, and indistinguishable from an\nexpense with no content. So a fat response is a possible outcome; a quietly\ngappy one is not.\n\nThe other eighteen tools take no `view`, each for its own reason:\n\n- **`sw_get_receipt`** is the one tool the media rung is documented never to\n  touch: its PRODUCT is the image. Stripping there would not shrink the answer,\n  it would delete it.\n- **`sw_get_categories` and `sw_get_currencies`** are static reference lists —\n  already narrow, no media, and every field on them is the answer.\n- **`sw_healthcheck`** answers reachability and auth.\n- **The fourteen writes** (`sw_create_expense`, `sw_update_expense`,\n  `sw_delete_expense`, `sw_undelete_expense`, `sw_create_group`,\n  `sw_delete_group`, `sw_undelete_group`, `sw_add_user_to_group`,\n  `sw_remove_user_from_group`, `sw_create_friend`, `sw_delete_friend`,\n  `sw_create_comment`, `sw_delete_comment`, `sw_update_user`) return receipts —\n  an id, a status — with nothing to strip and everything to keep.\n\n## Workflows\n\n**Add an expense to a group:**\n```\nsw_list_groups → find group ID for \"vacation\"\nsw_create_expense(group_id, \"Dinner\", \"80.00\", split_equally: true)\n```\n\n**Add someone to a group:**\n```\nsw_list_friends → find Meredith's user_id\nsw_get_group(id) → check if Meredith is already in members[]\nsw_add_user_to_group(group_id, user_id) → if not\n```\n\n**Custom split (you paid, split 60/40):**\n```\nsw_get_current_user → your user_id\nsw_list_friends → other person's user_id\nsw_create_expense(group_id, \"Hotel\", \"200.00\", users: [\n  { user_id: yours, paid_share: \"200.00\", owed_share: \"120.00\" },\n  { user_id: theirs, paid_share: \"0.00\", owed_share: \"80.00\" }\n])\n```\n\n**Get the receipt for an expense:**\n```\nsw_list_expenses(...) → find expense ID\nsw_get_receipt(id, extract_text: true) → line items and totals as text\nsw_get_receipt(id, inline: true)       → the actual bytes, when you need to see it\nsw_get_receipt(id)                     → writes e.g. ./splitwise-receipt-4644814211.pdf\n```\n\n**Search and edit an expense:**\n```\nsw_list_expenses(group_id, dated_after: \"2026-01-01\") → find expense ID\nsw_update_expense(expense_id, description: \"Corrected description\", cost: \"95.00\")\n```\n\n## Notes\n\n- Every write except `sw_undelete_expense` / `sw_undelete_group` asks the user to confirm first. Where the client can show a prompt, it does. Otherwise the first call changes nothing and returns `status: \"confirmation-required\"` with a `preview` (method, path, `willSend`) and a `confirmToken`: show the preview to the user, get their approval in chat, then repeat the same call with the same arguments plus `confirmToken` (see `MCP_CONFIRM_MODE`). A token acts once, expires, and is refused (`DRAFT_CHANGED`) if any argument changed\n- `cost` is always a decimal string (e.g. `\"25.00\"`)\n- `split_equally: true` and `users` array are mutually exclusive\n- For custom split updates, the **full `users` array is required** — the API replaces the entire split\n- `sw_delete_expense` is a soft delete — restore with `sw_undelete_expense`\n- The `receipt.original` / `receipt.large` URLs on an expense are **not public** — fetching them without the API key returns 401. Always use `sw_get_receipt`, which fetches them with the server's own credentials\n- `sw_get_receipt` writes into `output_dir`, else `$SPLITWISE_OUTPUT_DIR`, else the working directory, and never overwrites an existing file\n- That path is on the **server's** filesystem. If you can't read it — a hosted or containerised server — use `inline: true` (bytes) or `extract_text: true` (PDF text) instead of the path\n- `extract_text` only works on PDFs, and only when the PDF has a text layer; a scanned or photographed receipt returns `text_note` instead, and needs `inline: true` to read\n- API default for `sw_list_expenses` is 20 results when `limit` is omitted\n\nFile v3.2.1:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"splitwise-mcp\",\n  \"version\": \"3.2.1\",\n  \"publishedAt\": 1790351552467\n}\n\nFile v3.2.1:skill-card.md\n\n## Description:\n\nGuides agents in accessing and managing Splitwise expenses, groups, friends, balances, and receipts through an MCP server.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nPeople and developers using an agent can check shared expenses and balances, manage Splitwise groups and expenses, and retrieve receipts after configuring the Splitwise MCP server.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Creating, editing, or deleting Splitwise records can change shared financial data.\n\nMitigation: Review the proposed change and confirmation preview before approving a write.\n\nRisk: The Splitwise API key and returned financial data are sensitive.\n\nMitigation: Keep the API key private and limit access to balances, expenses, and receipts.\n\nRisk: Downloaded receipts may be written to the server's working directory.\n\nMitigation: Use a constrained receipt output directory or request inline receipt content when local files are unsuitable.\n\n## Reference(s):\n\n- [ClawHub skill release](https://clawhub.ai/chrischall/skills/splitwise-mcp)\n- [splitwise-mcp npm package](https://www.npmjs.com/package/splitwise-mcp)\n- [Splitwise API key registration](https://secure.splitwise.com/apps/register)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Configuration instructions, Shell commands]\n\n**Output Format:** [Markdown with JSON configuration and shell examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Explains Splitwise read and write workflows, including confirmation previews and receipt handling.]\n\n## Skill Version(s):\n\n3.2.1 (source: server-resolved release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.2.0: 3 files, 6433 bytes\n\nFiles: skill-card.md (2559b), SKILL.md (11443b), _meta.json (132b)\n\nFile v3.2.0:SKILL.md\n\n---\nname: splitwise-mcp\ndescription: Access Splitwise expense and group data via MCP. Use when the user asks about Splitwise expenses, groups, friends, or balances, or wants to add, edit, or delete expenses. Triggers on phrases like \"add that expense to Splitwise\", \"split this with the vacation group\", \"make sure Meredith is in that group\", \"what do I owe\", or any request involving shared expenses or group management in Splitwise. Requires splitwise-mcp installed and the splitwise server registered (see Setup below).\n---\n\n# splitwise-mcp\n\nMCP server for Splitwise — natural-language expense and group management via the Splitwise API.\n\n- **npm:** [npmjs.com/package/splitwise-mcp](https://www.npmjs.com/package/splitwise-mcp)\n- **Source:** [github.com/chrischall/splitwise-mcp](https://github.com/chrischall/splitwise-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"splitwise-mcp\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/splitwise-mcp\ncd splitwise-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/splitwise-mcp/dist/index.js\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `SPLITWISE_API_KEY=<value>`.\n\n### Getting your API key\n\n1. Go to [splitwise.com/apps/register](https://secure.splitwise.com/apps/register)\n2. Register an app (name and description can be anything)\n3. Copy the **API key** from the app detail page\n\n## Authentication\n\nAPI key auth — no login flow or token rotation. The key is attached to every request as `Authorization: Bearer <key>`.\n\n## Tools\n\n### User\n| Tool | Description |\n|------|-------------|\n| `sw_get_current_user(view?)` | Get the authenticated user's profile. On the default `compact` rung that is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; `first_name` / `last_name` separately are on `view: \"full\"` |\n\n### Groups\n| Tool | Description |\n|------|-------------|\n| `sw_list_groups(view?)` | List all groups with `id`, `name`, `group_type`, `members[]`, `simplified_debts` and `invite_link`. See [Response shape](#response-shape-view) — this is the response that does not fit at all on `full` |\n| `sw_get_group(id, view?)` | Get a single group's details including members and balances |\n| `sw_create_group(name, group_type?, simplify_by_default?)` | Create a new group (`group_type`: `apartment`, `house`, `trip`, `other`) |\n| `sw_add_user_to_group(group_id, user_id?)` | Add a user by `user_id` (preferred) or `first_name` + `last_name` + `email` |\n| `sw_remove_user_from_group(group_id, user_id)` | Remove a user from a group |\n\n### Friends\n| Tool | Description |\n|------|-------------|\n| `sw_list_friends(view?)` | List all friends. On the default `compact` rung each is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; the separate name fields are on `view: \"full\"` |\n\n### Expenses\n| Tool | Description |\n|------|-------------|\n| `sw_list_expenses(group_id?, friend_id?, dated_after?, dated_before?, limit?, offset?, view?)` | List or search expenses |\n| `sw_get_expense(id, view?)` | Get full details of a single expense |\n| `sw_create_expense(group_id, description, cost, split_equally? \\| users?)` | Create an expense — equal split or custom per-person split |\n| `sw_update_expense(expense_id, ...)` | Edit an existing expense (custom split requires full `users` array) |\n| `sw_delete_expense(id)` | Soft-delete an expense |\n| `sw_undelete_expense(id)` | Restore a soft-deleted expense |\n\n### Receipts\n| Tool | Description |\n|------|-------------|\n| `sw_get_receipt(id, size?, inline?, extract_text?, output_dir?, write?)` | Download the receipt attached to an expense. `inline: true` returns the bytes in the result (images **and** PDFs); `extract_text: true` returns a PDF's text layer; by default it also writes the file and returns the path |\n\n### Utilities\n| Tool | Description |\n|------|-------------|\n| `sw_get_notifications(view?)` | Recent activity feed for the current user |\n| `sw_get_categories` | Hierarchical list of expense categories (use `id` as `category_id`) |\n| `sw_get_currencies` | List of supported currency codes |\n\n## Response shape (`view`)\n\nNine read tools take `view: \"compact\" | \"full\"`, and **`compact` is the\ndefault** — you get the slim rung without asking. Two of them are not in the\ntable above: `sw_get_user(id, view?)` and `sw_get_comments(expense_id, view?)`.\n\nThis is not a nicety. A live `sw_list_groups` on a 51-group account came back\nas **192,123 characters and was REFUSED by the host before the model saw a byte\nof it** — the tool was not expensive, it was unusable. 60% of that response was\nimage URLs: `avatar` + `tall_avatar` + `cover_photo` (51.7 KB) and a `picture`\nobject per member across 51 groups (37.7 KB). Stripping media alone takes it to\n51.4 KB (−73%); the field projections below take it to 29.3 KB.\n\n**Compact means two different things here, depending on the tool.**\n\n**A hand-written field projection** — `sw_list_groups`, `sw_get_group`,\n`sw_list_friends`, `sw_get_current_user`, `sw_get_user`, `sw_list_expenses`,\n`sw_get_expense`:\n\n- **A person becomes `{id, name, email, registration_status, balance}`, and\n  `name` is `first_name` + `last_name` JOINED.** This is the one that will trip\n  you: reach for `last_name` on the default rung and it is not there. `balance`\n  survives because it is the whole reason to look a person up, and\n  `registration_status` because it is how you know an invite was never\n  accepted.\n- **A group keeps** `{id, name, group_type, updated_at, members[],\n  simplified_debts, invite_link}`. The whiteboard fields and the\n  `simplify_by_default` / `custom_avatar` / `group_reminders` settings go —\n  nothing here reads them. `original_debts` goes because `simplified_debts`\n  answers \"who owes whom\", and the two differ only when simplification is on;\n  `full` has both.\n- **An expense keeps the share breakdown**, as `{id, name, paid_share,\n  owed_share, net_balance}` per person rather than Splitwise's nested `user`\n  object, plus `repayments`, `comments_count` and `category` as a name. Two\n  details matter: `deleted_at` is kept **only when set**, because a deleted\n  expense still comes back from the list endpoint and a caller who cannot see\n  it will count it; and the receipt becomes `has_receipt: true` — the bytes\n  come from `sw_get_receipt`. The eleven-field repeat/reminder/transaction\n  block goes (`repeats`, `next_repeat`, `transaction_status`, …) — it was\n  `false` / `null` / `\"offline\"` on every expense in a live account.\n\n**Media stripping, with no field projection claimed** — `sw_get_notifications`\nand `sw_get_comments`. Compact drops the avatar URLs and touches nothing else.\nDo not expect a named field set from these two; expect the same records minus\nthe pictures.\n\n`view: \"full\"` returns Splitwise's records untouched, everywhere. There is **no\n`raw` rung**: `full` already IS the upstream payload, so a third value could\nonly alias it.\n\n**A projection that trips returns the rows WHOLE**, and for the entire array\nrather than per record — one odd record projected to nothing among fifty good\nones is a hole in the middle of an answer, and indistinguishable from an\nexpense with no content. So a fat response is a possible outcome; a quietly\ngappy one is not.\n\nThe other eighteen tools take no `view`, each for its own reason:\n\n- **`sw_get_receipt`** is the one tool the media rung is documented never to\n  touch: its PRODUCT is the image. Stripping there would not shrink the answer,\n  it would delete it.\n- **`sw_get_categories` and `sw_get_currencies`** are static reference lists —\n  already narrow, no media, and every field on them is the answer.\n- **`sw_healthcheck`** answers reachability and auth.\n- **The fourteen writes** (`sw_create_expense`, `sw_update_expense`,\n  `sw_delete_expense`, `sw_undelete_expense`, `sw_create_group`,\n  `sw_delete_group`, `sw_undelete_group`, `sw_add_user_to_group`,\n  `sw_remove_user_from_group`, `sw_create_friend`, `sw_delete_friend`,\n  `sw_create_comment`, `sw_delete_comment`, `sw_update_user`) return receipts —\n  an id, a status — with nothing to strip and everything to keep.\n\n## Workflows\n\n**Add an expense to a group:**\n```\nsw_list_groups → find group ID for \"vacation\"\nsw_create_expense(group_id, \"Dinner\", \"80.00\", split_equally: true)\n```\n\n**Add someone to a group:**\n```\nsw_list_friends → find Meredith's user_id\nsw_get_group(id) → check if Meredith is already in members[]\nsw_add_user_to_group(group_id, user_id) → if not\n```\n\n**Custom split (you paid, split 60/40):**\n```\nsw_get_current_user → your user_id\nsw_list_friends → other person's user_id\nsw_create_expense(group_id, \"Hotel\", \"200.00\", users: [\n  { user_id: yours, paid_share: \"200.00\", owed_share: \"120.00\" },\n  { user_id: theirs, paid_share: \"0.00\", owed_share: \"80.00\" }\n])\n```\n\n**Get the receipt for an expense:**\n```\nsw_list_expenses(...) → find expense ID\nsw_get_receipt(id, extract_text: true) → line items and totals as text\nsw_get_receipt(id, inline: true)       → the actual bytes, when you need to see it\nsw_get_receipt(id)                     → writes e.g. ./splitwise-receipt-4644814211.pdf\n```\n\n**Search and edit an expense:**\n```\nsw_list_expenses(group_id, dated_after: \"2026-01-01\") → find expense ID\nsw_update_expense(expense_id, description: \"Corrected description\", cost: \"95.00\")\n```\n\n## Notes\n\n- Every write except `sw_undelete_expense` / `sw_undelete_group` asks the user to confirm first. Where the client can show a prompt, it does. Otherwise the first call changes nothing and returns `status: \"confirmation-required\"` with a `preview` (method, path, `willSend`) and a `confirmToken`: show the preview to the user, get their approval in chat, then repeat the same call with the same arguments plus `confirmToken` (see `MCP_CONFIRM_MODE`). A token acts once, expires, and is refused (`DRAFT_CHANGED`) if any argument changed\n- `cost` is always a decimal string (e.g. `\"25.00\"`)\n- `split_equally: true` and `users` array are mutually exclusive\n- For custom split updates, the **full `users` array is required** — the API replaces the entire split\n- `sw_delete_expense` is a soft delete — restore with `sw_undelete_expense`\n- The `receipt.original` / `receipt.large` URLs on an expense are **not public** — fetching them without the API key returns 401. Always use `sw_get_receipt`, which fetches them with the server's own credentials\n- `sw_get_receipt` writes into `output_dir`, else `$SPLITWISE_OUTPUT_DIR`, else the working directory, and never overwrites an existing file\n- That path is on the **server's** filesystem. If you can't read it — a hosted or containerised server — use `inline: true` (bytes) or `extract_text: true` (PDF text) instead of the path\n- `extract_text` only works on PDFs, and only when the PDF has a text layer; a scanned or photographed receipt returns `text_note` instead, and needs `inline: true` to read\n- API default for `sw_list_expenses` is 20 results when `limit` is omitted\n\nFile v3.2.0:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"splitwise-mcp\",\n  \"version\": \"3.2.0\",\n  \"publishedAt\": 1790262727481\n}\n\nFile v3.2.0:skill-card.md\n\n## Description:\n\nsplitwise-mcp helps agents access Splitwise expenses, groups, friends, balances, receipts, and expense-management actions through an MCP server backed by the Splitwise API.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agent users use this skill to configure and operate a Splitwise MCP server for shared-expense workflows, including reading balances and groups, creating or editing expenses, managing friends or group membership, and retrieving receipt data.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The MCP server uses a Splitwise API key and can access account data including expenses, groups, friends, balances, and receipts.\n\nMitigation: Install and configure it only when the user is comfortable granting that account access, and protect the SPLITWISE_API_KEY as a secret.\n\nRisk: Write tools can create, edit, delete, or restore Splitwise records.\n\nMitigation: Review write previews and confirm only the intended changes before allowing write operations to proceed.\n\nRisk: Receipt downloads or extracted receipt text can contain sensitive personal or financial information and may be written to disk.\n\nMitigation: Choose output directories deliberately, prefer inline or extracted-text modes when file access is constrained, and handle generated receipt files as sensitive data.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/chrischall/skills/splitwise-mcp)\n- [splitwise-mcp npm package](https://www.npmjs.com/package/splitwise-mcp)\n- [Splitwise app registration](https://secure.splitwise.com/apps/register)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Shell commands, Configuration, API calls, Guidance]\n\n**Output Format:** [Markdown guidance with JSON configuration examples, shell commands, and MCP tool-call instructions]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May return Splitwise account data, expense records, group and friend data, balances, write confirmations, receipt paths, extracted receipt text, or inline receipt bytes depending on the MCP tool used.]\n\n## Skill Version(s):\n\n3.2.0 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.1.2: 3 files, 6077 bytes\n\nFiles: skill-card.md (2353b), SKILL.md (10909b), _meta.json (132b)\n\nFile v3.1.2:SKILL.md\n\n---\nname: splitwise-mcp\ndescription: Access Splitwise expense and group data via MCP. Use when the user asks about Splitwise expenses, groups, friends, or balances, or wants to add, edit, or delete expenses. Triggers on phrases like \"add that expense to Splitwise\", \"split this with the vacation group\", \"make sure Meredith is in that group\", \"what do I owe\", or any request involving shared expenses or group management in Splitwise. Requires splitwise-mcp installed and the splitwise server registered (see Setup below).\n---\n\n# splitwise-mcp\n\nMCP server for Splitwise — natural-language expense and group management via the Splitwise API.\n\n- **npm:** [npmjs.com/package/splitwise-mcp](https://www.npmjs.com/package/splitwise-mcp)\n- **Source:** [github.com/chrischall/splitwise-mcp](https://github.com/chrischall/splitwise-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"splitwise-mcp\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/splitwise-mcp\ncd splitwise-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/splitwise-mcp/dist/index.js\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `SPLITWISE_API_KEY=<value>`.\n\n### Getting your API key\n\n1. Go to [splitwise.com/apps/register](https://secure.splitwise.com/apps/register)\n2. Register an app (name and description can be anything)\n3. Copy the **API key** from the app detail page\n\n## Authentication\n\nAPI key auth — no login flow or token rotation. The key is attached to every request as `Authorization: Bearer <key>`.\n\n## Tools\n\n### User\n| Tool | Description |\n|------|-------------|\n| `sw_get_current_user(view?)` | Get the authenticated user's profile. On the default `compact` rung that is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; `first_name` / `last_name` separately are on `view: \"full\"` |\n\n### Groups\n| Tool | Description |\n|------|-------------|\n| `sw_list_groups(view?)` | List all groups with `id`, `name`, `group_type`, `members[]`, `simplified_debts` and `invite_link`. See [Response shape](#response-shape-view) — this is the response that does not fit at all on `full` |\n| `sw_get_group(id, view?)` | Get a single group's details including members and balances |\n| `sw_create_group(name, group_type?, simplify_by_default?)` | Create a new group (`group_type`: `apartment`, `house`, `trip`, `other`) |\n| `sw_add_user_to_group(group_id, user_id?)` | Add a user by `user_id` (preferred) or `first_name` + `last_name` + `email` |\n| `sw_remove_user_from_group(group_id, user_id)` | Remove a user from a group |\n\n### Friends\n| Tool | Description |\n|------|-------------|\n| `sw_list_friends(view?)` | List all friends. On the default `compact` rung each is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; the separate name fields are on `view: \"full\"` |\n\n### Expenses\n| Tool | Description |\n|------|-------------|\n| `sw_list_expenses(group_id?, friend_id?, dated_after?, dated_before?, limit?, offset?, view?)` | List or search expenses |\n| `sw_get_expense(id, view?)` | Get full details of a single expense |\n| `sw_create_expense(group_id, description, cost, split_equally? \\| users?)` | Create an expense — equal split or custom per-person split |\n| `sw_update_expense(expense_id, ...)` | Edit an existing expense (custom split requires full `users` array) |\n| `sw_delete_expense(id)` | Soft-delete an expense |\n| `sw_undelete_expense(id)` | Restore a soft-deleted expense |\n\n### Receipts\n| Tool | Description |\n|------|-------------|\n| `sw_get_receipt(id, size?, inline?, extract_text?, output_dir?, write?)` | Download the receipt attached to an expense. `inline: true` returns the bytes in the result (images **and** PDFs); `extract_text: true` returns a PDF's text layer; by default it also writes the file and returns the path |\n\n### Utilities\n| Tool | Description |\n|------|-------------|\n| `sw_get_notifications(view?)` | Recent activity feed for the current user |\n| `sw_get_categories` | Hierarchical list of expense categories (use `id` as `category_id`) |\n| `sw_get_currencies` | List of supported currency codes |\n\n## Response shape (`view`)\n\nNine read tools take `view: \"compact\" | \"full\"`, and **`compact` is the\ndefault** — you get the slim rung without asking. Two of them are not in the\ntable above: `sw_get_user(id, view?)` and `sw_get_comments(expense_id, view?)`.\n\nThis is not a nicety. A live `sw_list_groups` on a 51-group account came back\nas **192,123 characters and was REFUSED by the host before the model saw a byte\nof it** — the tool was not expensive, it was unusable. 60% of that response was\nimage URLs: `avatar` + `tall_avatar` + `cover_photo` (51.7 KB) and a `picture`\nobject per member across 51 groups (37.7 KB). Stripping media alone takes it to\n51.4 KB (−73%); the field projections below take it to 29.3 KB.\n\n**Compact means two different things here, depending on the tool.**\n\n**A hand-written field projection** — `sw_list_groups`, `sw_get_group`,\n`sw_list_friends`, `sw_get_current_user`, `sw_get_user`, `sw_list_expenses`,\n`sw_get_expense`:\n\n- **A person becomes `{id, name, email, registration_status, balance}`, and\n  `name` is `first_name` + `last_name` JOINED.** This is the one that will trip\n  you: reach for `last_name` on the default rung and it is not there. `balance`\n  survives because it is the whole reason to look a person up, and\n  `registration_status` because it is how you know an invite was never\n  accepted.\n- **A group keeps** `{id, name, group_type, updated_at, members[],\n  simplified_debts, invite_link}`. The whiteboard fields and the\n  `simplify_by_default` / `custom_avatar` / `group_reminders` settings go —\n  nothing here reads them. `original_debts` goes because `simplified_debts`\n  answers \"who owes whom\", and the two differ only when simplification is on;\n  `full` has both.\n- **An expense keeps the share breakdown**, as `{id, name, paid_share,\n  owed_share, net_balance}` per person rather than Splitwise's nested `user`\n  object, plus `repayments`, `comments_count` and `category` as a name. Two\n  details matter: `deleted_at` is kept **only when set**, because a deleted\n  expense still comes back from the list endpoint and a caller who cannot see\n  it will count it; and the receipt becomes `has_receipt: true` — the bytes\n  come from `sw_get_receipt`. The eleven-field repeat/reminder/transaction\n  block goes (`repeats`, `next_repeat`, `transaction_status`, …) — it was\n  `false` / `null` / `\"offline\"` on every expense in a live account.\n\n**Media stripping, with no field projection claimed** — `sw_get_notifications`\nand `sw_get_comments`. Compact drops the avatar URLs and touches nothing else.\nDo not expect a named field set from these two; expect the same records minus\nthe pictures.\n\n`view: \"full\"` returns Splitwise's records untouched, everywhere. There is **no\n`raw` rung**: `full` already IS the upstream payload, so a third value could\nonly alias it.\n\n**A projection that trips returns the rows WHOLE**, and for the entire array\nrather than per record — one odd record projected to nothing among fifty good\nones is a hole in the middle of an answer, and indistinguishable from an\nexpense with no content. So a fat response is a possible outcome; a quietly\ngappy one is not.\n\nThe other eighteen tools take no `view`, each for its own reason:\n\n- **`sw_get_receipt`** is the one tool the media rung is documented never to\n  touch: its PRODUCT is the image. Stripping there would not shrink the answer,\n  it would delete it.\n- **`sw_get_categories` and `sw_get_currencies`** are static reference lists —\n  already narrow, no media, and every field on them is the answer.\n- **`sw_healthcheck`** answers reachability and auth.\n- **The fourteen writes** (`sw_create_expense`, `sw_update_expense`,\n  `sw_delete_expense`, `sw_undelete_expense`, `sw_create_group`,\n  `sw_delete_group`, `sw_undelete_group`, `sw_add_user_to_group`,\n  `sw_remove_user_from_group`, `sw_create_friend`, `sw_delete_friend`,\n  `sw_create_comment`, `sw_delete_comment`, `sw_update_user`) return receipts —\n  an id, a status — with nothing to strip and everything to keep.\n\n## Workflows\n\n**Add an expense to a group:**\n```\nsw_list_groups → find group ID for \"vacation\"\nsw_create_expense(group_id, \"Dinner\", \"80.00\", split_equally: true)\n```\n\n**Add someone to a group:**\n```\nsw_list_friends → find Meredith's user_id\nsw_get_group(id) → check if Meredith is already in members[]\nsw_add_user_to_group(group_id, user_id) → if not\n```\n\n**Custom split (you paid, split 60/40):**\n```\nsw_get_current_user → your user_id\nsw_list_friends → other person's user_id\nsw_create_expense(group_id, \"Hotel\", \"200.00\", users: [\n  { user_id: yours, paid_share: \"200.00\", owed_share: \"120.00\" },\n  { user_id: theirs, paid_share: \"0.00\", owed_share: \"80.00\" }\n])\n```\n\n**Get the receipt for an expense:**\n```\nsw_list_expenses(...) → find expense ID\nsw_get_receipt(id, extract_text: true) → line items and totals as text\nsw_get_receipt(id, inline: true)       → the actual bytes, when you need to see it\nsw_get_receipt(id)                     → writes e.g. ./splitwise-receipt-4644814211.pdf\n```\n\n**Search and edit an expense:**\n```\nsw_list_expenses(group_id, dated_after: \"2026-01-01\") → find expense ID\nsw_update_expense(expense_id, description: \"Corrected description\", cost: \"95.00\")\n```\n\n## Notes\n\n- `cost` is always a decimal string (e.g. `\"25.00\"`)\n- `split_equally: true` and `users` array are mutually exclusive\n- For custom split updates, the **full `users` array is required** — the API replaces the entire split\n- `sw_delete_expense` is a soft delete — restore with `sw_undelete_expense`\n- The `receipt.original` / `receipt.large` URLs on an expense are **not public** — fetching them without the API key returns 401. Always use `sw_get_receipt`, which fetches them with the server's own credentials\n- `sw_get_receipt` writes into `output_dir`, else `$SPLITWISE_OUTPUT_DIR`, else the working directory, and never overwrites an existing file\n- That path is on the **server's** filesystem. If you can't read it — a hosted or containerised server — use `inline: true` (bytes) or `extract_text: true` (PDF text) instead of the path\n- `extract_text` only works on PDFs, and only when the PDF has a text layer; a scanned or photographed receipt returns `text_note` instead, and needs `inline: true` to read\n- API default for `sw_list_expenses` is 20 results when `limit` is omitted\n\nFile v3.1.2:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"splitwise-mcp\",\n  \"version\": \"3.1.2\",\n  \"publishedAt\": 1790199986484\n}\n\nFile v3.1.2:skill-card.md\n\n## Description:\n\nAccess Splitwise expense and group data via MCP for questions about expenses, groups, friends, balances, and requests to add, edit, or delete expenses.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agent users use this skill to configure and operate a Splitwise MCP server for shared-expense workflows. It supports reading Splitwise account data and performing live expense, group, friend, comment, and receipt operations through MCP tools.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can perform live create, update, delete, restore, group membership, friend, and comment actions in Splitwise.\n\nMitigation: Require user confirmation before any write operation and review the target group, people, amount, split, and expense identifier before calling the tool.\n\nRisk: The skill uses a Splitwise API key that can expose account data such as balances, emails, groups, receipts, and activity.\n\nMitigation: Keep the API key private, provide it only through the MCP server environment, and install the skill only when Splitwise account access is intended.\n\nRisk: Receipt retrieval can write files on the MCP server filesystem.\n\nMitigation: Set an explicit output directory or use inline or text extraction modes when receipt files should not be written.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/chrischall/skills/splitwise-mcp)\n- [npm package](https://www.npmjs.com/package/splitwise-mcp)\n- [Splitwise app registration](https://secure.splitwise.com/apps/register)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown with JSON and shell command snippets]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May guide MCP tool calls that read Splitwise data, change live Splitwise records, or retrieve receipt files.]\n\n## Skill Version(s):\n\n3.1.2 (source: release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.1.1: 3 files, 6013 bytes\n\nFiles: skill-card.md (2123b), SKILL.md (10909b), _meta.json (132b)\n\nFile v3.1.1:SKILL.md\n\n---\nname: splitwise-mcp\ndescription: Access Splitwise expense and group data via MCP. Use when the user asks about Splitwise expenses, groups, friends, or balances, or wants to add, edit, or delete expenses. Triggers on phrases like \"add that expense to Splitwise\", \"split this with the vacation group\", \"make sure Meredith is in that group\", \"what do I owe\", or any request involving shared expenses or group management in Splitwise. Requires splitwise-mcp installed and the splitwise server registered (see Setup below).\n---\n\n# splitwise-mcp\n\nMCP server for Splitwise — natural-language expense and group management via the Splitwise API.\n\n- **npm:** [npmjs.com/package/splitwise-mcp](https://www.npmjs.com/package/splitwise-mcp)\n- **Source:** [github.com/chrischall/splitwise-mcp](https://github.com/chrischall/splitwise-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"splitwise-mcp\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/splitwise-mcp\ncd splitwise-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/splitwise-mcp/dist/index.js\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `SPLITWISE_API_KEY=<value>`.\n\n### Getting your API key\n\n1. Go to [splitwise.com/apps/register](https://secure.splitwise.com/apps/register)\n2. Register an app (name and description can be anything)\n3. Copy the **API key** from the app detail page\n\n## Authentication\n\nAPI key auth — no login flow or token rotation. The key is attached to every request as `Authorization: Bearer <key>`.\n\n## Tools\n\n### User\n| Tool | Description |\n|------|-------------|\n| `sw_get_current_user(view?)` | Get the authenticated user's profile. On the default `compact` rung that is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; `first_name` / `last_name` separately are on `view: \"full\"` |\n\n### Groups\n| Tool | Description |\n|------|-------------|\n| `sw_list_groups(view?)` | List all groups with `id`, `name`, `group_type`, `members[]`, `simplified_debts` and `invite_link`. See [Response shape](#response-shape-view) — this is the response that does not fit at all on `full` |\n| `sw_get_group(id, view?)` | Get a single group's details including members and balances |\n| `sw_create_group(name, group_type?, simplify_by_default?)` | Create a new group (`group_type`: `apartment`, `house`, `trip`, `other`) |\n| `sw_add_user_to_group(group_id, user_id?)` | Add a user by `user_id` (preferred) or `first_name` + `last_name` + `email` |\n| `sw_remove_user_from_group(group_id, user_id)` | Remove a user from a group |\n\n### Friends\n| Tool | Description |\n|------|-------------|\n| `sw_list_friends(view?)` | List all friends. On the default `compact` rung each is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; the separate name fields are on `view: \"full\"` |\n\n### Expenses\n| Tool | Description |\n|------|-------------|\n| `sw_list_expenses(group_id?, friend_id?, dated_after?, dated_before?, limit?, offset?, view?)` | List or search expenses |\n| `sw_get_expense(id, view?)` | Get full details of a single expense |\n| `sw_create_expense(group_id, description, cost, split_equally? \\| users?)` | Create an expense — equal split or custom per-person split |\n| `sw_update_expense(expense_id, ...)` | Edit an existing expense (custom split requires full `users` array) |\n| `sw_delete_expense(id)` | Soft-delete an expense |\n| `sw_undelete_expense(id)` | Restore a soft-deleted expense |\n\n### Receipts\n| Tool | Description |\n|------|-------------|\n| `sw_get_receipt(id, size?, inline?, extract_text?, output_dir?, write?)` | Download the receipt attached to an expense. `inline: true` returns the bytes in the result (images **and** PDFs); `extract_text: true` returns a PDF's text layer; by default it also writes the file and returns the path |\n\n### Utilities\n| Tool | Description |\n|------|-------------|\n| `sw_get_notifications(view?)` | Recent activity feed for the current user |\n| `sw_get_categories` | Hierarchical list of expense categories (use `id` as `category_id`) |\n| `sw_get_currencies` | List of supported currency codes |\n\n## Response shape (`view`)\n\nNine read tools take `view: \"compact\" | \"full\"`, and **`compact` is the\ndefault** — you get the slim rung without asking. Two of them are not in the\ntable above: `sw_get_user(id, view?)` and `sw_get_comments(expense_id, view?)`.\n\nThis is not a nicety. A live `sw_list_groups` on a 51-group account came back\nas **192,123 characters and was REFUSED by the host before the model saw a byte\nof it** — the tool was not expensive, it was unusable. 60% of that response was\nimage URLs: `avatar` + `tall_avatar` + `cover_photo` (51.7 KB) and a `picture`\nobject per member across 51 groups (37.7 KB). Stripping media alone takes it to\n51.4 KB (−73%); the field projections below take it to 29.3 KB.\n\n**Compact means two different things here, depending on the tool.**\n\n**A hand-written field projection** — `sw_list_groups`, `sw_get_group`,\n`sw_list_friends`, `sw_get_current_user`, `sw_get_user`, `sw_list_expenses`,\n`sw_get_expense`:\n\n- **A person becomes `{id, name, email, registration_status, balance}`, and\n  `name` is `first_name` + `last_name` JOINED.** This is the one that will trip\n  you: reach for `last_name` on the default rung and it is not there. `balance`\n  survives because it is the whole reason to look a person up, and\n  `registration_status` because it is how you know an invite was never\n  accepted.\n- **A group keeps** `{id, name, group_type, updated_at, members[],\n  simplified_debts, invite_link}`. The whiteboard fields and the\n  `simplify_by_default` / `custom_avatar` / `group_reminders` settings go —\n  nothing here reads them. `original_debts` goes because `simplified_debts`\n  answers \"who owes whom\", and the two differ only when simplification is on;\n  `full` has both.\n- **An expense keeps the share breakdown**, as `{id, name, paid_share,\n  owed_share, net_balance}` per person rather than Splitwise's nested `user`\n  object, plus `repayments`, `comments_count` and `category` as a name. Two\n  details matter: `deleted_at` is kept **only when set**, because a deleted\n  expense still comes back from the list endpoint and a caller who cannot see\n  it will count it; and the receipt becomes `has_receipt: true` — the bytes\n  come from `sw_get_receipt`. The eleven-field repeat/reminder/transaction\n  block goes (`repeats`, `next_repeat`, `transaction_status`, …) — it was\n  `false` / `null` / `\"offline\"` on every expense in a live account.\n\n**Media stripping, with no field projection claimed** — `sw_get_notifications`\nand `sw_get_comments`. Compact drops the avatar URLs and touches nothing else.\nDo not expect a named field set from these two; expect the same records minus\nthe pictures.\n\n`view: \"full\"` returns Splitwise's records untouched, everywhere. There is **no\n`raw` rung**: `full` already IS the upstream payload, so a third value could\nonly alias it.\n\n**A projection that trips returns the rows WHOLE**, and for the entire array\nrather than per record — one odd record projected to nothing among fifty good\nones is a hole in the middle of an answer, and indistinguishable from an\nexpense with no content. So a fat response is a possible outcome; a quietly\ngappy one is not.\n\nThe other eighteen tools take no `view`, each for its own reason:\n\n- **`sw_get_receipt`** is the one tool the media rung is documented never to\n  touch: its PRODUCT is the image. Stripping there would not shrink the answer,\n  it would delete it.\n- **`sw_get_categories` and `sw_get_currencies`** are static reference lists —\n  already narrow, no media, and every field on them is the answer.\n- **`sw_healthcheck`** answers reachability and auth.\n- **The fourteen writes** (`sw_create_expense`, `sw_update_expense`,\n  `sw_delete_expense`, `sw_undelete_expense`, `sw_create_group`,\n  `sw_delete_group`, `sw_undelete_group`, `sw_add_user_to_group`,\n  `sw_remove_user_from_group`, `sw_create_friend`, `sw_delete_friend`,\n  `sw_create_comment`, `sw_delete_comment`, `sw_update_user`) return receipts —\n  an id, a status — with nothing to strip and everything to keep.\n\n## Workflows\n\n**Add an expense to a group:**\n```\nsw_list_groups → find group ID for \"vacation\"\nsw_create_expense(group_id, \"Dinner\", \"80.00\", split_equally: true)\n```\n\n**Add someone to a group:**\n```\nsw_list_friends → find Meredith's user_id\nsw_get_group(id) → check if Meredith is already in members[]\nsw_add_user_to_group(group_id, user_id) → if not\n```\n\n**Custom split (you paid, split 60/40):**\n```\nsw_get_current_user → your user_id\nsw_list_friends → other person's user_id\nsw_create_expense(group_id, \"Hotel\", \"200.00\", users: [\n  { user_id: yours, paid_share: \"200.00\", owed_share: \"120.00\" },\n  { user_id: theirs, paid_share: \"0.00\", owed_share: \"80.00\" }\n])\n```\n\n**Get the receipt for an expense:**\n```\nsw_list_expenses(...) → find expense ID\nsw_get_receipt(id, extract_text: true) → line items and totals as text\nsw_get_receipt(id, inline: true)       → the actual bytes, when you need to see it\nsw_get_receipt(id)                     → writes e.g. ./splitwise-receipt-4644814211.pdf\n```\n\n**Search and edit an expense:**\n```\nsw_list_expenses(group_id, dated_after: \"2026-01-01\") → find expense ID\nsw_update_expense(expense_id, description: \"Corrected description\", cost: \"95.00\")\n```\n\n## Notes\n\n- `cost` is always a decimal string (e.g. `\"25.00\"`)\n- `split_equally: true` and `users` array are mutually exclusive\n- For custom split updates, the **full `users` array is required** — the API replaces the entire split\n- `sw_delete_expense` is a soft delete — restore with `sw_undelete_expense`\n- The `receipt.original` / `receipt.large` URLs on an expense are **not public** — fetching them without the API key returns 401. Always use `sw_get_receipt`, which fetches them with the server's own credentials\n- `sw_get_receipt` writes into `output_dir`, else `$SPLITWISE_OUTPUT_DIR`, else the working directory, and never overwrites an existing file\n- That path is on the **server's** filesystem. If you can't read it — a hosted or containerised server — use `inline: true` (bytes) or `extract_text: true` (PDF text) instead of the path\n- `extract_text` only works on PDFs, and only when the PDF has a text layer; a scanned or photographed receipt returns `text_note` instead, and needs `inline: true` to read\n- API default for `sw_list_expenses` is 20 results when `limit` is omitted\n\nFile v3.1.1:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"splitwise-mcp\",\n  \"version\": \"3.1.1\",\n  \"publishedAt\": 1790178072122\n}\n\nFile v3.1.1:skill-card.md\n\n## Description:\n\nAccess Splitwise expense, group, friend, balance, receipt, and notification data through a registered splitwise-mcp MCP server, including supported create, edit, delete, and membership workflows.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal users and developers use this skill to let an agent inspect Splitwise balances, expenses, groups, friends, receipts, categories, currencies, and notifications, and to perform documented Splitwise write workflows when authorized.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can change Splitwise financial records and group membership through write tools.\n\nMitigation: Before using write tools, require the agent to summarize the exact expense, amount, split, group, user, or deletion and wait for explicit confirmation.\n\nRisk: The skill requires API-key access to the user's Splitwise account.\n\nMitigation: Install only if the splitwise-mcp package is trusted and the user is comfortable granting that account access.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/chrischall/skills/splitwise-mcp)\n- [splitwise-mcp npm package](https://www.npmjs.com/package/splitwise-mcp)\n- [Splitwise app registration](https://secure.splitwise.com/apps/register)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, API Calls, Text, Files, Configuration]\n\n**Output Format:** [Markdown and structured MCP tool calls, with optional downloaded receipt files]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Uses compact response views by default for supported read tools; receipt handling may return text, inline bytes, or a server file path.]\n\n## Skill Version(s):\n\n3.1.1 (source: release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.1.0: 3 files, 6143 bytes\n\nFiles: skill-card.md (2503b), SKILL.md (10909b), _meta.json (132b)\n\nFile v3.1.0:SKILL.md\n\n---\nname: splitwise-mcp\ndescription: Access Splitwise expense and group data via MCP. Use when the user asks about Splitwise expenses, groups, friends, or balances, or wants to add, edit, or delete expenses. Triggers on phrases like \"add that expense to Splitwise\", \"split this with the vacation group\", \"make sure Meredith is in that group\", \"what do I owe\", or any request involving shared expenses or group management in Splitwise. Requires splitwise-mcp installed and the splitwise server registered (see Setup below).\n---\n\n# splitwise-mcp\n\nMCP server for Splitwise — natural-language expense and group management via the Splitwise API.\n\n- **npm:** [npmjs.com/package/splitwise-mcp](https://www.npmjs.com/package/splitwise-mcp)\n- **Source:** [github.com/chrischall/splitwise-mcp](https://github.com/chrischall/splitwise-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"splitwise-mcp\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/splitwise-mcp\ncd splitwise-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/splitwise-mcp/dist/index.js\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `SPLITWISE_API_KEY=<value>`.\n\n### Getting your API key\n\n1. Go to [splitwise.com/apps/register](https://secure.splitwise.com/apps/register)\n2. Register an app (name and description can be anything)\n3. Copy the **API key** from the app detail page\n\n## Authentication\n\nAPI key auth — no login flow or token rotation. The key is attached to every request as `Authorization: Bearer <key>`.\n\n## Tools\n\n### User\n| Tool | Description |\n|------|-------------|\n| `sw_get_current_user(view?)` | Get the authenticated user's profile. On the default `compact` rung that is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; `first_name` / `last_name` separately are on `view: \"full\"` |\n\n### Groups\n| Tool | Description |\n|------|-------------|\n| `sw_list_groups(view?)` | List all groups with `id`, `name`, `group_type`, `members[]`, `simplified_debts` and `invite_link`. See [Response shape](#response-shape-view) — this is the response that does not fit at all on `full` |\n| `sw_get_group(id, view?)` | Get a single group's details including members and balances |\n| `sw_create_group(name, group_type?, simplify_by_default?)` | Create a new group (`group_type`: `apartment`, `house`, `trip`, `other`) |\n| `sw_add_user_to_group(group_id, user_id?)` | Add a user by `user_id` (preferred) or `first_name` + `last_name` + `email` |\n| `sw_remove_user_from_group(group_id, user_id)` | Remove a user from a group |\n\n### Friends\n| Tool | Description |\n|------|-------------|\n| `sw_list_friends(view?)` | List all friends. On the default `compact` rung each is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; the separate name fields are on `view: \"full\"` |\n\n### Expenses\n| Tool | Description |\n|------|-------------|\n| `sw_list_expenses(group_id?, friend_id?, dated_after?, dated_before?, limit?, offset?, view?)` | List or search expenses |\n| `sw_get_expense(id, view?)` | Get full details of a single expense |\n| `sw_create_expense(group_id, description, cost, split_equally? \\| users?)` | Create an expense — equal split or custom per-person split |\n| `sw_update_expense(expense_id, ...)` | Edit an existing expense (custom split requires full `users` array) |\n| `sw_delete_expense(id)` | Soft-delete an expense |\n| `sw_undelete_expense(id)` | Restore a soft-deleted expense |\n\n### Receipts\n| Tool | Description |\n|------|-------------|\n| `sw_get_receipt(id, size?, inline?, extract_text?, output_dir?, write?)` | Download the receipt attached to an expense. `inline: true` returns the bytes in the result (images **and** PDFs); `extract_text: true` returns a PDF's text layer; by default it also writes the file and returns the path |\n\n### Utilities\n| Tool | Description |\n|------|-------------|\n| `sw_get_notifications(view?)` | Recent activity feed for the current user |\n| `sw_get_categories` | Hierarchical list of expense categories (use `id` as `category_id`) |\n| `sw_get_currencies` | List of supported currency codes |\n\n## Response shape (`view`)\n\nNine read tools take `view: \"compact\" | \"full\"`, and **`compact` is the\ndefault** — you get the slim rung without asking. Two of them are not in the\ntable above: `sw_get_user(id, view?)` and `sw_get_comments(expense_id, view?)`.\n\nThis is not a nicety. A live `sw_list_groups` on a 51-group account came back\nas **192,123 characters and was REFUSED by the host before the model saw a byte\nof it** — the tool was not expensive, it was unusable. 60% of that response was\nimage URLs: `avatar` + `tall_avatar` + `cover_photo` (51.7 KB) and a `picture`\nobject per member across 51 groups (37.7 KB). Stripping media alone takes it to\n51.4 KB (−73%); the field projections below take it to 29.3 KB.\n\n**Compact means two different things here, depending on the tool.**\n\n**A hand-written field projection** — `sw_list_groups`, `sw_get_group`,\n`sw_list_friends`, `sw_get_current_user`, `sw_get_user`, `sw_list_expenses`,\n`sw_get_expense`:\n\n- **A person becomes `{id, name, email, registration_status, balance}`, and\n  `name` is `first_name` + `last_name` JOINED.** This is the one that will trip\n  you: reach for `last_name` on the default rung and it is not there. `balance`\n  survives because it is the whole reason to look a person up, and\n  `registration_status` because it is how you know an invite was never\n  accepted.\n- **A group keeps** `{id, name, group_type, updated_at, members[],\n  simplified_debts, invite_link}`. The whiteboard fields and the\n  `simplify_by_default` / `custom_avatar` / `group_reminders` settings go —\n  nothing here reads them. `original_debts` goes because `simplified_debts`\n  answers \"who owes whom\", and the two differ only when simplification is on;\n  `full` has both.\n- **An expense keeps the share breakdown**, as `{id, name, paid_share,\n  owed_share, net_balance}` per person rather than Splitwise's nested `user`\n  object, plus `repayments`, `comments_count` and `category` as a name. Two\n  details matter: `deleted_at` is kept **only when set**, because a deleted\n  expense still comes back from the list endpoint and a caller who cannot see\n  it will count it; and the receipt becomes `has_receipt: true` — the bytes\n  come from `sw_get_receipt`. The eleven-field repeat/reminder/transaction\n  block goes (`repeats`, `next_repeat`, `transaction_status`, …) — it was\n  `false` / `null` / `\"offline\"` on every expense in a live account.\n\n**Media stripping, with no field projection claimed** — `sw_get_notifications`\nand `sw_get_comments`. Compact drops the avatar URLs and touches nothing else.\nDo not expect a named field set from these two; expect the same records minus\nthe pictures.\n\n`view: \"full\"` returns Splitwise's records untouched, everywhere. There is **no\n`raw` rung**: `full` already IS the upstream payload, so a third value could\nonly alias it.\n\n**A projection that trips returns the rows WHOLE**, and for the entire array\nrather than per record — one odd record projected to nothing among fifty good\nones is a hole in the middle of an answer, and indistinguishable from an\nexpense with no content. So a fat response is a possible outcome; a quietly\ngappy one is not.\n\nThe other eighteen tools take no `view`, each for its own reason:\n\n- **`sw_get_receipt`** is the one tool the media rung is documented never to\n  touch: its PRODUCT is the image. Stripping there would not shrink the answer,\n  it would delete it.\n- **`sw_get_categories` and `sw_get_currencies`** are static reference lists —\n  already narrow, no media, and every field on them is the answer.\n- **`sw_healthcheck`** answers reachability and auth.\n- **The fourteen writes** (`sw_create_expense`, `sw_update_expense`,\n  `sw_delete_expense`, `sw_undelete_expense`, `sw_create_group`,\n  `sw_delete_group`, `sw_undelete_group`, `sw_add_user_to_group`,\n  `sw_remove_user_from_group`, `sw_create_friend`, `sw_delete_friend`,\n  `sw_create_comment`, `sw_delete_comment`, `sw_update_user`) return receipts —\n  an id, a status — with nothing to strip and everything to keep.\n\n## Workflows\n\n**Add an expense to a group:**\n```\nsw_list_groups → find group ID for \"vacation\"\nsw_create_expense(group_id, \"Dinner\", \"80.00\", split_equally: true)\n```\n\n**Add someone to a group:**\n```\nsw_list_friends → find Meredith's user_id\nsw_get_group(id) → check if Meredith is already in members[]\nsw_add_user_to_group(group_id, user_id) → if not\n```\n\n**Custom split (you paid, split 60/40):**\n```\nsw_get_current_user → your user_id\nsw_list_friends → other person's user_id\nsw_create_expense(group_id, \"Hotel\", \"200.00\", users: [\n  { user_id: yours, paid_share: \"200.00\", owed_share: \"120.00\" },\n  { user_id: theirs, paid_share: \"0.00\", owed_share: \"80.00\" }\n])\n```\n\n**Get the receipt for an expense:**\n```\nsw_list_expenses(...) → find expense ID\nsw_get_receipt(id, extract_text: true) → line items and totals as text\nsw_get_receipt(id, inline: true)       → the actual bytes, when you need to see it\nsw_get_receipt(id)                     → writes e.g. ./splitwise-receipt-4644814211.pdf\n```\n\n**Search and edit an expense:**\n```\nsw_list_expenses(group_id, dated_after: \"2026-01-01\") → find expense ID\nsw_update_expense(expense_id, description: \"Corrected description\", cost: \"95.00\")\n```\n\n## Notes\n\n- `cost` is always a decimal string (e.g. `\"25.00\"`)\n- `split_equally: true` and `users` array are mutually exclusive\n- For custom split updates, the **full `users` array is required** — the API replaces the entire split\n- `sw_delete_expense` is a soft delete — restore with `sw_undelete_expense`\n- The `receipt.original` / `receipt.large` URLs on an expense are **not public** — fetching them without the API key returns 401. Always use `sw_get_receipt`, which fetches them with the server's own credentials\n- `sw_get_receipt` writes into `output_dir`, else `$SPLITWISE_OUTPUT_DIR`, else the working directory, and never overwrites an existing file\n- That path is on the **server's** filesystem. If you can't read it — a hosted or containerised server — use `inline: true` (bytes) or `extract_text: true` (PDF text) instead of the path\n- `extract_text` only works on PDFs, and only when the PDF has a text layer; a scanned or photographed receipt returns `text_note` instead, and needs `inline: true` to read\n- API default for `sw_list_expenses` is 20 results when `limit` is omitted\n\nFile v3.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"splitwise-mcp\",\n  \"version\": \"3.1.0\",\n  \"publishedAt\": 1789873250296\n}\n\nFile v3.1.0:skill-card.md\n\n## Description:\n\nAccess Splitwise expense and group data via MCP, including reading balances, groups, friends, and expenses and adding, editing, or deleting expense records.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agents use this skill to connect a configured Splitwise MCP server so users can query shared-expense data and perform account, group, friend, receipt, comment, and expense workflows through natural language.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill exposes Splitwise operations that can make real account, group, friend, comment, receipt, user, and expense changes.\n\nMitigation: Review requested actions before invoking write tools, scope the API key to the intended account, and reserve installation for agents trusted to manage Splitwise data.\n\nRisk: Receipt download options can write files to the MCP server filesystem by default.\n\nMitigation: Prefer inline receipt bytes or PDF text extraction when filesystem access is not intended, and set an explicit output directory when writing files is necessary.\n\nRisk: The ClawHub security verdict is suspicious because the account-changing surface is broader than the main description makes clear.\n\nMitigation: Review the full tool list and security guidance before installation, especially if the agent should have only expense-level access.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/chrischall/skills/splitwise-mcp)\n- [Publisher profile](https://clawhub.ai/user/chrischall)\n- [npm package](https://www.npmjs.com/package/splitwise-mcp)\n- [Splitwise app registration](https://secure.splitwise.com/apps/register)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown with JSON and shell command examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Produces MCP setup guidance and tool-use guidance; configured tool calls may read or change Splitwise account data and can download receipt files.]\n\n## Skill Version(s):\n\n3.1.0 (source: release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.0.0: 3 files, 6085 bytes\n\nFiles: skill-card.md (2366b), SKILL.md (10909b), _meta.json (132b)\n\nFile v3.0.0:SKILL.md\n\n---\nname: splitwise-mcp\ndescription: Access Splitwise expense and group data via MCP. Use when the user asks about Splitwise expenses, groups, friends, or balances, or wants to add, edit, or delete expenses. Triggers on phrases like \"add that expense to Splitwise\", \"split this with the vacation group\", \"make sure Meredith is in that group\", \"what do I owe\", or any request involving shared expenses or group management in Splitwise. Requires splitwise-mcp installed and the splitwise server registered (see Setup below).\n---\n\n# splitwise-mcp\n\nMCP server for Splitwise — natural-language expense and group management via the Splitwise API.\n\n- **npm:** [npmjs.com/package/splitwise-mcp](https://www.npmjs.com/package/splitwise-mcp)\n- **Source:** [github.com/chrischall/splitwise-mcp](https://github.com/chrischall/splitwise-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"splitwise-mcp\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/splitwise-mcp\ncd splitwise-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/splitwise-mcp/dist/index.js\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `SPLITWISE_API_KEY=<value>`.\n\n### Getting your API key\n\n1. Go to [splitwise.com/apps/register](https://secure.splitwise.com/apps/register)\n2. Register an app (name and description can be anything)\n3. Copy the **API key** from the app detail page\n\n## Authentication\n\nAPI key auth — no login flow or token rotation. The key is attached to every request as `Authorization: Bearer <key>`.\n\n## Tools\n\n### User\n| Tool | Description |\n|------|-------------|\n| `sw_get_current_user(view?)` | Get the authenticated user's profile. On the default `compact` rung that is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; `first_name` / `last_name` separately are on `view: \"full\"` |\n\n### Groups\n| Tool | Description |\n|------|-------------|\n| `sw_list_groups(view?)` | List all groups with `id`, `name`, `group_type`, `members[]`, `simplified_debts` and `invite_link`. See [Response shape](#response-shape-view) — this is the response that does not fit at all on `full` |\n| `sw_get_group(id, view?)` | Get a single group's details including members and balances |\n| `sw_create_group(name, group_type?, simplify_by_default?)` | Create a new group (`group_type`: `apartment`, `house`, `trip`, `other`) |\n| `sw_add_user_to_group(group_id, user_id?)` | Add a user by `user_id` (preferred) or `first_name` + `last_name` + `email` |\n| `sw_remove_user_from_group(group_id, user_id)` | Remove a user from a group |\n\n### Friends\n| Tool | Description |\n|------|-------------|\n| `sw_list_friends(view?)` | List all friends. On the default `compact` rung each is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; the separate name fields are on `view: \"full\"` |\n\n### Expenses\n| Tool | Description |\n|------|-------------|\n| `sw_list_expenses(group_id?, friend_id?, dated_after?, dated_before?, limit?, offset?, view?)` | List or search expenses |\n| `sw_get_expense(id, view?)` | Get full details of a single expense |\n| `sw_create_expense(group_id, description, cost, split_equally? \\| users?)` | Create an expense — equal split or custom per-person split |\n| `sw_update_expense(expense_id, ...)` | Edit an existing expense (custom split requires full `users` array) |\n| `sw_delete_expense(id)` | Soft-delete an expense |\n| `sw_undelete_expense(id)` | Restore a soft-deleted expense |\n\n### Receipts\n| Tool | Description |\n|------|-------------|\n| `sw_get_receipt(id, size?, inline?, extract_text?, output_dir?, write?)` | Download the receipt attached to an expense. `inline: true` returns the bytes in the result (images **and** PDFs); `extract_text: true` returns a PDF's text layer; by default it also writes the file and returns the path |\n\n### Utilities\n| Tool | Description |\n|------|-------------|\n| `sw_get_notifications(view?)` | Recent activity feed for the current user |\n| `sw_get_categories` | Hierarchical list of expense categories (use `id` as `category_id`) |\n| `sw_get_currencies` | List of supported currency codes |\n\n## Response shape (`view`)\n\nNine read tools take `view: \"compact\" | \"full\"`, and **`compact` is the\ndefault** — you get the slim rung without asking. Two of them are not in the\ntable above: `sw_get_user(id, view?)` and `sw_get_comments(expense_id, view?)`.\n\nThis is not a nicety. A live `sw_list_groups` on a 51-group account came back\nas **192,123 characters and was REFUSED by the host before the model saw a byte\nof it** — the tool was not expensive, it was unusable. 60% of that response was\nimage URLs: `avatar` + `tall_avatar` + `cover_photo` (51.7 KB) and a `picture`\nobject per member across 51 groups (37.7 KB). Stripping media alone takes it to\n51.4 KB (−73%); the field projections below take it to 29.3 KB.\n\n**Compact means two different things here, depending on the tool.**\n\n**A hand-written field projection** — `sw_list_groups`, `sw_get_group`,\n`sw_list_friends`, `sw_get_current_user`, `sw_get_user`, `sw_list_expenses`,\n`sw_get_expense`:\n\n- **A person becomes `{id, name, email, registration_status, balance}`, and\n  `name` is `first_name` + `last_name` JOINED.** This is the one that will trip\n  you: reach for `last_name` on the default rung and it is not there. `balance`\n  survives because it is the whole reason to look a person up, and\n  `registration_status` because it is how you know an invite was never\n  accepted.\n- **A group keeps** `{id, name, group_type, updated_at, members[],\n  simplified_debts, invite_link}`. The whiteboard fields and the\n  `simplify_by_default` / `custom_avatar` / `group_reminders` settings go —\n  nothing here reads them. `original_debts` goes because `simplified_debts`\n  answers \"who owes whom\", and the two differ only when simplification is on;\n  `full` has both.\n- **An expense keeps the share breakdown**, as `{id, name, paid_share,\n  owed_share, net_balance}` per person rather than Splitwise's nested `user`\n  object, plus `repayments`, `comments_count` and `category` as a name. Two\n  details matter: `deleted_at` is kept **only when set**, because a deleted\n  expense still comes back from the list endpoint and a caller who cannot see\n  it will count it; and the receipt becomes `has_receipt: true` — the bytes\n  come from `sw_get_receipt`. The eleven-field repeat/reminder/transaction\n  block goes (`repeats`, `next_repeat`, `transaction_status`, …) — it was\n  `false` / `null` / `\"offline\"` on every expense in a live account.\n\n**Media stripping, with no field projection claimed** — `sw_get_notifications`\nand `sw_get_comments`. Compact drops the avatar URLs and touches nothing else.\nDo not expect a named field set from these two; expect the same records minus\nthe pictures.\n\n`view: \"full\"` returns Splitwise's records untouched, everywhere. There is **no\n`raw` rung**: `full` already IS the upstream payload, so a third value could\nonly alias it.\n\n**A projection that trips returns the rows WHOLE**, and for the entire array\nrather than per record — one odd record projected to nothing among fifty good\nones is a hole in the middle of an answer, and indistinguishable from an\nexpense with no content. So a fat response is a possible outcome; a quietly\ngappy one is not.\n\nThe other eighteen tools take no `view`, each for its own reason:\n\n- **`sw_get_receipt`** is the one tool the media rung is documented never to\n  touch: its PRODUCT is the image. Stripping there would not shrink the answer,\n  it would delete it.\n- **`sw_get_categories` and `sw_get_currencies`** are static reference lists —\n  already narrow, no media, and every field on them is the answer.\n- **`sw_healthcheck`** answers reachability and auth.\n- **The fourteen writes** (`sw_create_expense`, `sw_update_expense`,\n  `sw_delete_expense`, `sw_undelete_expense`, `sw_create_group`,\n  `sw_delete_group`, `sw_undelete_group`, `sw_add_user_to_group`,\n  `sw_remove_user_from_group`, `sw_create_friend`, `sw_delete_friend`,\n  `sw_create_comment`, `sw_delete_comment`, `sw_update_user`) return receipts —\n  an id, a status — with nothing to strip and everything to keep.\n\n## Workflows\n\n**Add an expense to a group:**\n```\nsw_list_groups → find group ID for \"vacation\"\nsw_create_expense(group_id, \"Dinner\", \"80.00\", split_equally: true)\n```\n\n**Add someone to a group:**\n```\nsw_list_friends → find Meredith's user_id\nsw_get_group(id) → check if Meredith is already in members[]\nsw_add_user_to_group(group_id, user_id) → if not\n```\n\n**Custom split (you paid, split 60/40):**\n```\nsw_get_current_user → your user_id\nsw_list_friends → other person's user_id\nsw_create_expense(group_id, \"Hotel\", \"200.00\", users: [\n  { user_id: yours, paid_share: \"200.00\", owed_share: \"120.00\" },\n  { user_id: theirs, paid_share: \"0.00\", owed_share: \"80.00\" }\n])\n```\n\n**Get the receipt for an expense:**\n```\nsw_list_expenses(...) → find expense ID\nsw_get_receipt(id, extract_text: true) → line items and totals as text\nsw_get_receipt(id, inline: true)       → the actual bytes, when you need to see it\nsw_get_receipt(id)                     → writes e.g. ./splitwise-receipt-4644814211.pdf\n```\n\n**Search and edit an expense:**\n```\nsw_list_expenses(group_id, dated_after: \"2026-01-01\") → find expense ID\nsw_update_expense(expense_id, description: \"Corrected description\", cost: \"95.00\")\n```\n\n## Notes\n\n- `cost` is always a decimal string (e.g. `\"25.00\"`)\n- `split_equally: true` and `users` array are mutually exclusive\n- For custom split updates, the **full `users` array is required** — the API replaces the entire split\n- `sw_delete_expense` is a soft delete — restore with `sw_undelete_expense`\n- The `receipt.original` / `receipt.large` URLs on an expense are **not public** — fetching them without the API key returns 401. Always use `sw_get_receipt`, which fetches them with the server's own credentials\n- `sw_get_receipt` writes into `output_dir`, else `$SPLITWISE_OUTPUT_DIR`, else the working directory, and never overwrites an existing file\n- That path is on the **server's** filesystem. If you can't read it — a hosted or containerised server — use `inline: true` (bytes) or `extract_text: true` (PDF text) instead of the path\n- `extract_text` only works on PDFs, and only when the PDF has a text layer; a scanned or photographed receipt returns `text_note` instead, and needs `inline: true` to read\n- API default for `sw_list_expenses` is 20 results when `limit` is omitted\n\nFile v3.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"splitwise-mcp\",\n  \"version\": \"3.0.0\",\n  \"publishedAt\": 1789688300367\n}\n\nFile v3.0.0:skill-card.md\n\n## Description:\n\nAccess Splitwise expense, group, friend, receipt, and balance data through an MCP server, including supported create, update, delete, and restore actions.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal users and developers use this skill to let an agent query and manage Splitwise shared expenses, groups, friends, receipts, and balances through registered MCP tools.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The MCP server can create, update, delete, or restore Splitwise expenses and can modify groups, friends, comments, and profile data.\n\nMitigation: Require explicit user confirmation before any write, delete, restore, or profile-changing action.\n\nRisk: The Splitwise API key grants account access to the MCP server.\n\nMitigation: Store SPLITWISE_API_KEY as a protected credential and avoid exposing it in prompts, logs, shared configuration, or committed files.\n\nRisk: Receipt retrieval writes files to disk by default and returns server-side paths that may not be readable in hosted or containerized environments.\n\nMitigation: Use inline or text receipt retrieval unless file output is intentional, and set an explicit output directory when writing receipts.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/chrischall/skills/splitwise-mcp)\n- [npm package: splitwise-mcp](https://www.npmjs.com/package/splitwise-mcp)\n- [Splitwise app registration](https://secure.splitwise.com/apps/register)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown and plain text with JSON configuration and inline shell commands]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [MCP tool results may include Splitwise records, action receipts, receipt text, receipt bytes, or server-side file paths depending on the selected tool options.]\n\n## Skill Version(s):\n\n3.0.0 (source: server-resolved release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v2.4.2: 3 files, 6105 bytes\n\nFiles: skill-card.md (2410b), SKILL.md (10909b), _meta.json (132b)\n\nFile v2.4.2:SKILL.md\n\n---\nname: splitwise-mcp\ndescription: Access Splitwise expense and group data via MCP. Use when the user asks about Splitwise expenses, groups, friends, or balances, or wants to add, edit, or delete expenses. Triggers on phrases like \"add that expense to Splitwise\", \"split this with the vacation group\", \"make sure Meredith is in that group\", \"what do I owe\", or any request involving shared expenses or group management in Splitwise. Requires splitwise-mcp installed and the splitwise server registered (see Setup below).\n---\n\n# splitwise-mcp\n\nMCP server for Splitwise — natural-language expense and group management via the Splitwise API.\n\n- **npm:** [npmjs.com/package/splitwise-mcp](https://www.npmjs.com/package/splitwise-mcp)\n- **Source:** [github.com/chrischall/splitwise-mcp](https://github.com/chrischall/splitwise-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"splitwise-mcp\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/splitwise-mcp\ncd splitwise-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/splitwise-mcp/dist/index.js\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `SPLITWISE_API_KEY=<value>`.\n\n### Getting your API key\n\n1. Go to [splitwise.com/apps/register](https://secure.splitwise.com/apps/register)\n2. Register an app (name and description can be anything)\n3. Copy the **API key** from the app detail page\n\n## Authentication\n\nAPI key auth — no login flow or token rotation. The key is attached to every request as `Authorization: Bearer <key>`.\n\n## Tools\n\n### User\n| Tool | Description |\n|------|-------------|\n| `sw_get_current_user(view?)` | Get the authenticated user's profile. On the default `compact` rung that is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; `first_name` / `last_name` separately are on `view: \"full\"` |\n\n### Groups\n| Tool | Description |\n|------|-------------|\n| `sw_list_groups(view?)` | List all groups with `id`, `name`, `group_type`, `members[]`, `simplified_debts` and `invite_link`. See [Response shape](#response-shape-view) — this is the response that does not fit at all on `full` |\n| `sw_get_group(id, view?)` | Get a single group's details including members and balances |\n| `sw_create_group(name, group_type?, simplify_by_default?)` | Create a new group (`group_type`: `apartment`, `house`, `trip`, `other`) |\n| `sw_add_user_to_group(group_id, user_id?)` | Add a user by `user_id` (preferred) or `first_name` + `last_name` + `email` |\n| `sw_remove_user_from_group(group_id, user_id)` | Remove a user from a group |\n\n### Friends\n| Tool | Description |\n|------|-------------|\n| `sw_list_friends(view?)` | List all friends. On the default `compact` rung each is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; the separate name fields are on `view: \"full\"` |\n\n### Expenses\n| Tool | Description |\n|------|-------------|\n| `sw_list_expenses(group_id?, friend_id?, dated_after?, dated_before?, limit?, offset?, view?)` | List or search expenses |\n| `sw_get_expense(id, view?)` | Get full details of a single expense |\n| `sw_create_expense(group_id, description, cost, split_equally? \\| users?)` | Create an expense — equal split or custom per-person split |\n| `sw_update_expense(expense_id, ...)` | Edit an existing expense (custom split requires full `users` array) |\n| `sw_delete_expense(id)` | Soft-delete an expense |\n| `sw_undelete_expense(id)` | Restore a soft-deleted expense |\n\n### Receipts\n| Tool | Description |\n|------|-------------|\n| `sw_get_receipt(id, size?, inline?, extract_text?, output_dir?, write?)` | Download the receipt attached to an expense. `inline: true` returns the bytes in the result (images **and** PDFs); `extract_text: true` returns a PDF's text layer; by default it also writes the file and returns the path |\n\n### Utilities\n| Tool | Description |\n|------|-------------|\n| `sw_get_notifications(view?)` | Recent activity feed for the current user |\n| `sw_get_categories` | Hierarchical list of expense categories (use `id` as `category_id`) |\n| `sw_get_currencies` | List of supported currency codes |\n\n## Response shape (`view`)\n\nNine read tools take `view: \"compact\" | \"full\"`, and **`compact` is the\ndefault** — you get the slim rung without asking. Two of them are not in the\ntable above: `sw_get_user(id, view?)` and `sw_get_comments(expense_id, view?)`.\n\nThis is not a nicety. A live `sw_list_groups` on a 51-group account came back\nas **192,123 characters and was REFUSED by the host before the model saw a byte\nof it** — the tool was not expensive, it was unusable. 60% of that response was\nimage URLs: `avatar` + `tall_avatar` + `cover_photo` (51.7 KB) and a `picture`\nobject per member across 51 groups (37.7 KB). Stripping media alone takes it to\n51.4 KB (−73%); the field projections below take it to 29.3 KB.\n\n**Compact means two different things here, depending on the tool.**\n\n**A hand-written field projection** — `sw_list_groups`, `sw_get_group`,\n`sw_list_friends`, `sw_get_current_user`, `sw_get_user`, `sw_list_expenses`,\n`sw_get_expense`:\n\n- **A person becomes `{id, name, email, registration_status, balance}`, and\n  `name` is `first_name` + `last_name` JOINED.** This is the one that will trip\n  you: reach for `last_name` on the default rung and it is not there. `balance`\n  survives because it is the whole reason to look a person up, and\n  `registration_status` because it is how you know an invite was never\n  accepted.\n- **A group keeps** `{id, name, group_type, updated_at, members[],\n  simplified_debts, invite_link}`. The whiteboard fields and the\n  `simplify_by_default` / `custom_avatar` / `group_reminders` settings go —\n  nothing here reads them. `original_debts` goes because `simplified_debts`\n  answers \"who owes whom\", and the two differ only when simplification is on;\n  `full` has both.\n- **An expense keeps the share breakdown**, as `{id, name, paid_share,\n  owed_share, net_balance}` per person rather than Splitwise's nested `user`\n  object, plus `repayments`, `comments_count` and `category` as a name. Two\n  details matter: `deleted_at` is kept **only when set**, because a deleted\n  expense still comes back from the list endpoint and a caller who cannot see\n  it will count it; and the receipt becomes `has_receipt: true` — the bytes\n  come from `sw_get_receipt`. The eleven-field repeat/reminder/transaction\n  block goes (`repeats`, `next_repeat`, `transaction_status`, …) — it was\n  `false` / `null` / `\"offline\"` on every expense in a live account.\n\n**Media stripping, with no field projection claimed** — `sw_get_notifications`\nand `sw_get_comments`. Compact drops the avatar URLs and touches nothing else.\nDo not expect a named field set from these two; expect the same records minus\nthe pictures.\n\n`view: \"full\"` returns Splitwise's records untouched, everywhere. There is **no\n`raw` rung**: `full` already IS the upstream payload, so a third value could\nonly alias it.\n\n**A projection that trips returns the rows WHOLE**, and for the entire array\nrather than per record — one odd record projected to nothing among fifty good\nones is a hole in the middle of an answer, and indistinguishable from an\nexpense with no content. So a fat response is a possible outcome; a quietly\ngappy one is not.\n\nThe other eighteen tools take no `view`, each for its own reason:\n\n- **`sw_get_receipt`** is the one tool the media rung is documented never to\n  touch: its PRODUCT is the image. Stripping there would not shrink the answer,\n  it would delete it.\n- **`sw_get_categories` and `sw_get_currencies`** are static reference lists —\n  already narrow, no media, and every field on them is the answer.\n- **`sw_healthcheck`** answers reachability and auth.\n- **The fourteen writes** (`sw_create_expense`, `sw_update_expense`,\n  `sw_delete_expense`, `sw_undelete_expense`, `sw_create_group`,\n  `sw_delete_group`, `sw_undelete_group`, `sw_add_user_to_group`,\n  `sw_remove_user_from_group`, `sw_create_friend`, `sw_delete_friend`,\n  `sw_create_comment`, `sw_delete_comment`, `sw_update_user`) return receipts —\n  an id, a status — with nothing to strip and everything to keep.\n\n## Workflows\n\n**Add an expense to a group:**\n```\nsw_list_groups → find group ID for \"vacation\"\nsw_create_expense(group_id, \"Dinner\", \"80.00\", split_equally: true)\n```\n\n**Add someone to a group:**\n```\nsw_list_friends → find Meredith's user_id\nsw_get_group(id) → check if Meredith is already in members[]\nsw_add_user_to_group(group_id, user_id) → if not\n```\n\n**Custom split (you paid, split 60/40):**\n```\nsw_get_current_user → your user_id\nsw_list_friends → other person's user_id\nsw_create_expense(group_id, \"Hotel\", \"200.00\", users: [\n  { user_id: yours, paid_share: \"200.00\", owed_share: \"120.00\" },\n  { user_id: theirs, paid_share: \"0.00\", owed_share: \"80.00\" }\n])\n```\n\n**Get the receipt for an expense:**\n```\nsw_list_expenses(...) → find expense ID\nsw_get_receipt(id, extract_text: true) → line items and totals as text\nsw_get_receipt(id, inline: true)       → the actual bytes, when you need to see it\nsw_get_receipt(id)                     → writes e.g. ./splitwise-receipt-4644814211.pdf\n```\n\n**Search and edit an expense:**\n```\nsw_list_expenses(group_id, dated_after: \"2026-01-01\") → find expense ID\nsw_update_expense(expense_id, description: \"Corrected description\", cost: \"95.00\")\n```\n\n## Notes\n\n- `cost` is always a decimal string (e.g. `\"25.00\"`)\n- `split_equally: true` and `users` array are mutually exclusive\n- For custom split updates, the **full `users` array is required** — the API replaces the entire split\n- `sw_delete_expense` is a soft delete — restore with `sw_undelete_expense`\n- The `receipt.original` / `receipt.large` URLs on an expense are **not public** — fetching them without the API key returns 401. Always use `sw_get_receipt`, which fetches them with the server's own credentials\n- `sw_get_receipt` writes into `output_dir`, else `$SPLITWISE_OUTPUT_DIR`, else the working directory, and never overwrites an existing file\n- That path is on the **server's** filesystem. If you can't read it — a hosted or containerised server — use `inline: true` (bytes) or `extract_text: true` (PDF text) instead of the path\n- `extract_text` only works on PDFs, and only when the PDF has a text layer; a scanned or photographed receipt returns `text_note` instead, and needs `inline: true` to read\n- API default for `sw_list_expenses` is 20 results when `limit` is omitted\n\nFile v2.4.2:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"splitwise-mcp\",\n  \"version\": \"2.4.2\",\n  \"publishedAt\": 1789063104273\n}\n\nFile v2.4.2:skill-card.md\n\n## Description:\n\nsplitwise-mcp lets agents access Splitwise expense, group, friend, balance, receipt, and activity data through an MCP server, including actions that create, update, delete, or restore Splitwise records when configured with an API key.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agent users use this skill to connect an assistant to Splitwise for shared-expense lookup and group management. It supports balance checks, expense creation or edits, friend and group changes, comments, receipt retrieval, and compact response handling for large Splitwise accounts.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can change financial records and account-related Splitwise data.\n\nMitigation: Require manual confirmation before create, update, delete, restore, comment, group, friend, or receipt file-write actions.\n\nRisk: The setup uses a Splitwise API key with access to expense, friend, group, comment, and receipt data.\n\nMitigation: Store the key outside committed files and avoid committing .mcp.json or .env when they contain credentials.\n\nRisk: The recommended npx setup may install an unpinned package version.\n\nMitigation: Pin a reviewed splitwise-mcp package version or commit before deployment.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/chrischall/skills/splitwise-mcp)\n- [npm package](https://www.npmjs.com/package/splitwise-mcp)\n- [Splitwise app registration](https://secure.splitwise.com/apps/register)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with JSON configuration snippets, shell commands, and MCP tool usage guidance.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Requires a registered splitwise-mcp server and SPLITWISE_API_KEY; receipt retrieval can return inline bytes, extracted text, or a server-side file path.]\n\n## Skill Version(s):\n\n2.4.2 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.","readmeExcerpt":"Skill: splitwise-mcp Owner: chrischall Summary: Access Splitwise expense and group data via MCP. Use when the user asks about Splitwise expenses, groups, friends, or balances, or wants to add, edit, or delete expenses. Triggers on phrases like \"add that expense to Splitwise\", \"split this with the vacation group\", \"make sure Meredith is in that group\", \"what do I owe\", or any request involving shared expenses or group","codeSnippets":[],"executableExamples":[{"language":"json","snippet":"{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"splitwise-mcp\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}"},{"language":"bash","snippet":"git clone https://github.com/chrischall/splitwise-mcp\ncd splitwise-mcp\nnpm install && npm run build"},{"language":"json","snippet":"{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/splitwise-mcp/dist/index.js\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}"},{"language":"text","snippet":"sw_list_groups → find group ID for \"vacation\"\nsw_create_expense(group_id, \"Dinner\", \"80.00\", split_equally: true)"},{"language":"text","snippet":"sw_list_friends → find Meredith's user_id\nsw_get_group(id) → check if Meredith is already in members[]\nsw_add_user_to_group(group_id, user_id) → if not"},{"language":"text","snippet":"sw_get_current_user → your user_id\nsw_list_friends → other person's user_id\nsw_create_expense(group_id, \"Hotel\", \"200.00\", users: [\n  { user_id: yours, paid_share: \"200.00\", owed_share: \"120.00\" },\n  { user_id: theirs, paid_share: \"0.00\", owed_share: \"80.00\" }\n])"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: splitwise-mcp\ndescription: Access Splitwise expense and group data via MCP. Use when the user asks about Splitwise expenses, groups, friends, or balances, or wants to add, edit, or delete expenses. Triggers on phrases like \"add that expense to Splitwise\", \"split this with the vacation group\", \"make sure Meredith is in that group\", \"what do I owe\", or any request involving shared expenses or group management in Splitwise. Requires splitwise-mcp installed and the splitwise server registered (see Setup below).\n---\n\n# splitwise-mcp\n\nMCP server for Splitwise — natural-language expense and group management via the Splitwise API.\n\n- **npm:** [npmjs.com/package/splitwise-mcp](https://www.npmjs.com/package/splitwise-mcp)\n- **Source:** [github.com/chrischall/splitwise-mcp](https://github.com/chrischall/splitwise-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"splitwise-mcp\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/splitwise-mcp\ncd splitwise-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splitwise\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/splitwise-mcp/dist/index.js\"],\n      \"env\": {\n        \"SPLITWISE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `SPLITWISE_API_KEY=<value>`.\n\n### Getting your API key\n\n1. Go to [splitwise.com/apps/register](https://secure.splitwise.com/apps/register)\n2. Register an app (name and description can be anything)\n3. Copy the **API key** from the app detail page\n\n## Authentication\n\nAPI key auth — no login flow or token rotation. The key is attached to every request as `Authorization: Bearer <key>`.\n\n## Tools\n\n### User\n| Tool | Description |\n|------|-------------|\n| `sw_get_current_user(view?)` | Get the authenticated user's profile. On the default `compact` rung that is `id`, `name` (first + last joined), `email`, `registration_status`, `balance`; `first_name` / `last_name` separately are on `view: \"full\"` |\n\n### Groups\n| Tool | Description |\n|------|-------------|\n| `sw_list_groups(view?)` | List all groups with `id`, `name`, `group_type`, `members[]`, `simplified_debts` and `invite_link`. See [Response shape](#response-shape-view) — this is the response that does not fit at all on `full` |\n| `sw_get_group(id, view?)` | Get a single group's details including members and balances |\n| `sw_create_group(name, group_type?, simplify_by_default?)` | Create a new group (`group_type`: `apartment`, `house`, `trip`, `other`) |\n| `sw_add_user_to_group(group_id, user_id?)` | Add a user by `user_id` (preferred) or `first_name` + `last_name` + `email` |\n| `sw_remove_user_from_group(group_id, user_id)` | Remove a user from a group |\n\n### F"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"splitwise-mcp\",\n  \"version\": \"3.3.0\",\n  \"publishedAt\": 1791380812629\n}"},{"path":"skill-card.md","content":"## Description:\n\nHelps agents use Splitwise to check balances, groups, friends, and expenses and manage shared-expense records through MCP.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nPeople and agents managing shared expenses use this skill to review Splitwise balances and records, add or edit expenses, manage groups and friends, and retrieve receipts.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The installed package receives a Splitwise API key and can read account balances, friends, expenses, and receipts.\n\nMitigation: Confirm that you trust the package before providing it with your Splitwise API key.\n\nRisk: Approved write actions can create, change, delete, or restore Splitwise records.\n\nMitigation: Review the proposed changes and approve writes only when they match your intent.\n\nRisk: Receipt retrieval can save files to the server filesystem.\n\nMitigation: Use inline receipt or text extraction modes when you do not want receipt files saved on the server.\n\n## Reference(s):\n\n- [ClawHub skill listing](https://clawhub.ai/chrischall/skills/splitwise-mcp)\n- [splitwise-mcp npm package](https://www.npmjs.com/package/splitwise-mcp)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, Configuration instructions, Shell commands, MCP tool calls]\n\n**Output Format:** [Markdown with JSON and shell examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Tool results can include Splitwise account data and receipts.]\n\n## Skill Version(s):\n\n3.3.0 (source: ClawHub release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":1183,"uniquenessScore":42,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-09T11:56:13.528Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-09T11:56:13.528Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T04:07:52.603Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}