splitwise-mcp 2.2.1 → 2.2.3

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.2.1"
10
+ "version": "2.2.3"
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.2.1",
18
+ "version": "2.2.3",
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.2.1",
4
+ "version": "2.2.3",
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/README.md CHANGED
@@ -190,7 +190,7 @@ Add to Claude Desktop config:
190
190
  ## Development
191
191
 
192
192
  ```bash
193
- npm test # run the test suite (vitest)
193
+ npm test # tsc typecheck + run the test suite (vitest)
194
194
  npm run build # compile TypeScript -> dist/
195
195
  ```
196
196
 
package/dist/bundle.js CHANGED
@@ -70897,55 +70897,19 @@ var StdioServerTransport = class {
70897
70897
  }
70898
70898
  };
70899
70899
 
70900
- // node_modules/@chrischall/mcp-utils/dist/server/index.js
70901
- async function createMcpServer(opts) {
70902
- const server = new McpServer({ name: opts.name, version: opts.version });
70903
- if (opts.banner !== void 0) {
70904
- console.error(opts.banner);
70905
- }
70906
- const deps = opts.deps;
70907
- for (const register of opts.tools) {
70908
- await register(server, deps);
70909
- }
70910
- return server;
70911
- }
70912
- function withGracefulShutdown(server, opts = {}) {
70913
- const shouldExit = opts.exit ?? true;
70914
- let shuttingDown = false;
70915
- const handler = (signal) => {
70916
- if (shuttingDown)
70917
- return;
70918
- shuttingDown = true;
70919
- void (async () => {
70920
- try {
70921
- if (opts.onSignal)
70922
- await opts.onSignal(signal);
70923
- await server.close();
70924
- } catch (err) {
70925
- console.error(`[mcp-utils] error during graceful shutdown on ${signal}: ${err instanceof Error ? err.message : String(err)}`);
70926
- } finally {
70927
- if (shouldExit)
70928
- process.exit(0);
70929
- }
70930
- })();
70931
- };
70932
- process.on("SIGINT", () => handler("SIGINT"));
70933
- process.on("SIGTERM", () => handler("SIGTERM"));
70934
- }
70935
- async function runMcp(opts) {
70936
- const server = await createMcpServer(opts);
70937
- const shutdown = opts.shutdown ?? true;
70938
- if (shutdown !== false) {
70939
- withGracefulShutdown(server, shutdown === true ? {} : shutdown);
70940
- }
70941
- const spec = opts.transport ?? "stdio";
70942
- const transport = spec === "stdio" ? new StdioServerTransport() : spec;
70943
- await server.connect(transport);
70944
- return server;
70945
- }
70946
-
70947
70900
  // node_modules/@chrischall/mcp-utils/dist/errors/index.js
70948
70901
  var DEFAULT_ERROR_MESSAGE_MAX = 500;
70902
+ var McpToolError = class extends Error {
70903
+ /** Actionable remediation text, when one applies. */
70904
+ hint;
70905
+ constructor(message, opts) {
70906
+ super(message, opts?.cause !== void 0 ? { cause: opts.cause } : void 0);
70907
+ this.name = "McpToolError";
70908
+ if (opts?.hint !== void 0)
70909
+ this.hint = opts.hint;
70910
+ Object.setPrototypeOf(this, new.target.prototype);
70911
+ }
70912
+ };
70949
70913
  var BEARER_RE = /(bearer\s+)[A-Za-z0-9._~+/=-]{8,}/gi;
70950
70914
  var JWT_RE = /\b[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{8,}\b/g;
70951
70915
  var BASIC_AUTH_RE = /(authorization\s*:\s*basic\s+)[A-Za-z0-9+/=_-]{6,}/gi;
@@ -70992,6 +70956,12 @@ function imageResult(base643, mimeType) {
70992
70956
  content: [{ type: "image", data: base643, mimeType }]
70993
70957
  };
70994
70958
  }
