splitwise-mcp 3.2.3 → 3.3.0
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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +3 -2
- package/dist/bundle.js +32 -4
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/server.json +2 -2
- package/skills/splitwise-mcp/SKILL.md +1 -1
|
@@ -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": "3.
|
|
10
|
+
"version": "3.3.0"
|
|
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": "3.
|
|
18
|
+
"version": "3.3.0",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Hall"
|
|
21
21
|
},
|
package/README.md
CHANGED
|
@@ -117,11 +117,12 @@ Add to Claude Desktop config:
|
|
|
117
117
|
|
|
118
118
|
## Confirmations
|
|
119
119
|
|
|
120
|
-
Every Splitwise write (creating, editing or deleting expenses, groups, friends, comments, or your profile) notifies other people, so it asks you to confirm first. A client that can show a confirmation prompt (Claude Code) shows one. On a client that cannot (claude.ai, Claude Desktop), the first call changes nothing and returns a preview of exactly what will be sent plus a `confirmToken`; only a repeat call with that token goes through, and the token is refused if anything in the request changed in between.
|
|
120
|
+
Every Splitwise write (creating, editing or deleting expenses, groups, friends, comments, or your profile) notifies other people, so it asks you to confirm first. A client that can show a confirmation prompt (Claude Code) shows one (unless `MCP_CONFIRM_ELICITATION=off`). On a client that cannot (claude.ai, Claude Desktop), the first call changes nothing and returns a preview of exactly what will be sent plus a `confirmToken`; only a repeat call with that token goes through, and the token is refused if anything in the request changed in between.
|
|
121
121
|
|
|
122
122
|
| variable | default | |
|
|
123
123
|
|---|---|---|
|
|
124
|
-
| `MCP_CONFIRM_MODE` | `ask-user` | What a write does on a client that cannot show a confirmation prompt (claude.ai, Claude Desktop). `ask-user`: two steps — the first call does nothing and returns a preview plus a token, and the model must get your approval in chat before calling again with it. `auto`: the same two steps, but the model may use the token after reviewing the preview itself. `refuse`: writes are refused on such clients. A client that can show prompts (Claude Code) always gets the real prompt
|
|
124
|
+
| `MCP_CONFIRM_MODE` | `ask-user` | What a write does on a client that cannot show a confirmation prompt (claude.ai, Claude Desktop). `ask-user`: two steps — the first call does nothing and returns a preview plus a token, and the model must get your approval in chat before calling again with it. `auto`: the same two steps, but the model may use the token after reviewing the preview itself. `refuse`: writes are refused on such clients. A client that can show prompts (Claude Code) always gets the real prompt, unless `MCP_CONFIRM_ELICITATION=off`. An unrecognised value is treated as `refuse`. |
|
|
125
|
+
| `MCP_CONFIRM_ELICITATION` | `on` | `off` never shows a confirmation prompt, so every client gets the `MCP_CONFIRM_MODE` behaviour. Set it for a client that says it can show prompts but never does (the write hangs — opencode 2.0.x). Any other value is treated as `on`, with a warning on stderr. |
|
|
125
126
|
| `MCP_CONFIRM_TTL_SECONDS` | `600` | How long a token stays valid. |
|
|
126
127
|
| `MCP_CONFIRM_SECRET` | random per process | Signing key; set it only if tokens must survive a server restart. |
|
|
127
128
|
|
package/dist/bundle.js
CHANGED
|
@@ -97980,6 +97980,7 @@ function escapeKey(key) {
|
|
|
97980
97980
|
var DEFAULT_REQUEST_KEY = "confirmation";
|
|
97981
97981
|
var DEFAULT_CONFIRMATION_LABEL = "Confirm this action should proceed.";
|
|
97982
97982
|
var UNSUPPORTED_NOTE = "Nothing was done because this client cannot show a confirmation prompt (it declares no MCP elicitation capability), and this action is never taken without one";
|
|
97983
|
+
var DISABLED_NOTE = "Nothing was done because confirmation prompts are turned off for this server, and this action is never taken without one";
|
|
97983
97984
|
var STATE_PREFIX = "mcpu.confirm.v1.";
|
|
97984
97985
|
function bindingKey(binding) {
|
|
97985
97986
|
if (binding.ttlSeconds !== void 0 && !(Number.isFinite(binding.ttlSeconds) && binding.ttlSeconds > 0)) {
|
|
@@ -98052,6 +98053,15 @@ ${JSON.stringify(preview, null, 2)}`,
|
|
|
98052
98053
|
};
|
|
98053
98054
|
const response = inputResponse(ctx.mcpReq.inputResponses, requestKey);
|
|
98054
98055
|
const accepted = acceptedContent(ctx.mcpReq.inputResponses, requestKey, confirmationSchema);
|
|
98056
|
+
if (options.elicitation === false) {
|
|
98057
|
+
return textResult({
|
|
98058
|
+
confirmed: false,
|
|
98059
|
+
dispatched: false,
|
|
98060
|
+
action: options.action,
|
|
98061
|
+
reason: "confirmation-unsupported",
|
|
98062
|
+
note: options.unsupportedNote ? `${DISABLED_NOTE}. ${options.unsupportedNote}` : `${DISABLED_NOTE}.`
|
|
98063
|
+
});
|
|
98064
|
+
}
|
|
98055
98065
|
if (response.kind === "missing") {
|
|
98056
98066
|
if (callerAcceptsFormElicitation(ctx) === false) {
|
|
98057
98067
|
return textResult({
|
|
@@ -98246,7 +98256,7 @@ async function tokenConfirmation(action, fb) {
|
|
|
98246
98256
|
}
|
|
98247
98257
|
async function requireConfirmationWithFallback(ctx, options) {
|
|
98248
98258
|
const { tokenFallback, ...confirmation } = options;
|
|
98249
|
-
if (tokenFallback && callerAcceptsFormElicitation(ctx) === false) {
|
|
98259
|
+
if (tokenFallback && (options.elicitation === false || callerAcceptsFormElicitation(ctx) === false)) {
|
|
98250
98260
|
return tokenConfirmation(options.action, tokenFallback);
|
|
98251
98261
|
}
|
|
98252
98262
|
return requireConfirmation(ctx, confirmation);
|
|
@@ -98394,6 +98404,20 @@ function readConfirmMode(env = process.env) {
|
|
|
98394
98404
|
}
|
|
98395
98405
|
return "refuse";
|
|
98396
98406
|
}
|
|
98407
|
+
function readConfirmElicitation(env = process.env) {
|
|
98408
|
+
const raw = readEnvVar("MCP_CONFIRM_ELICITATION", { env })?.trim().toLowerCase();
|
|
98409
|
+
if (!raw || raw === "on")
|
|
98410
|
+
return "on";
|
|
98411
|
+
if (raw === "off")
|
|
98412
|
+
return "off";
|
|
98413
|
+
const key = `elicitation:${raw}`;
|
|
98414
|
+
if (!warned.has(key)) {
|
|
98415
|
+
warned.add(key);
|
|
98416
|
+
process.stderr.write(`MCP_CONFIRM_ELICITATION="${raw}" is not one of on, off; treating it as on.
|
|
98417
|
+
`);
|
|
98418
|
+
}
|
|
98419
|
+
return "on";
|
|
98420
|
+
}
|
|
98397
98421
|
function readConfirmTtl(env) {
|
|
98398
98422
|
const raw = readEnvVar("MCP_CONFIRM_TTL_SECONDS", { env })?.trim();
|
|
98399
98423
|
if (!raw)
|
|
@@ -98438,6 +98462,7 @@ function spentTokenStoreFromEnv(env = process.env) {
|
|
|
98438
98462
|
}
|
|
98439
98463
|
var CONFIRM_TOKEN_AUTO_INSTRUCTION = "Nothing has been done yet. Review this preview; if it is what was intended, call again with the same arguments plus confirmToken. (This server runs with MCP_CONFIRM_MODE=auto, so the user's approval in chat is not required.)";
|
|
98440
98464
|
var REFUSE_HINT = "Set MCP_CONFIRM_MODE=ask-user on the server to allow two-step confirmation instead.";
|
|
98465
|
+
var ELICITATION_OFF_HINT = "MCP_CONFIRM_ELICITATION=off on the server turns confirmation prompts off.";
|
|
98441
98466
|
var BAD_TTL_HINT = "MCP_CONFIRM_TTL_SECONDS on the server is not a positive whole number of seconds; fix it to allow two-step confirmation.";
|
|
98442
98467
|
function boundArgs(args) {
|
|
98443
98468
|
if (args === null || typeof args !== "object" || Array.isArray(args) || !("confirmToken" in args))
|
|
@@ -98451,10 +98476,13 @@ function confirmationFromEnv(options) {
|
|
|
98451
98476
|
const spent = callerSpent ?? spentTokenStoreFromEnv(env);
|
|
98452
98477
|
const mode = readConfirmMode(env);
|
|
98453
98478
|
const ttlSeconds = readConfirmTtl(env);
|
|
98479
|
+
const elicitationOff = readConfirmElicitation(env) === "off";
|
|
98454
98480
|
const bound = args === void 0 ? void 0 : boundArgs(args);
|
|
98455
|
-
const
|
|
98481
|
+
const bindingAdded = bound === void 0 || rest.binding ? rest : { ...rest, binding: { key: confirmKeyFromEnv(env), args: bound, ttlSeconds: ttlSeconds ?? DEFAULT_TTL_SECONDS2 } };
|
|
98482
|
+
const confirmation = elicitationOff ? { ...bindingAdded, elicitation: false } : bindingAdded;
|
|
98456
98483
|
if (mode === "refuse" || ttlSeconds === void 0) {
|
|
98457
|
-
const
|
|
98484
|
+
const reason = mode === "refuse" ? REFUSE_HINT : BAD_TTL_HINT;
|
|
98485
|
+
const hint = elicitationOff ? `${ELICITATION_OFF_HINT} ${reason}` : reason;
|
|
98458
98486
|
return {
|
|
98459
98487
|
...confirmation,
|
|
98460
98488
|
unsupportedNote: confirmation.unsupportedNote ? `${confirmation.unsupportedNote} ${hint}` : hint
|
|
@@ -100586,7 +100614,7 @@ function registerUtilityTools(server, client2) {
|
|
|
100586
100614
|
// src/index.ts
|
|
100587
100615
|
await runMcp({
|
|
100588
100616
|
name: "splitwise-mcp",
|
|
100589
|
-
version: "3.
|
|
100617
|
+
version: "3.3.0",
|
|
100590
100618
|
// x-release-please-version
|
|
100591
100619
|
deps: client,
|
|
100592
100620
|
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: '3.
|
|
22
|
+
version: '3.3.0', // 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": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
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>",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@chrischall/mcp-utils": "^2.
|
|
48
|
+
"@chrischall/mcp-utils": "^2.15.0",
|
|
49
49
|
"@modelcontextprotocol/server": "^2.3.0",
|
|
50
50
|
"dotenv": "^18.0.2",
|
|
51
51
|
"unpdf": "^1.8.1",
|
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": "3.
|
|
9
|
+
"version": "3.3.0",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "splitwise-mcp",
|
|
14
|
-
"version": "3.
|
|
14
|
+
"version": "3.3.0",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|
|
@@ -221,7 +221,7 @@ sw_update_expense(expense_id, description: "Corrected description", cost: "95.00
|
|
|
221
221
|
|
|
222
222
|
## Notes
|
|
223
223
|
|
|
224
|
-
- 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
|
|
224
|
+
- 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
|
|
225
225
|
- `cost` is always a decimal string (e.g. `"25.00"`)
|
|
226
226
|
- `split_equally: true` and `users` array are mutually exclusive
|
|
227
227
|
- For custom split updates, the **full `users` array is required** — the API replaces the entire split
|