splitwise-mcp 2.4.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "metadata": {
9
9
  "description": "MCP server for Splitwise — natural-language expense and group management via the Splitwise API",
10
- "version": "2.4.0"
10
+ "version": "2.4.1"
11
11
  },
12
12
  "plugins": [
13
13
  {
@@ -15,7 +15,7 @@
15
15
  "displayName": "Splitwise",
16
16
  "source": "./",
17
17
  "description": "MCP server for Splitwise — manage expenses, groups, and friends via natural language",
18
- "version": "2.4.0",
18
+ "version": "2.4.1",
19
19
  "author": {
20
20
  "name": "Chris Hall"
21
21
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "splitwise-mcp",
3
3
  "displayName": "Splitwise",
4
- "version": "2.4.0",
4
+ "version": "2.4.1",
5
5
  "description": "MCP server for Splitwise — natural-language expense and group management via the Splitwise API",
6
6
  "author": {
7
7
  "name": "Chris Hall",
package/dist/bundle.js CHANGED
@@ -72674,7 +72674,7 @@ function registerUtilityTools(server, client2) {
72674
72674
  // src/index.ts
72675
72675
  await runMcp({
72676
72676
  name: "splitwise-mcp",
72677
- version: "2.4.0",
72677
+ version: "2.4.1",
72678
72678
  // x-release-please-version
72679
72679
  deps: client,
72680
72680
  banner: "[splitwise-mcp] This project was developed and is maintained by AI (Claude Sonnet 4.6). Use at your own discretion.",
package/dist/index.js CHANGED
@@ -19,7 +19,7 @@ import { registerUtilityTools } from './tools/utilities.js';
19
19
  // client into the same registrars instead of this singleton.
20
20
  await runMcp({
21
21
  name: 'splitwise-mcp',
22
- version: '2.4.0', // x-release-please-version
22
+ version: '2.4.1', // x-release-please-version
23
23
  deps: client,
24
24
  banner: '[splitwise-mcp] This project was developed and is maintained by AI (Claude Sonnet 4.6). Use at your own discretion.',
25
25
  tools: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "splitwise-mcp",
3
- "version": "2.4.0",
3
+ "version": "2.4.1",
4
4
  "mcpName": "io.github.chrischall/splitwise-mcp",
5
5
  "description": "Splitwise MCP server for Claude — developed and maintained by AI (Claude Code)",
6
6
  "author": "Claude Code (AI) <https://www.anthropic.com/claude>",
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/chrischall/splitwise-mcp",
7
7
  "source": "github"
8
8
  },
9
- "version": "2.4.0",
9
+ "version": "2.4.1",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "splitwise-mcp",
14
- "version": "2.4.0",
14
+ "version": "2.4.1",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },
@@ -71,13 +71,13 @@ API key auth — no login flow or token rotation. The key is attached to every r
71
71
  ### User
72
72
  | Tool | Description |
73
73
  |------|-------------|
74
- | `sw_get_current_user` | Get the authenticated user's profile (`id`, `first_name`, `last_name`, `email`) |
74
+ | `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"` |
75
75
 
76
76
  ### Groups
77
77
  | Tool | Description |
78
78
  |------|-------------|
79
- | `sw_list_groups` | List all groups with `id`, `name`, and `members[]` |
80
- | `sw_get_group(id)` | Get a single group's details including members and balances |
79
+ | `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` |
80
+ | `sw_get_group(id, view?)` | Get a single group's details including members and balances |
81
81
  | `sw_create_group(name, group_type?, simplify_by_default?)` | Create a new group (`group_type`: `apartment`, `house`, `trip`, `other`) |
82
82
  | `sw_add_user_to_group(group_id, user_id?)` | Add a user by `user_id` (preferred) or `first_name` + `last_name` + `email` |
83
83
  | `sw_remove_user_from_group(group_id, user_id)` | Remove a user from a group |
@@ -85,13 +85,13 @@ API key auth — no login flow or token rotation. The key is attached to every r
85
85
  ### Friends
86
86
  | Tool | Description |
87
87
  |------|-------------|
88
- | `sw_list_friends` | List all friends with `id`, `first_name`, `last_name`, `email` |
88
+ | `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"` |
89
89
 
90
90
  ### Expenses
91
91
  | Tool | Description |
92
92
  |------|-------------|
93
- | `sw_list_expenses(group_id?, friend_id?, dated_after?, dated_before?, limit?, offset?)` | List or search expenses |
94
- | `sw_get_expense(id)` | Get full details of a single expense |
93
+ | `sw_list_expenses(group_id?, friend_id?, dated_after?, dated_before?, limit?, offset?, view?)` | List or search expenses |
94
+ | `sw_get_expense(id, view?)` | Get full details of a single expense |
95
95
  | `sw_create_expense(group_id, description, cost, split_equally? \| users?)` | Create an expense — equal split or custom per-person split |
96
96
  | `sw_update_expense(expense_id, ...)` | Edit an existing expense (custom split requires full `users` array) |
97
97
  | `sw_delete_expense(id)` | Soft-delete an expense |
@@ -105,10 +105,81 @@ API key auth — no login flow or token rotation. The key is attached to every r
105
105
  ### Utilities
106
106
  | Tool | Description |
107
107
  |------|-------------|
108
- | `sw_get_notifications` | Recent activity feed for the current user |
108
+ | `sw_get_notifications(view?)` | Recent activity feed for the current user |
109
109
  | `sw_get_categories` | Hierarchical list of expense categories (use `id` as `category_id`) |
110
110
  | `sw_get_currencies` | List of supported currency codes |
111
111
 
112
+ ## Response shape (`view`)
113
+
114
+ Nine read tools take `view: "compact" | "full"`, and **`compact` is the
115
+ default** — you get the slim rung without asking. Two of them are not in the
116
+ table above: `sw_get_user(id, view?)` and `sw_get_comments(expense_id, view?)`.
117
+
118
+ This is not a nicety. A live `sw_list_groups` on a 51-group account came back
119
+ as **192,123 characters and was REFUSED by the host before the model saw a byte
120
+ of it** — the tool was not expensive, it was unusable. 60% of that response was
121
+ image URLs: `avatar` + `tall_avatar` + `cover_photo` (51.7 KB) and a `picture`
122
+ object per member across 51 groups (37.7 KB). Stripping media alone takes it to
123
+ 51.4 KB (−73%); the field projections below take it to 29.3 KB.
124
+
125
+ **Compact means two different things here, depending on the tool.**
126
+
127
+ **A hand-written field projection** — `sw_list_groups`, `sw_get_group`,
128
+ `sw_list_friends`, `sw_get_current_user`, `sw_get_user`, `sw_list_expenses`,
129
+ `sw_get_expense`:
130
+
131
+ - **A person becomes `{id, name, email, registration_status, balance}`, and
132
+ `name` is `first_name` + `last_name` JOINED.** This is the one that will trip
133
+ you: reach for `last_name` on the default rung and it is not there. `balance`
134
+ survives because it is the whole reason to look a person up, and
135
+ `registration_status` because it is how you know an invite was never
136
+ accepted.
137
+ - **A group keeps** `{id, name, group_type, updated_at, members[],
138
+ simplified_debts, invite_link}`. The whiteboard fields and the
139
+ `simplify_by_default` / `custom_avatar` / `group_reminders` settings go —
140
+ nothing here reads them. `original_debts` goes because `simplified_debts`
141
+ answers "who owes whom", and the two differ only when simplification is on;
142
+ `full` has both.
143
+ - **An expense keeps the share breakdown**, as `{id, name, paid_share,
144
+ owed_share, net_balance}` per person rather than Splitwise's nested `user`
145
+ object, plus `repayments`, `comments_count` and `category` as a name. Two
146
+ details matter: `deleted_at` is kept **only when set**, because a deleted
147
+ expense still comes back from the list endpoint and a caller who cannot see
148
+ it will count it; and the receipt becomes `has_receipt: true` — the bytes
149
+ come from `sw_get_receipt`. The eleven-field repeat/reminder/transaction
150
+ block goes (`repeats`, `next_repeat`, `transaction_status`, …) — it was
151
+ `false` / `null` / `"offline"` on every expense in a live account.
152
+
153
+ **Media stripping, with no field projection claimed** — `sw_get_notifications`
154
+ and `sw_get_comments`. Compact drops the avatar URLs and touches nothing else.
155
+ Do not expect a named field set from these two; expect the same records minus
156
+ the pictures.
157
+
158
+ `view: "full"` returns Splitwise's records untouched, everywhere. There is **no
159
+ `raw` rung**: `full` already IS the upstream payload, so a third value could
160
+ only alias it.
161
+
162
+ **A projection that trips returns the rows WHOLE**, and for the entire array
163
+ rather than per record — one odd record projected to nothing among fifty good
164
+ ones is a hole in the middle of an answer, and indistinguishable from an
165
+ expense with no content. So a fat response is a possible outcome; a quietly
166
+ gappy one is not.
167
+
168
+ The other eighteen tools take no `view`, each for its own reason:
169
+
170
+ - **`sw_get_receipt`** is the one tool the media rung is documented never to
171
+ touch: its PRODUCT is the image. Stripping there would not shrink the answer,
172
+ it would delete it.
173
+ - **`sw_get_categories` and `sw_get_currencies`** are static reference lists —
174
+ already narrow, no media, and every field on them is the answer.
175
+ - **`sw_healthcheck`** answers reachability and auth.
176
+ - **The fourteen writes** (`sw_create_expense`, `sw_update_expense`,
177
+ `sw_delete_expense`, `sw_undelete_expense`, `sw_create_group`,
178
+ `sw_delete_group`, `sw_undelete_group`, `sw_add_user_to_group`,
179
+ `sw_remove_user_from_group`, `sw_create_friend`, `sw_delete_friend`,
180
+ `sw_create_comment`, `sw_delete_comment`, `sw_update_user`) return receipts —
181
+ an id, a status — with nothing to strip and everything to keep.
182
+
112
183
  ## Workflows
113
184
 
114
185
  **Add an expense to a group:**