70959
+ function errorResult(message) {
70960
+ return {
70961
+ content: [{ type: "text", text: redactSecrets(message) }],
70962
+ isError: true
70963
+ };
70964
+ }
70995
70965
  function pruneUndefined(obj) {
70996
70966
  const out = {};
70997
70967
  for (const key of Object.keys(obj)) {
@@ -71001,6 +70971,75 @@ function pruneUndefined(obj) {
71001
70971
  return out;
71002
70972
  }
71003
70973
 
70974
+ // node_modules/@chrischall/mcp-utils/dist/server/index.js
70975
+ function hintResultOrRethrow(err) {
70976
+ if (err instanceof McpToolError && err.hint) {
70977
+ return errorResult(`${err.message}
70978
+
70979
+ Hint: ${err.hint}`);
70980
+ }
70981
+ throw err;
70982
+ }
70983
+ function surfaceToolHints(server) {
70984
+ const register = server.registerTool.bind(server);
70985
+ server.registerTool = (name, config2, cb) => register(name, config2, (...args) => {
70986
+ let result;
70987
+ try {
70988
+ result = cb(...args);
70989
+ } catch (err) {
70990
+ return hintResultOrRethrow(err);
70991
+ }
70992
+ return result instanceof Promise ? result.catch(hintResultOrRethrow) : result;
70993
+ });
70994
+ }
70995
+ async function createMcpServer(opts) {
70996
+ const server = new McpServer({ name: opts.name, version: opts.version });
70997
+ if (opts.surfaceHints !== false)
70998
+ surfaceToolHints(server);
70999
+ if (opts.banner !== void 0) {
71000
+ console.error(opts.banner);
71001
+ }
71002
+ const deps = opts.deps;
71003
+ for (const register of opts.tools) {
71004
+ await register(server, deps);
71005
+ }
71006
+ return server;
71007
+ }
71008
+ function withGracefulShutdown(server, opts = {}) {
71009
+ const shouldExit = opts.exit ?? true;
71010
+ let shuttingDown = false;
71011
+ const handler = (signal) => {
71012
+ if (shuttingDown)
71013
+ return;
71014
+ shuttingDown = true;
71015
+ void (async () => {
71016
+ try {
71017
+ if (opts.onSignal)
71018
+ await opts.onSignal(signal);
71019
+ await server.close();
71020
+ } catch (err) {
71021
+ console.error(`[mcp-utils] error during graceful shutdown on ${signal}: ${err instanceof Error ? err.message : String(err)}`);
71022
+ } finally {
71023
+ if (shouldExit)
71024
+ process.exit(0);
71025
+ }
71026
+ })();
71027
+ };
71028
+ process.on("SIGINT", () => handler("SIGINT"));
71029
+ process.on("SIGTERM", () => handler("SIGTERM"));
71030
+ }
71031
+ async function runMcp(opts) {
71032
+ const server = await createMcpServer(opts);
71033
+ const shutdown = opts.shutdown ?? true;
71034
+ if (shutdown !== false) {
71035
+ withGracefulShutdown(server, shutdown === true ? {} : shutdown);
71036
+ }
71037
+ const spec = opts.transport ?? "stdio";
71038
+ const transport = spec === "stdio" ? new StdioServerTransport() : spec;
71039
+ await server.connect(transport);
71040
+ return server;
71041
+ }
71042
+
71004
71043
  // node_modules/@chrischall/mcp-utils/dist/config/index.js
71005
71044
  import { homedir } from "node:os";
71006
71045
  import { isAbsolute, join, resolve } from "node:path";
@@ -71971,7 +72010,7 @@ function registerUtilityTools(server, client2) {
71971
72010
  // src/index.ts
71972
72011
  await runMcp({
71973
72012
  name: "splitwise-mcp",
71974
- version: "2.2.1",
72013
+ version: "2.2.3",
71975
72014
  // x-release-please-version
71976
72015
  deps: client,
71977
72016
  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
@@ -18,7 +18,7 @@ import { registerUtilityTools } from './tools/utilities.js';
18
18
  // client into the same registrars instead of this singleton.
19
19
  await runMcp({
20
20
  name: 'splitwise-mcp',
21
- version: '2.2.1', // x-release-please-version
21
+ version: '2.2.3', // x-release-please-version
22
22
  deps: client,
23
23
  banner: '[splitwise-mcp] This project was developed and is maintained by AI (Claude Sonnet 4.6). Use at your own discretion.',
24
24
  tools: [
package/mint.yaml ADDED
@@ -0,0 +1,27 @@
1
+ version: 1
2
+ name: Splitwise
3
+ slug: splitwise
4
+ summary: >-
5
+ Splitwise expenses, groups and friends. Bearer/API-key auth against the
6
+ documented REST API — no browser bridge, so it hosts on any tier.
7
+ env:
8
+ - name: SPLITWISE_API_KEY
9
+ secret: true
10
+ required: true
11
+ help: >-
12
+ Your Splitwise API key. Register an app at
13
+ https://secure.splitwise.com/apps/register and copy its API key.
14
+ egress:
15
+ allow:
16
+ # Only hosts the SERVER process actually fetches. Hosts that appear
17
+ # solely in a URL this server BUILDS and returns are excluded.
18
+ #
19
+ # The Splitwise REST API (https://secure.splitwise.com/api/v3.0) — every
20
+ # tool but sw_get_receipt talks only to this host.
21
+ - secure.splitwise.com
22
+ # sw_get_receipt fetches the receipt URL the API hands back, which lives at
23
+ # https://www.splitwise.com/api/v4.0/expenses/{id}/receipt (checked live
24
+ # 2026-08-28) and 302s to the presigned S3 object below. The child's fetch
25
+ # follows that redirect, so each hop is its own CONNECT and must be listed.
26
+ - www.splitwise.com
27
+ - splitwise.s3.amazonaws.com
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "splitwise-mcp",
3
- "version": "2.2.1",
3
+ "version": "2.2.3",
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>",
@@ -32,18 +32,20 @@
32
32
  ".claude-plugin",
33
33
  "skills/",
34
34
  ".mcp.json",
35
- "server.json"
35
+ "server.json",
36
+ "mint.yaml"
36
37
  ],
37
38
  "scripts": {
38
39
  "build": "tsc && npm run bundle",
39
40
  "bundle": "esbuild src/index.ts --bundle --platform=node --format=esm --external:dotenv --outfile=dist/bundle.js",
40
41
  "dev": "node dist/index.js",
41
- "test": "vitest run",
42
+ "test": "npm run typecheck && vitest run",
42
43
  "test:watch": "vitest",
43
- "test:coverage": "vitest run --coverage"
44
+ "test:coverage": "npm run typecheck && vitest run --coverage",
45
+ "typecheck": "tsc -p tsconfig.json --noEmit"
44
46
  },
45
47
  "dependencies": {
46
- "@chrischall/mcp-utils": "^0.14.0",
48
+ "@chrischall/mcp-utils": "^0.15.0",
47
49
  "@modelcontextprotocol/sdk": "^1.29.0",
48
50
  "dotenv": "^17.4.0",
49
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": "2.2.1",
9
+ "version": "2.2.3",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "splitwise-mcp",
14
- "version": "2.2.1",
14
+ "version": "2.2.3",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },