splitwise-mcp 2.0.1 → 2.0.2

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": "1.3.0"
10
+ "version": "2.0.2"
11
11
  },
12
12
  "plugins": [
13
13
  {
@@ -15,14 +15,19 @@
15
15
  "displayName": "Splitwise",
16
16
  "source": "./",
17
17
  "description": "MCP server for Splitwise — manage expenses, groups, and friends via natural language",
18
- "version": "1.3.0",
18
+ "version": "2.0.2",
19
19
  "author": {
20
20
  "name": "Chris Hall"
21
21
  },
22
22
  "homepage": "https://github.com/chrischall/splitwise-mcp",
23
23
  "repository": "https://github.com/chrischall/splitwise-mcp",
24
24
  "license": "MIT",
25
- "keywords": ["splitwise", "expenses", "mcp", "finance"],
25
+ "keywords": [
26
+ "splitwise",
27
+ "expenses",
28
+ "mcp",
29
+ "finance"
30
+ ],
26
31
  "category": "finance"
27
32
  }
28
33
  ]
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "splitwise-mcp",
3
3
  "displayName": "Splitwise",
4
- "version": "1.3.0",
4
+ "version": "2.0.2",
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",
@@ -10,7 +10,12 @@
10
10
  "homepage": "https://github.com/chrischall/splitwise-mcp",
11
11
  "repository": "https://github.com/chrischall/splitwise-mcp",
12
12
  "license": "MIT",
13
- "keywords": ["splitwise", "expenses", "mcp", "finance"],
13
+ "keywords": [
14
+ "splitwise",
15
+ "expenses",
16
+ "mcp",
17
+ "finance"
18
+ ],
14
19
  "skills": "./SKILL.md",
15
20
  "mcp": "./.mcp.json"
16
21
  }
package/README.md ADDED
@@ -0,0 +1,174 @@
1
+ # Splitwise MCP
2
+
3
+ A [Model Context Protocol](https://modelcontextprotocol.io) server that connects Claude to [Splitwise](https://www.splitwise.com), giving you natural-language access to your expenses, groups, friends, and balances.
4
+
5
+ > [!WARNING]
6
+ > **AI-developed project.** This codebase was entirely built and is actively maintained by [Claude Code](https://www.anthropic.com/claude). No human has audited the implementation. Review all code and tool permissions before use.
7
+
8
+ ## What you can do
9
+
10
+ Ask Claude things like:
11
+
12
+ - *"What do I owe?"*
13
+ - *"Add a $50 dinner expense to the vacation group"*
14
+ - *"Split this hotel bill 60/40 with Sarah"*
15
+ - *"Who's in the trip group?"*
16
+ - *"Add Meredith to the household group"*
17
+ - *"Show me recent expenses"*
18
+ - *"Delete that duplicate expense"*
19
+
20
+ ## Requirements
21
+
22
+ - [Claude Desktop](https://claude.ai/download) or [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
23
+ - [Node.js](https://nodejs.org) 20.6 or later
24
+ - A [Splitwise](https://www.splitwise.com) account and API key
25
+
26
+ ## Installation
27
+
28
+ ### Option A -- npx (recommended)
29
+
30
+ ```bash
31
+ npx -y splitwise-mcp
32
+ ```
33
+
34
+ Add to your Claude config (`.mcp.json` or Claude Desktop config):
35
+
36
+ ```json
37
+ {
38
+ "mcpServers": {
39
+ "splitwise": {
40
+ "command": "npx",
41
+ "args": ["-y", "splitwise-mcp"],
42
+ "env": {
43
+ "SPLITWISE_API_KEY": "your-api-key-here"
44
+ }
45
+ }
46
+ }
47
+ }
48
+ ```
49
+
50
+ ### Option B -- from source
51
+
52
+ ```bash
53
+ git clone https://github.com/chrischall/splitwise-mcp.git
54
+ cd splitwise-mcp
55
+ npm install
56
+ npm run build
57
+ ```
58
+
59
+ Add to Claude Desktop config:
60
+
61
+ - **Mac:** `~/Library/Application Support/Claude/claude_desktop_config.json`
62
+ - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
63
+
64
+ ```json
65
+ {
66
+ "mcpServers": {
67
+ "splitwise": {
68
+ "command": "node",
69
+ "args": ["/absolute/path/to/splitwise-mcp/dist/index.js"],
70
+ "env": {
71
+ "SPLITWISE_API_KEY": "your-api-key-here"
72
+ }
73
+ }
74
+ }
75
+ }
76
+ ```
77
+
78
+ ### Getting your API key
79
+
80
+ 1. Go to [secure.splitwise.com/apps/register](https://secure.splitwise.com/apps/register)
81
+ 2. Register an app (name and description can be anything)
82
+ 3. Copy the **API key** from the app detail page
83
+
84
+ ## Credentials
85
+
86
+ | Env var | Required | Notes |
87
+ |---------|----------|-------|
88
+ | `SPLITWISE_API_KEY` | Yes | API key from [splitwise.com/apps/register](https://secure.splitwise.com/apps/register) |
89
+
90
+ ## Available tools
91
+
92
+ 20 tools across 5 domains. All tools are prefixed `sw_`.
93
+
94
+ ### User
95
+
96
+ | Tool | What it does |
97
+ |------|-------------|
98
+ | `sw_get_current_user` | Get the authenticated user's profile |
99
+ | `sw_get_user` | Get another user's profile by ID |
100
+
101
+ ### Groups
102
+
103
+ | Tool | What it does |
104
+ |------|-------------|
105
+ | `sw_list_groups` | List all groups with members |
106
+ | `sw_get_group` | Group details including members and balances |
107
+ | `sw_create_group` | Create a new group |
108
+ | `sw_delete_group` | Soft-delete a group |
109
+ | `sw_undelete_group` | Restore a deleted group |
110
+ | `sw_add_user_to_group` | Add a user to a group |
111
+ | `sw_remove_user_from_group` | Remove a user from a group |
112
+
113
+ ### Friends
114
+
115
+ | Tool | What it does |
116
+ |------|-------------|
117
+ | `sw_list_friends` | List all friends |
118
+ | `sw_create_friend` | Add a friend by email |
119
+ | `sw_delete_friend` | Remove a friendship |
120
+
121
+ ### Expenses
122
+
123
+ | Tool | What it does |
124
+ |------|-------------|
125
+ | `sw_list_expenses` | List or search expenses with filters |
126
+ | `sw_get_expense` | Full details of a single expense |
127
+ | `sw_create_expense` | Create an expense (equal or custom split) |
128
+ | `sw_update_expense` | Edit an existing expense |
129
+ | `sw_delete_expense` | Soft-delete an expense |
130
+ | `sw_undelete_expense` | Restore a deleted expense |
131
+ | `sw_get_comments` | Get comments on an expense |
132
+ | `sw_create_comment` | Add a comment to an expense |
133
+ | `sw_delete_comment` | Delete a comment |
134
+
135
+ ### Utilities
136
+
137
+ | Tool | What it does |
138
+ |------|-------------|
139
+ | `sw_get_notifications` | Recent activity feed |
140
+ | `sw_get_categories` | Expense category list |
141
+ | `sw_get_currencies` | Supported currency codes |
142
+
143
+ ## Troubleshooting
144
+
145
+ **"SPLITWISE_API_KEY is required"** -- set the environment variable in your MCP config or a `.env` file.
146
+
147
+ **429 rate limit** -- Splitwise has undocumented rate limits. Wait a moment and retry.
148
+
149
+ **Tools not appearing in Claude** -- go to **Claude Desktop > Settings > Developer** to see connected servers. Make sure you fully quit and relaunched after editing the config.
150
+
151
+ ## Development
152
+
153
+ ```bash
154
+ npm test # run the test suite (vitest)
155
+ npm run build # compile TypeScript -> dist/
156
+ ```
157
+
158
+ ### Project structure
159
+
160
+ ```
161
+ src/
162
+ client.ts Splitwise API client (auth, request handling)
163
+ index.ts MCP server entry point
164
+ tools/
165
+ user.ts sw_get_current_user, sw_get_user
166
+ groups.ts group CRUD and membership
167
+ friends.ts friend list and management
168
+ expenses.ts expense CRUD, comments
169
+ utilities.ts notifications, categories, currencies
170
+ ```
171
+
172
+ ## License
173
+
174
+ MIT
package/dist/bundle.js CHANGED
@@ -30119,14 +30119,23 @@ import { fileURLToPath } from "url";
30119
30119
  try {
30120
30120
  const { config: config2 } = await import("dotenv");
30121
30121
  const __dirname = dirname(fileURLToPath(import.meta.url));
30122
- config2({ path: join(__dirname, "..", ".env"), override: false });
30122
+ config2({ path: join(__dirname, "..", ".env"), override: false, quiet: true });
30123
30123
  } catch {
30124
30124
  }
30125
+ function readVar(key) {
30126
+ const raw = process.env[key];
30127
+ if (typeof raw !== "string") return void 0;
30128
+ const trimmed = raw.trim();
30129
+ if (trimmed.length === 0) return void 0;
30130
+ if (trimmed === "undefined" || trimmed === "null") return void 0;
30131
+ if (/^\$\{[^}]*\}$/.test(trimmed)) return void 0;
30132
+ return trimmed;
30133
+ }
30125
30134
  var BASE_URL = "https://secure.splitwise.com/api/v3.0";
30126
30135
  var SplitwiseClient = class {
30127
30136
  apiKey;
30128
30137
  constructor() {
30129
- const key = process.env.SPLITWISE_API_KEY;
30138
+ const key = readVar("SPLITWISE_API_KEY");
30130
30139
  if (!key) throw new Error("SPLITWISE_API_KEY environment variable is required");
30131
30140
  this.apiKey = key;
30132
30141
  }
package/dist/client.js CHANGED
@@ -4,16 +4,34 @@ import { fileURLToPath } from 'url';
4
4
  try {
5
5
  const { config } = await import('dotenv');
6
6
  const __dirname = dirname(fileURLToPath(import.meta.url));
7
- config({ path: join(__dirname, '..', '.env'), override: false });
7
+ config({ path: join(__dirname, '..', '.env'), override: false, quiet: true });
8
8
  }
9
9
  catch {
10
10
  // not available — rely on process.env (mcpb sets credentials via mcp_config.env)
11
11
  }
12
+ /**
13
+ * Read an env var, trim whitespace, and treat as unset if blank or if the value
14
+ * looks like an unsubstituted shell placeholder (e.g. `${FOO}`) — defends
15
+ * against MCP hosts that pass .mcp.json env blocks through unexpanded.
16
+ */
17
+ function readVar(key) {
18
+ const raw = process.env[key];
19
+ if (typeof raw !== 'string')
20
+ return undefined;
21
+ const trimmed = raw.trim();
22
+ if (trimmed.length === 0)
23
+ return undefined;
24
+ if (trimmed === 'undefined' || trimmed === 'null')
25
+ return undefined;
26
+ if (/^\$\{[^}]*\}$/.test(trimmed))
27
+ return undefined;
28
+ return trimmed;
29
+ }
12
30
  const BASE_URL = 'https://secure.splitwise.com/api/v3.0';
13
31
  export class SplitwiseClient {
14
32
  apiKey;
15
33
  constructor() {
16
- const key = process.env.SPLITWISE_API_KEY;
34
+ const key = readVar('SPLITWISE_API_KEY');
17
35
  if (!key)
18
36
  throw new Error('SPLITWISE_API_KEY environment variable is required');
19
37
  this.apiKey = key;
package/package.json CHANGED
@@ -1,12 +1,28 @@
1
1
  {
2
2
  "name": "splitwise-mcp",
3
- "version": "2.0.1",
4
- "description": "Splitwise MCP server for Claude — developed and maintained by AI (Claude Sonnet 4.6)",
5
- "author": "Claude Sonnet 4.6 (AI) <https://www.anthropic.com/claude>",
3
+ "version": "2.0.2",
4
+ "mcpName": "io.github.chrischall/splitwise-mcp",
5
+ "description": "Splitwise MCP server for Claude — developed and maintained by AI (Claude Code)",
6
+ "author": "Claude Code (AI) <https://www.anthropic.com/claude>",
6
7
  "repository": {
7
8
  "type": "git",
8
9
  "url": "git+https://github.com/chrischall/splitwise-mcp.git"
9
10
  },
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "mcp",
14
+ "model-context-protocol",
15
+ "claude",
16
+ "ai",
17
+ "splitwise",
18
+ "expenses",
19
+ "expense-tracking",
20
+ "groups",
21
+ "friends",
22
+ "split-bills",
23
+ "finance",
24
+ "shared-expenses"
25
+ ],
10
26
  "type": "module",
11
27
  "bin": {
12
28
  "splitwise-mcp": "dist/index.js"
@@ -15,7 +31,8 @@
15
31
  "dist",
16
32
  ".claude-plugin",
17
33
  "SKILL.md",
18
- ".mcp.json"
34
+ ".mcp.json",
35
+ "server.json"
19
36
  ],
20
37
  "scripts": {
21
38
  "build": "tsc && npm run bundle",
package/server.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
+ "name": "io.github.chrischall/splitwise-mcp",
4
+ "description": "Splitwise expense and group management for Claude — shared expenses, settle up, friends",
5
+ "repository": {
6
+ "url": "https://github.com/chrischall/splitwise-mcp",
7
+ "source": "github"
8
+ },
9
+ "version": "2.0.2",
10
+ "packages": [
11
+ {
12
+ "registryType": "npm",
13
+ "identifier": "splitwise-mcp",
14
+ "version": "2.0.2",
15
+ "transport": {
16
+ "type": "stdio"
17
+ },
18
+ "environmentVariables": [
19
+ {
20
+ "name": "SPLITWISE_API_KEY",
21
+ "description": "Your Splitwise API key (splitwise.com/apps/api)",
22
+ "isRequired": true,
23
+ "format": "string",
24
+ "isSecret": true
25
+ }
26
+ ]
27
+ }
28
+ ]
29
+ }