monzo-mcp 1.0.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/LICENSE +21 -0
- package/README.md +351 -0
- package/build/client.d.ts +16 -0
- package/build/client.js +84 -0
- package/build/client.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +38 -0
- package/build/index.js.map +1 -0
- package/build/tools/accounts.d.ts +3 -0
- package/build/tools/accounts.js +56 -0
- package/build/tools/accounts.js.map +1 -0
- package/build/tools/attachments.d.ts +3 -0
- package/build/tools/attachments.js +81 -0
- package/build/tools/attachments.js.map +1 -0
- package/build/tools/feed.d.ts +3 -0
- package/build/tools/feed.js +47 -0
- package/build/tools/feed.js.map +1 -0
- package/build/tools/pots.d.ts +3 -0
- package/build/tools/pots.js +89 -0
- package/build/tools/pots.js.map +1 -0
- package/build/tools/receipts.d.ts +3 -0
- package/build/tools/receipts.js +75 -0
- package/build/tools/receipts.js.map +1 -0
- package/build/tools/transactions.d.ts +3 -0
- package/build/tools/transactions.js +91 -0
- package/build/tools/transactions.js.map +1 -0
- package/build/tools/webhooks.d.ts +3 -0
- package/build/tools/webhooks.js +62 -0
- package/build/tools/webhooks.js.map +1 -0
- package/build/utils.d.ts +16 -0
- package/build/utils.js +33 -0
- package/build/utils.js.map +1 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sam
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
# Monzo MCP Server
|
|
2
|
+
|
|
3
|
+
An MCP (Model Context Protocol) server for the [Monzo banking API](https://docs.monzo.com). Check your balance, list transactions, manage pots, and more — all through natural language.
|
|
4
|
+
|
|
5
|
+
Works with any MCP-compatible client, including Claude Desktop, Claude Code, Cursor, Windsurf, Cline, and others.
|
|
6
|
+
|
|
7
|
+
> **Note:** The Monzo Developer API is for personal use only. You can only connect to your own account or a small number of explicitly allowed users.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
19 tools covering the full Monzo API:
|
|
12
|
+
|
|
13
|
+
| Category | Tools | Description |
|
|
14
|
+
|----------|-------|-------------|
|
|
15
|
+
| **Accounts** | `monzo_whoami`, `monzo_list_accounts`, `monzo_get_balance` | View account info and balances |
|
|
16
|
+
| **Pots** | `monzo_list_pots`, `monzo_deposit_into_pot`, `monzo_withdraw_from_pot` | Manage savings pots |
|
|
17
|
+
| **Transactions** | `monzo_list_transactions`, `monzo_get_transaction`, `monzo_annotate_transaction` | Browse and annotate transactions |
|
|
18
|
+
| **Feed** | `monzo_create_feed_item` | Push custom items to the Monzo app feed |
|
|
19
|
+
| **Attachments** | `monzo_upload_attachment`, `monzo_register_attachment`, `monzo_deregister_attachment` | Attach images to transactions |
|
|
20
|
+
| **Receipts** | `monzo_create_receipt`, `monzo_get_receipt`, `monzo_delete_receipt` | Manage digital receipts |
|
|
21
|
+
| **Webhooks** | `monzo_register_webhook`, `monzo_list_webhooks`, `monzo_delete_webhook` | Set up real-time notifications |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Getting Your Monzo Access Token
|
|
26
|
+
|
|
27
|
+
You need an access token to use this server.
|
|
28
|
+
|
|
29
|
+
### Step 1: Create a Monzo Developer Account
|
|
30
|
+
|
|
31
|
+
1. Go to [developers.monzo.com](https://developers.monzo.com)
|
|
32
|
+
2. Log in with your Monzo email address
|
|
33
|
+
3. You'll receive a magic link in your email — click it to sign in
|
|
34
|
+
|
|
35
|
+
### Step 2: Get an Access Token via the API Playground
|
|
36
|
+
|
|
37
|
+
1. Go to [developers.monzo.com/api/playground](https://developers.monzo.com/api/playground)
|
|
38
|
+
2. Click **Auth** to start the authentication flow
|
|
39
|
+
3. You'll receive a **push notification** on your Monzo app — tap it and verify with your PIN, fingerprint, or Face ID (Strong Customer Authentication)
|
|
40
|
+
4. Once approved, the Playground will show your **Access Token**
|
|
41
|
+
5. Copy this token — you'll need it in the next section
|
|
42
|
+
|
|
43
|
+
### Important Notes About Tokens
|
|
44
|
+
|
|
45
|
+
- **Tokens expire** after approximately **6 hours**
|
|
46
|
+
- After authentication, you have **5 minutes** of full transaction history access. After that, only the **last 90 days** are available
|
|
47
|
+
- Generating a new token **invalidates** the previous one
|
|
48
|
+
- If your token expires, repeat Step 2
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
### Prerequisites
|
|
55
|
+
|
|
56
|
+
- [Node.js](https://nodejs.org/) 18 or later
|
|
57
|
+
|
|
58
|
+
### Use via npx (recommended)
|
|
59
|
+
|
|
60
|
+
No installation required — just configure your MCP client to run:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npx monzo-mcp
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Install globally
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm install -g monzo-mcp
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Then run:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
monzo-mcp-server
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Build from source
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
git clone https://github.com/samaxbytez/monzo-mcp-server.git
|
|
82
|
+
cd monzo-mcp-server
|
|
83
|
+
npm install
|
|
84
|
+
npm run build
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Configuration
|
|
90
|
+
|
|
91
|
+
### Claude Desktop
|
|
92
|
+
|
|
93
|
+
Add the following to your Claude Desktop config file:
|
|
94
|
+
|
|
95
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
96
|
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"mcpServers": {
|
|
101
|
+
"monzo": {
|
|
102
|
+
"command": "npx",
|
|
103
|
+
"args": ["monzo-mcp"],
|
|
104
|
+
"env": {
|
|
105
|
+
"MONZO_ACCESS_TOKEN": "your_access_token_here"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Then restart Claude Desktop.
|
|
113
|
+
|
|
114
|
+
### Claude Code (CLI)
|
|
115
|
+
|
|
116
|
+
Add to your project's `.mcp.json`:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"mcpServers": {
|
|
121
|
+
"monzo": {
|
|
122
|
+
"command": "npx",
|
|
123
|
+
"args": ["monzo-mcp"],
|
|
124
|
+
"env": {
|
|
125
|
+
"MONZO_ACCESS_TOKEN": "your_access_token_here"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Or add it directly via the CLI:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
claude mcp add monzo -- npx monzo-mcp
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Other MCP Clients (Cursor, Windsurf, Cline, etc.)
|
|
139
|
+
|
|
140
|
+
Refer to your client's documentation for how to add an MCP server. The server command is:
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
npx monzo-mcp
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
With the environment variable `MONZO_ACCESS_TOKEN` set to your token.
|
|
147
|
+
|
|
148
|
+
### Environment Variables
|
|
149
|
+
|
|
150
|
+
| Variable | Required | Description |
|
|
151
|
+
|----------|----------|-------------|
|
|
152
|
+
| `MONZO_ACCESS_TOKEN` | Yes | Your Monzo API access token |
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Usage Examples
|
|
157
|
+
|
|
158
|
+
Once configured, you can ask your AI assistant things like (using Claude as an example):
|
|
159
|
+
|
|
160
|
+
- **"What's my Monzo balance?"** — calls `monzo_get_balance`
|
|
161
|
+
- **"Show my recent transactions"** — calls `monzo_list_transactions`
|
|
162
|
+
- **"List my pots"** — calls `monzo_list_pots`
|
|
163
|
+
- **"Move £50 into my Holiday pot"** — calls `monzo_deposit_into_pot`
|
|
164
|
+
- **"What did I spend at Tesco last week?"** — calls `monzo_list_transactions` with filters
|
|
165
|
+
- **"Send me a notification in Monzo saying 'Remember to buy milk'"** — calls `monzo_create_feed_item`
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Tool Reference
|
|
170
|
+
|
|
171
|
+
### Accounts
|
|
172
|
+
|
|
173
|
+
#### `monzo_whoami`
|
|
174
|
+
Verify the authenticated user. Returns user ID, authentication type, and client ID.
|
|
175
|
+
|
|
176
|
+
#### `monzo_list_accounts`
|
|
177
|
+
List all accounts. Optionally filter by `account_type` (`uk_retail`, `uk_retail_joint`).
|
|
178
|
+
|
|
179
|
+
#### `monzo_get_balance`
|
|
180
|
+
Get the balance for a specific account. Returns balance, total balance, currency, and spend today — all in **pence** (minor units).
|
|
181
|
+
|
|
182
|
+
**Parameters:**
|
|
183
|
+
- `account_id` (required) — The account ID
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
### Pots
|
|
188
|
+
|
|
189
|
+
#### `monzo_list_pots`
|
|
190
|
+
List all pots for an account.
|
|
191
|
+
|
|
192
|
+
**Parameters:**
|
|
193
|
+
- `current_account_id` (required) — The account ID
|
|
194
|
+
|
|
195
|
+
#### `monzo_deposit_into_pot`
|
|
196
|
+
Move money from your account into a pot.
|
|
197
|
+
|
|
198
|
+
**Parameters:**
|
|
199
|
+
- `pot_id` (required) — The pot to deposit into
|
|
200
|
+
- `source_account_id` (required) — The account to move money from
|
|
201
|
+
- `amount` (required) — Amount in **pence** (e.g. `1000` = £10.00)
|
|
202
|
+
- `dedupe_id` (required) — A unique string to prevent duplicate deposits
|
|
203
|
+
|
|
204
|
+
#### `monzo_withdraw_from_pot`
|
|
205
|
+
Move money from a pot back into your account. Pots with "added security" (lock) cannot be withdrawn via API.
|
|
206
|
+
|
|
207
|
+
**Parameters:**
|
|
208
|
+
- `pot_id` (required) — The pot to withdraw from
|
|
209
|
+
- `destination_account_id` (required) — The account to move money to
|
|
210
|
+
- `amount` (required) — Amount in **pence**
|
|
211
|
+
- `dedupe_id` (required) — A unique string to prevent duplicate withdrawals
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
### Transactions
|
|
216
|
+
|
|
217
|
+
#### `monzo_list_transactions`
|
|
218
|
+
List transactions for an account. Limited to the last 90 days (after 5 minutes post-authentication).
|
|
219
|
+
|
|
220
|
+
**Parameters:**
|
|
221
|
+
- `account_id` (required) — The account ID
|
|
222
|
+
- `since` (optional) — RFC 3339 timestamp or object ID (e.g. `2024-01-01T00:00:00Z`)
|
|
223
|
+
- `before` (optional) — RFC 3339 timestamp
|
|
224
|
+
- `limit` (optional) — Results per page (default 30, max 100)
|
|
225
|
+
|
|
226
|
+
#### `monzo_get_transaction`
|
|
227
|
+
Get details of a single transaction.
|
|
228
|
+
|
|
229
|
+
**Parameters:**
|
|
230
|
+
- `transaction_id` (required) — The transaction ID
|
|
231
|
+
- `expand_merchant` (optional) — Set to `true` to include full merchant details
|
|
232
|
+
|
|
233
|
+
#### `monzo_annotate_transaction`
|
|
234
|
+
Add custom key-value metadata to a transaction.
|
|
235
|
+
|
|
236
|
+
**Parameters:**
|
|
237
|
+
- `transaction_id` (required) — The transaction ID
|
|
238
|
+
- `key` (required) — The metadata key
|
|
239
|
+
- `value` (required) — The metadata value (empty string to delete)
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
### Feed
|
|
244
|
+
|
|
245
|
+
#### `monzo_create_feed_item`
|
|
246
|
+
Create a custom item in the Monzo app feed.
|
|
247
|
+
|
|
248
|
+
**Parameters:**
|
|
249
|
+
- `account_id` (required) — The account ID
|
|
250
|
+
- `title` (required) — Feed item title
|
|
251
|
+
- `body` (required) — Feed item body text
|
|
252
|
+
- `image_url` (optional) — URL of an image to display
|
|
253
|
+
- `url` (optional) — URL to open when tapped
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
### Attachments
|
|
258
|
+
|
|
259
|
+
#### `monzo_upload_attachment`
|
|
260
|
+
Get a pre-signed upload URL for an image.
|
|
261
|
+
|
|
262
|
+
**Parameters:**
|
|
263
|
+
- `file_name` (required) — e.g. `receipt.png`
|
|
264
|
+
- `file_type` (required) — MIME type, e.g. `image/png`
|
|
265
|
+
- `content_length` (required) — File size in bytes
|
|
266
|
+
|
|
267
|
+
#### `monzo_register_attachment`
|
|
268
|
+
Attach an uploaded image to a transaction.
|
|
269
|
+
|
|
270
|
+
**Parameters:**
|
|
271
|
+
- `external_id` (required) — The transaction ID
|
|
272
|
+
- `file_url` (required) — The URL from `monzo_upload_attachment`
|
|
273
|
+
- `file_type` (required) — MIME type
|
|
274
|
+
|
|
275
|
+
#### `monzo_deregister_attachment`
|
|
276
|
+
Remove an attachment from a transaction.
|
|
277
|
+
|
|
278
|
+
**Parameters:**
|
|
279
|
+
- `id` (required) — The attachment ID
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
### Receipts
|
|
284
|
+
|
|
285
|
+
#### `monzo_create_receipt`
|
|
286
|
+
Create or update a digital receipt on a transaction.
|
|
287
|
+
|
|
288
|
+
**Parameters:**
|
|
289
|
+
- `transaction_id` (required) — The transaction ID
|
|
290
|
+
- `items` (required) — JSON array of receipt items (each with `description`, `amount` in pence, `currency`, `quantity`)
|
|
291
|
+
- `tax` (optional) — Total tax in pence
|
|
292
|
+
|
|
293
|
+
#### `monzo_get_receipt`
|
|
294
|
+
Get a receipt by its external ID.
|
|
295
|
+
|
|
296
|
+
**Parameters:**
|
|
297
|
+
- `external_id` (required) — Typically the transaction ID
|
|
298
|
+
|
|
299
|
+
#### `monzo_delete_receipt`
|
|
300
|
+
Delete a receipt.
|
|
301
|
+
|
|
302
|
+
**Parameters:**
|
|
303
|
+
- `external_id` (required) — Typically the transaction ID
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
### Webhooks
|
|
308
|
+
|
|
309
|
+
#### `monzo_register_webhook`
|
|
310
|
+
Register a URL to receive real-time transaction notifications.
|
|
311
|
+
|
|
312
|
+
**Parameters:**
|
|
313
|
+
- `account_id` (required) — The account ID
|
|
314
|
+
- `url` (required) — The webhook URL
|
|
315
|
+
|
|
316
|
+
#### `monzo_list_webhooks`
|
|
317
|
+
List all webhooks for an account.
|
|
318
|
+
|
|
319
|
+
**Parameters:**
|
|
320
|
+
- `account_id` (required) — The account ID
|
|
321
|
+
|
|
322
|
+
#### `monzo_delete_webhook`
|
|
323
|
+
Delete a webhook.
|
|
324
|
+
|
|
325
|
+
**Parameters:**
|
|
326
|
+
- `webhook_id` (required) — The webhook ID
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## Troubleshooting
|
|
331
|
+
|
|
332
|
+
### "Missing required environment variable: MONZO_ACCESS_TOKEN"
|
|
333
|
+
You haven't set the `MONZO_ACCESS_TOKEN` in your MCP server config. See [Getting Your Monzo Access Token](#getting-your-monzo-access-token).
|
|
334
|
+
|
|
335
|
+
### "Monzo API error (401): unauthorized"
|
|
336
|
+
Your access token has expired (tokens last ~6 hours). Get a new one from the [Monzo Playground](https://developers.monzo.com/api/playground).
|
|
337
|
+
|
|
338
|
+
### "Monzo API error (403): forbidden"
|
|
339
|
+
You may need to complete Strong Customer Authentication. Open the Monzo app and check for a pending approval notification.
|
|
340
|
+
|
|
341
|
+
### "Transaction history is empty or limited"
|
|
342
|
+
After 5 minutes post-authentication, the API only returns the last 90 days of transactions. This is a Monzo security restriction.
|
|
343
|
+
|
|
344
|
+
### Pots withdrawal fails
|
|
345
|
+
Pots with "added security" (locked pots) cannot be withdrawn from via the API. Unlock the pot in the Monzo app first.
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## License
|
|
350
|
+
|
|
351
|
+
MIT
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare class MonzoApiError extends Error {
|
|
2
|
+
readonly status: number;
|
|
3
|
+
readonly errorCode: string;
|
|
4
|
+
constructor(status: number, errorCode: string, message: string);
|
|
5
|
+
}
|
|
6
|
+
export declare class MonzoClient {
|
|
7
|
+
private accessToken;
|
|
8
|
+
constructor(accessToken: string);
|
|
9
|
+
get<T = unknown>(path: string, params?: Record<string, string>): Promise<T>;
|
|
10
|
+
postForm<T = unknown>(path: string, body?: Record<string, string>): Promise<T>;
|
|
11
|
+
putForm<T = unknown>(path: string, body?: Record<string, string>): Promise<T>;
|
|
12
|
+
patchForm<T = unknown>(path: string, body?: Record<string, string>): Promise<T>;
|
|
13
|
+
putJson<T = unknown>(path: string, body: unknown): Promise<T>;
|
|
14
|
+
deleteReq<T = unknown>(path: string, params?: Record<string, string>): Promise<T>;
|
|
15
|
+
private request;
|
|
16
|
+
}
|
package/build/client.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const MONZO_API_URL = "https://api.monzo.com";
|
|
2
|
+
export class MonzoApiError extends Error {
|
|
3
|
+
status;
|
|
4
|
+
errorCode;
|
|
5
|
+
constructor(status, errorCode, message) {
|
|
6
|
+
super(`Monzo API error (${status}): ${errorCode} - ${message}`);
|
|
7
|
+
this.name = "MonzoApiError";
|
|
8
|
+
this.status = status;
|
|
9
|
+
this.errorCode = errorCode;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function parseApiError(status, body) {
|
|
13
|
+
try {
|
|
14
|
+
const parsed = JSON.parse(body);
|
|
15
|
+
const code = parsed?.error ?? "unknown";
|
|
16
|
+
const message = parsed?.message ?? parsed?.error_description ?? `HTTP ${status}`;
|
|
17
|
+
return new MonzoApiError(status, code, message);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return new MonzoApiError(status, "unknown", `HTTP ${status} error`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function encodeFormBody(data) {
|
|
24
|
+
return new URLSearchParams(data).toString();
|
|
25
|
+
}
|
|
26
|
+
export class MonzoClient {
|
|
27
|
+
accessToken;
|
|
28
|
+
constructor(accessToken) {
|
|
29
|
+
this.accessToken = accessToken;
|
|
30
|
+
}
|
|
31
|
+
async get(path, params) {
|
|
32
|
+
return this.request("GET", path, undefined, undefined, params);
|
|
33
|
+
}
|
|
34
|
+
async postForm(path, body) {
|
|
35
|
+
return this.request("POST", path, body, "form");
|
|
36
|
+
}
|
|
37
|
+
async putForm(path, body) {
|
|
38
|
+
return this.request("PUT", path, body, "form");
|
|
39
|
+
}
|
|
40
|
+
async patchForm(path, body) {
|
|
41
|
+
return this.request("PATCH", path, body, "form");
|
|
42
|
+
}
|
|
43
|
+
async putJson(path, body) {
|
|
44
|
+
return this.request("PUT", path, body, "json");
|
|
45
|
+
}
|
|
46
|
+
async deleteReq(path, params) {
|
|
47
|
+
return this.request("DELETE", path, undefined, undefined, params);
|
|
48
|
+
}
|
|
49
|
+
async request(method, path, body, bodyType, params) {
|
|
50
|
+
const url = new URL(path, MONZO_API_URL);
|
|
51
|
+
if (params) {
|
|
52
|
+
for (const [k, v] of Object.entries(params)) {
|
|
53
|
+
url.searchParams.set(k, v);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const headers = {
|
|
57
|
+
Authorization: `Bearer ${this.accessToken}`,
|
|
58
|
+
};
|
|
59
|
+
let encodedBody;
|
|
60
|
+
if (body && bodyType === "json") {
|
|
61
|
+
headers["Content-Type"] = "application/json";
|
|
62
|
+
encodedBody = JSON.stringify(body);
|
|
63
|
+
}
|
|
64
|
+
else if (body && bodyType === "form") {
|
|
65
|
+
headers["Content-Type"] = "application/x-www-form-urlencoded";
|
|
66
|
+
encodedBody = encodeFormBody(body);
|
|
67
|
+
}
|
|
68
|
+
const response = await fetch(url.toString(), {
|
|
69
|
+
method,
|
|
70
|
+
headers,
|
|
71
|
+
body: encodedBody,
|
|
72
|
+
});
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
const errorBody = await response.text();
|
|
75
|
+
throw parseApiError(response.status, errorBody);
|
|
76
|
+
}
|
|
77
|
+
const text = await response.text();
|
|
78
|
+
if (!text) {
|
|
79
|
+
return {};
|
|
80
|
+
}
|
|
81
|
+
return JSON.parse(text);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
ADDED
package/build/index.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { MonzoClient } from "./client.js";
|
|
5
|
+
import { registerAccountTools } from "./tools/accounts.js";
|
|
6
|
+
import { registerPotTools } from "./tools/pots.js";
|
|
7
|
+
import { registerTransactionTools } from "./tools/transactions.js";
|
|
8
|
+
import { registerFeedTools } from "./tools/feed.js";
|
|
9
|
+
import { registerAttachmentTools } from "./tools/attachments.js";
|
|
10
|
+
import { registerReceiptTools } from "./tools/receipts.js";
|
|
11
|
+
import { registerWebhookTools } from "./tools/webhooks.js";
|
|
12
|
+
const MONZO_ACCESS_TOKEN = process.env.MONZO_ACCESS_TOKEN;
|
|
13
|
+
if (!MONZO_ACCESS_TOKEN) {
|
|
14
|
+
console.error("Missing required environment variable: MONZO_ACCESS_TOKEN");
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
const monzoClient = new MonzoClient(MONZO_ACCESS_TOKEN);
|
|
18
|
+
const server = new McpServer({
|
|
19
|
+
name: "monzo-api",
|
|
20
|
+
version: "1.0.0",
|
|
21
|
+
});
|
|
22
|
+
registerAccountTools(server, monzoClient);
|
|
23
|
+
registerPotTools(server, monzoClient);
|
|
24
|
+
registerTransactionTools(server, monzoClient);
|
|
25
|
+
registerFeedTools(server, monzoClient);
|
|
26
|
+
registerAttachmentTools(server, monzoClient);
|
|
27
|
+
registerReceiptTools(server, monzoClient);
|
|
28
|
+
registerWebhookTools(server, monzoClient);
|
|
29
|
+
async function main() {
|
|
30
|
+
const transport = new StdioServerTransport();
|
|
31
|
+
await server.connect(transport);
|
|
32
|
+
console.error("Monzo MCP Server running on stdio");
|
|
33
|
+
}
|
|
34
|
+
main().catch((error) => {
|
|
35
|
+
console.error("Fatal error:", error);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
});
|
|
38
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;AAE1D,IAAI,CAAC,kBAAkB,EAAE,CAAC;IACxB,OAAO,CAAC,KAAK,CACX,2DAA2D,CAC5D,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,kBAAkB,CAAC,CAAC;AAExD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,oBAAoB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAC1C,gBAAgB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AACtC,wBAAwB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAC9C,iBAAiB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AACvC,uBAAuB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAC7C,oBAAoB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAC1C,oBAAoB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAE1C,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;AACrD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { jsonResponse, errorResponse, logToolCall, buildParams } from "../utils.js";
|
|
3
|
+
export function registerAccountTools(server, client) {
|
|
4
|
+
server.registerTool("monzo_whoami", {
|
|
5
|
+
title: "Who Am I",
|
|
6
|
+
description: "Verify the authenticated Monzo user. Returns user ID, authentication type, and client ID.",
|
|
7
|
+
}, async () => {
|
|
8
|
+
logToolCall("monzo_whoami");
|
|
9
|
+
try {
|
|
10
|
+
const result = await client.get("/ping/whoami");
|
|
11
|
+
return jsonResponse(result);
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
return errorResponse(error);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
server.registerTool("monzo_list_accounts", {
|
|
18
|
+
title: "List Accounts",
|
|
19
|
+
description: "List the authenticated user's Monzo accounts. Returns account IDs, types, and descriptions.",
|
|
20
|
+
inputSchema: {
|
|
21
|
+
account_type: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("Filter by account type (e.g. 'uk_retail', 'uk_retail_joint')"),
|
|
25
|
+
},
|
|
26
|
+
}, async ({ account_type }) => {
|
|
27
|
+
logToolCall("monzo_list_accounts", { account_type });
|
|
28
|
+
try {
|
|
29
|
+
const params = buildParams({ account_type });
|
|
30
|
+
const result = await client.get("/accounts", params);
|
|
31
|
+
return jsonResponse(result);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
return errorResponse(error);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
server.registerTool("monzo_get_balance", {
|
|
38
|
+
title: "Get Balance",
|
|
39
|
+
description: "Fetch the balance of a Monzo account. Returns balance, total balance, currency, and spend today (all in minor units / pence).",
|
|
40
|
+
inputSchema: {
|
|
41
|
+
account_id: z
|
|
42
|
+
.string()
|
|
43
|
+
.describe("The account ID to get the balance for"),
|
|
44
|
+
},
|
|
45
|
+
}, async ({ account_id }) => {
|
|
46
|
+
logToolCall("monzo_get_balance", { account_id });
|
|
47
|
+
try {
|
|
48
|
+
const result = await client.get("/balance", { account_id });
|
|
49
|
+
return jsonResponse(result);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
return errorResponse(error);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=accounts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/tools/accounts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEpF,MAAM,UAAU,oBAAoB,CAClC,MAAiB,EACjB,MAAmB;IAEnB,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,UAAU;QACjB,WAAW,EACT,2FAA2F;KAC9F,EACD,KAAK,IAAI,EAAE;QACT,WAAW,CAAC,cAAc,CAAC,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAChD,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,6FAA6F;QAC/F,WAAW,EAAE;YACX,YAAY,EAAE,CAAC;iBACZ,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,8DAA8D,CAAC;SAC5E;KACF,EACD,KAAK,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE;QACzB,WAAW,CAAC,qBAAqB,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YACrD,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,aAAa;QACpB,WAAW,EACT,+HAA+H;QACjI,WAAW,EAAE;YACX,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,CAAC,uCAAuC,CAAC;SACrD;KACF,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;QACvB,WAAW,CAAC,mBAAmB,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;YAC5D,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { jsonResponse, errorResponse, logToolCall } from "../utils.js";
|
|
3
|
+
export function registerAttachmentTools(server, client) {
|
|
4
|
+
server.registerTool("monzo_upload_attachment", {
|
|
5
|
+
title: "Upload Attachment",
|
|
6
|
+
description: "Get a pre-signed upload URL for attaching an image to a Monzo transaction. Returns the upload URL and file URL to use with monzo_register_attachment.",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
file_name: z
|
|
9
|
+
.string()
|
|
10
|
+
.describe("The name of the file (e.g. 'receipt.png')"),
|
|
11
|
+
file_type: z
|
|
12
|
+
.string()
|
|
13
|
+
.describe("The MIME type of the file (e.g. 'image/png', 'image/jpeg')"),
|
|
14
|
+
content_length: z
|
|
15
|
+
.number()
|
|
16
|
+
.int()
|
|
17
|
+
.positive()
|
|
18
|
+
.describe("The file size in bytes"),
|
|
19
|
+
},
|
|
20
|
+
}, async ({ file_name, file_type, content_length }) => {
|
|
21
|
+
logToolCall("monzo_upload_attachment", { file_name, file_type });
|
|
22
|
+
try {
|
|
23
|
+
const result = await client.postForm("/attachment/upload", {
|
|
24
|
+
file_name,
|
|
25
|
+
file_type,
|
|
26
|
+
content_length: String(content_length),
|
|
27
|
+
});
|
|
28
|
+
return jsonResponse(result);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
return errorResponse(error);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
server.registerTool("monzo_register_attachment", {
|
|
35
|
+
title: "Register Attachment",
|
|
36
|
+
description: "Register an uploaded image as an attachment on a Monzo transaction. The image must already be uploaded to the URL from monzo_upload_attachment.",
|
|
37
|
+
inputSchema: {
|
|
38
|
+
external_id: z
|
|
39
|
+
.string()
|
|
40
|
+
.describe("The transaction ID to attach the image to"),
|
|
41
|
+
file_url: z
|
|
42
|
+
.string()
|
|
43
|
+
.describe("The file_url returned from monzo_upload_attachment"),
|
|
44
|
+
file_type: z
|
|
45
|
+
.string()
|
|
46
|
+
.describe("The MIME type of the file (e.g. 'image/png')"),
|
|
47
|
+
},
|
|
48
|
+
}, async ({ external_id, file_url, file_type }) => {
|
|
49
|
+
logToolCall("monzo_register_attachment", { external_id });
|
|
50
|
+
try {
|
|
51
|
+
const result = await client.postForm("/attachment/register", {
|
|
52
|
+
external_id,
|
|
53
|
+
file_url,
|
|
54
|
+
file_type,
|
|
55
|
+
});
|
|
56
|
+
return jsonResponse(result);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
return errorResponse(error);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
server.registerTool("monzo_deregister_attachment", {
|
|
63
|
+
title: "Deregister Attachment",
|
|
64
|
+
description: "Remove an attachment from a Monzo transaction.",
|
|
65
|
+
inputSchema: {
|
|
66
|
+
id: z
|
|
67
|
+
.string()
|
|
68
|
+
.describe("The attachment ID to remove"),
|
|
69
|
+
},
|
|
70
|
+
}, async ({ id }) => {
|
|
71
|
+
logToolCall("monzo_deregister_attachment", { id });
|
|
72
|
+
try {
|
|
73
|
+
const result = await client.postForm("/attachment/deregister", { id });
|
|
74
|
+
return jsonResponse(result);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
return errorResponse(error);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=attachments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/tools/attachments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { jsonResponse, errorResponse, logToolCall } from "../utils.js";
|
|
3
|
+
export function registerFeedTools(server, client) {
|
|
4
|
+
server.registerTool("monzo_create_feed_item", {
|
|
5
|
+
title: "Create Feed Item",
|
|
6
|
+
description: "Create a feed item in the Monzo app for a given account. The item appears in the user's transaction feed with a title, body, and optional image.",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
account_id: z
|
|
9
|
+
.string()
|
|
10
|
+
.describe("The account ID to create the feed item for"),
|
|
11
|
+
title: z
|
|
12
|
+
.string()
|
|
13
|
+
.describe("The title of the feed item"),
|
|
14
|
+
body: z
|
|
15
|
+
.string()
|
|
16
|
+
.describe("The body text of the feed item"),
|
|
17
|
+
image_url: z
|
|
18
|
+
.string()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("URL of an image to display with the feed item"),
|
|
21
|
+
url: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("URL to open when the feed item is tapped"),
|
|
25
|
+
},
|
|
26
|
+
}, async ({ account_id, title, body, image_url, url }) => {
|
|
27
|
+
logToolCall("monzo_create_feed_item", { account_id, title });
|
|
28
|
+
try {
|
|
29
|
+
const formBody = {
|
|
30
|
+
account_id,
|
|
31
|
+
type: "basic",
|
|
32
|
+
"params[title]": title,
|
|
33
|
+
"params[body]": body,
|
|
34
|
+
};
|
|
35
|
+
if (image_url)
|
|
36
|
+
formBody["params[image_url]"] = image_url;
|
|
37
|
+
if (url)
|
|
38
|
+
formBody["url"] = url;
|
|
39
|
+
const result = await client.postForm("/feed", formBody);
|
|
40
|
+
return jsonResponse(result);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
return errorResponse(error);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=feed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feed.js","sourceRoot":"","sources":["../../src/tools/feed.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEvE,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,MAAmB;IAEnB,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;QACE,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,kJAAkJ;QACpJ,WAAW,EAAE;YACX,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,CAAC,4CAA4C,CAAC;YACzD,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,CAAC,4BAA4B,CAAC;YACzC,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,QAAQ,CAAC,gCAAgC,CAAC;YAC7C,SAAS,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,+CAA+C,CAAC;YAC5D,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,0CAA0C,CAAC;SACxD;KACF,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,EAAE;QACpD,WAAW,CAAC,wBAAwB,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC;YACH,MAAM,QAAQ,GAA2B;gBACvC,UAAU;gBACV,IAAI,EAAE,OAAO;gBACb,eAAe,EAAE,KAAK;gBACtB,cAAc,EAAE,IAAI;aACrB,CAAC;YACF,IAAI,SAAS;gBAAE,QAAQ,CAAC,mBAAmB,CAAC,GAAG,SAAS,CAAC;YACzD,IAAI,GAAG;gBAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;YAE/B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACxD,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { jsonResponse, errorResponse, logToolCall } from "../utils.js";
|
|
3
|
+
export function registerPotTools(server, client) {
|
|
4
|
+
server.registerTool("monzo_list_pots", {
|
|
5
|
+
title: "List Pots",
|
|
6
|
+
description: "List all pots for a Monzo account. Returns pot IDs, names, balances, and styles.",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
current_account_id: z
|
|
9
|
+
.string()
|
|
10
|
+
.describe("The account ID to list pots for"),
|
|
11
|
+
},
|
|
12
|
+
}, async ({ current_account_id }) => {
|
|
13
|
+
logToolCall("monzo_list_pots", { current_account_id });
|
|
14
|
+
try {
|
|
15
|
+
const result = await client.get("/pots", { current_account_id });
|
|
16
|
+
return jsonResponse(result);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
return errorResponse(error);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
server.registerTool("monzo_deposit_into_pot", {
|
|
23
|
+
title: "Deposit Into Pot",
|
|
24
|
+
description: "Move money from a Monzo account into a pot. Amount is in pence (e.g. 1000 = £10.00). Requires a unique dedupe_id to prevent duplicate deposits.",
|
|
25
|
+
inputSchema: {
|
|
26
|
+
pot_id: z
|
|
27
|
+
.string()
|
|
28
|
+
.describe("The pot ID to deposit into"),
|
|
29
|
+
source_account_id: z
|
|
30
|
+
.string()
|
|
31
|
+
.describe("The account ID to move money from"),
|
|
32
|
+
amount: z
|
|
33
|
+
.number()
|
|
34
|
+
.int()
|
|
35
|
+
.positive()
|
|
36
|
+
.describe("Amount in pence to deposit (e.g. 1000 = £10.00)"),
|
|
37
|
+
dedupe_id: z
|
|
38
|
+
.string()
|
|
39
|
+
.describe("Unique string to prevent duplicate deposits"),
|
|
40
|
+
},
|
|
41
|
+
}, async ({ pot_id, source_account_id, amount, dedupe_id }) => {
|
|
42
|
+
logToolCall("monzo_deposit_into_pot", { pot_id, amount });
|
|
43
|
+
try {
|
|
44
|
+
const result = await client.putForm(`/pots/${pot_id}/deposit`, {
|
|
45
|
+
source_account_id,
|
|
46
|
+
amount: String(amount),
|
|
47
|
+
dedupe_id,
|
|
48
|
+
});
|
|
49
|
+
return jsonResponse(result);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
return errorResponse(error);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
server.registerTool("monzo_withdraw_from_pot", {
|
|
56
|
+
title: "Withdraw From Pot",
|
|
57
|
+
description: "Move money from a pot back into a Monzo account. Amount is in pence (e.g. 1000 = £10.00). Requires a unique dedupe_id. Pots with added security cannot be withdrawn via API.",
|
|
58
|
+
inputSchema: {
|
|
59
|
+
pot_id: z
|
|
60
|
+
.string()
|
|
61
|
+
.describe("The pot ID to withdraw from"),
|
|
62
|
+
destination_account_id: z
|
|
63
|
+
.string()
|
|
64
|
+
.describe("The account ID to move money to"),
|
|
65
|
+
amount: z
|
|
66
|
+
.number()
|
|
67
|
+
.int()
|
|
68
|
+
.positive()
|
|
69
|
+
.describe("Amount in pence to withdraw (e.g. 1000 = £10.00)"),
|
|
70
|
+
dedupe_id: z
|
|
71
|
+
.string()
|
|
72
|
+
.describe("Unique string to prevent duplicate withdrawals"),
|
|
73
|
+
},
|
|
74
|
+
}, async ({ pot_id, destination_account_id, amount, dedupe_id }) => {
|
|
75
|
+
logToolCall("monzo_withdraw_from_pot", { pot_id, amount });
|
|
76
|
+
try {
|
|
77
|
+
const result = await client.putForm(`/pots/${pot_id}/withdraw`, {
|
|
78
|
+
destination_account_id,
|
|
79
|
+
amount: String(amount),
|
|
80
|
+
dedupe_id,
|
|
81
|
+
});
|
|
82
|
+
return jsonResponse(result);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
return errorResponse(error);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=pots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pots.js","sourceRoot":"","sources":["../../src/tools/pots.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEvE,MAAM,UAAU,gBAAgB,CAC9B,MAAiB,EACjB,MAAmB;IAEnB,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,KAAK,EAAE,WAAW;QAClB,WAAW,EACT,kFAAkF;QACpF,WAAW,EAAE;YACX,kBAAkB,EAAE,CAAC;iBAClB,MAAM,EAAE;iBACR,QAAQ,CAAC,iCAAiC,CAAC;SAC/C;KACF,EACD,KAAK,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE;QAC/B,WAAW,CAAC,iBAAiB,EAAE,EAAE,kBAAkB,EAAE,CAAC,CAAC;QACvD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,kBAAkB,EAAE,CAAC,CAAC;YACjE,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;QACE,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,iJAAiJ;QACnJ,WAAW,EAAE;YACX,MAAM,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,QAAQ,CAAC,4BAA4B,CAAC;YACzC,iBAAiB,EAAE,CAAC;iBACjB,MAAM,EAAE;iBACR,QAAQ,CAAC,mCAAmC,CAAC;YAChD,MAAM,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,QAAQ,EAAE;iBACV,QAAQ,CAAC,iDAAiD,CAAC;YAC9D,SAAS,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,CAAC,6CAA6C,CAAC;SAC3D;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE;QACzD,WAAW,CAAC,wBAAwB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,MAAM,UAAU,EAAE;gBAC7D,iBAAiB;gBACjB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;gBACtB,SAAS;aACV,CAAC,CAAC;YACH,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EACT,8KAA8K;QAChL,WAAW,EAAE;YACX,MAAM,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,QAAQ,CAAC,6BAA6B,CAAC;YAC1C,sBAAsB,EAAE,CAAC;iBACtB,MAAM,EAAE;iBACR,QAAQ,CAAC,iCAAiC,CAAC;YAC9C,MAAM,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,QAAQ,EAAE;iBACV,QAAQ,CAAC,kDAAkD,CAAC;YAC/D,SAAS,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,CAAC,gDAAgD,CAAC;SAC9D;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE;QAC9D,WAAW,CAAC,yBAAyB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,MAAM,WAAW,EAAE;gBAC9D,sBAAsB;gBACtB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;gBACtB,SAAS;aACV,CAAC,CAAC;YACH,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { jsonResponse, errorResponse, logToolCall } from "../utils.js";
|
|
3
|
+
export function registerReceiptTools(server, client) {
|
|
4
|
+
server.registerTool("monzo_create_receipt", {
|
|
5
|
+
title: "Create/Update Receipt",
|
|
6
|
+
description: "Create or update a receipt on a Monzo transaction. Provide the transaction ID and receipt items as a JSON structure.",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
transaction_id: z
|
|
9
|
+
.string()
|
|
10
|
+
.describe("The transaction ID to attach the receipt to"),
|
|
11
|
+
items: z
|
|
12
|
+
.string()
|
|
13
|
+
.describe("JSON array of receipt items, each with: description (string), amount (integer in pence), currency (string, e.g. 'GBP'), quantity (number). Example: [{\"description\":\"Coffee\",\"amount\":350,\"currency\":\"GBP\",\"quantity\":1}]"),
|
|
14
|
+
tax: z
|
|
15
|
+
.number()
|
|
16
|
+
.int()
|
|
17
|
+
.optional()
|
|
18
|
+
.describe("Total tax amount in pence"),
|
|
19
|
+
},
|
|
20
|
+
}, async ({ transaction_id, items, tax }) => {
|
|
21
|
+
logToolCall("monzo_create_receipt", { transaction_id });
|
|
22
|
+
try {
|
|
23
|
+
const parsedItems = JSON.parse(items);
|
|
24
|
+
const receiptBody = {
|
|
25
|
+
transaction_id,
|
|
26
|
+
external_id: transaction_id,
|
|
27
|
+
items: parsedItems,
|
|
28
|
+
};
|
|
29
|
+
if (tax !== undefined)
|
|
30
|
+
receiptBody.tax = tax;
|
|
31
|
+
const result = await client.putJson("/transaction-receipts", receiptBody);
|
|
32
|
+
return jsonResponse(result);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
return errorResponse(error);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
server.registerTool("monzo_get_receipt", {
|
|
39
|
+
title: "Get Receipt",
|
|
40
|
+
description: "Retrieve a receipt attached to a Monzo transaction.",
|
|
41
|
+
inputSchema: {
|
|
42
|
+
external_id: z
|
|
43
|
+
.string()
|
|
44
|
+
.describe("The external ID (typically the transaction ID) of the receipt"),
|
|
45
|
+
},
|
|
46
|
+
}, async ({ external_id }) => {
|
|
47
|
+
logToolCall("monzo_get_receipt", { external_id });
|
|
48
|
+
try {
|
|
49
|
+
const result = await client.get("/transaction-receipts", { external_id });
|
|
50
|
+
return jsonResponse(result);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
return errorResponse(error);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
server.registerTool("monzo_delete_receipt", {
|
|
57
|
+
title: "Delete Receipt",
|
|
58
|
+
description: "Delete a receipt from a Monzo transaction.",
|
|
59
|
+
inputSchema: {
|
|
60
|
+
external_id: z
|
|
61
|
+
.string()
|
|
62
|
+
.describe("The external ID (typically the transaction ID) of the receipt to delete"),
|
|
63
|
+
},
|
|
64
|
+
}, async ({ external_id }) => {
|
|
65
|
+
logToolCall("monzo_delete_receipt", { external_id });
|
|
66
|
+
try {
|
|
67
|
+
const result = await client.deleteReq("/transaction-receipts", { external_id });
|
|
68
|
+
return jsonResponse(result);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
return errorResponse(error);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=receipts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipts.js","sourceRoot":"","sources":["../../src/tools/receipts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { jsonResponse, errorResponse, logToolCall, buildParams } from "../utils.js";
|
|
3
|
+
export function registerTransactionTools(server, client) {
|
|
4
|
+
server.registerTool("monzo_list_transactions", {
|
|
5
|
+
title: "List Transactions",
|
|
6
|
+
description: "List transactions for a Monzo account. Returns transaction amounts, merchants, categories, and metadata. Note: transaction history is limited to 90 days for API access.",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
account_id: z
|
|
9
|
+
.string()
|
|
10
|
+
.describe("The account ID to list transactions for"),
|
|
11
|
+
since: z
|
|
12
|
+
.string()
|
|
13
|
+
.optional()
|
|
14
|
+
.describe("RFC 3339 timestamp or object ID to filter transactions after (e.g. '2024-01-01T00:00:00Z')"),
|
|
15
|
+
before: z
|
|
16
|
+
.string()
|
|
17
|
+
.optional()
|
|
18
|
+
.describe("RFC 3339 timestamp to filter transactions before"),
|
|
19
|
+
limit: z
|
|
20
|
+
.number()
|
|
21
|
+
.int()
|
|
22
|
+
.positive()
|
|
23
|
+
.max(100)
|
|
24
|
+
.optional()
|
|
25
|
+
.describe("Number of results per page (default 30, max 100)"),
|
|
26
|
+
},
|
|
27
|
+
}, async ({ account_id, since, before, limit }) => {
|
|
28
|
+
logToolCall("monzo_list_transactions", { account_id, since, before, limit });
|
|
29
|
+
try {
|
|
30
|
+
const params = buildParams({ account_id, since, before, limit });
|
|
31
|
+
const result = await client.get("/transactions", params);
|
|
32
|
+
return jsonResponse(result);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
return errorResponse(error);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
server.registerTool("monzo_get_transaction", {
|
|
39
|
+
title: "Get Transaction",
|
|
40
|
+
description: "Retrieve details of a single Monzo transaction by its ID. Optionally expand merchant details.",
|
|
41
|
+
inputSchema: {
|
|
42
|
+
transaction_id: z
|
|
43
|
+
.string()
|
|
44
|
+
.describe("The transaction ID to look up"),
|
|
45
|
+
expand_merchant: z
|
|
46
|
+
.boolean()
|
|
47
|
+
.optional()
|
|
48
|
+
.describe("Set to true to include full merchant details"),
|
|
49
|
+
},
|
|
50
|
+
}, async ({ transaction_id, expand_merchant }) => {
|
|
51
|
+
logToolCall("monzo_get_transaction", { transaction_id });
|
|
52
|
+
try {
|
|
53
|
+
const params = {};
|
|
54
|
+
if (expand_merchant) {
|
|
55
|
+
params["expand[]"] = "merchant";
|
|
56
|
+
}
|
|
57
|
+
const result = await client.get(`/transactions/${transaction_id}`, params);
|
|
58
|
+
return jsonResponse(result);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
return errorResponse(error);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
server.registerTool("monzo_annotate_transaction", {
|
|
65
|
+
title: "Annotate Transaction",
|
|
66
|
+
description: "Add custom metadata/annotations to a Monzo transaction. You can store key-value pairs on the transaction.",
|
|
67
|
+
inputSchema: {
|
|
68
|
+
transaction_id: z
|
|
69
|
+
.string()
|
|
70
|
+
.describe("The transaction ID to annotate"),
|
|
71
|
+
key: z
|
|
72
|
+
.string()
|
|
73
|
+
.describe("The metadata key (will be stored as metadata[key])"),
|
|
74
|
+
value: z
|
|
75
|
+
.string()
|
|
76
|
+
.describe("The metadata value. Set to empty string to delete the key."),
|
|
77
|
+
},
|
|
78
|
+
}, async ({ transaction_id, key, value }) => {
|
|
79
|
+
logToolCall("monzo_annotate_transaction", { transaction_id, key });
|
|
80
|
+
try {
|
|
81
|
+
const result = await client.patchForm(`/transactions/${transaction_id}`, {
|
|
82
|
+
[`metadata[${key}]`]: value,
|
|
83
|
+
});
|
|
84
|
+
return jsonResponse(result);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
return errorResponse(error);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=transactions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transactions.js","sourceRoot":"","sources":["../../src/tools/transactions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { jsonResponse, errorResponse, logToolCall } from "../utils.js";
|
|
3
|
+
export function registerWebhookTools(server, client) {
|
|
4
|
+
server.registerTool("monzo_register_webhook", {
|
|
5
|
+
title: "Register Webhook",
|
|
6
|
+
description: "Register a webhook URL to receive real-time notifications for a Monzo account. Each time a transaction is created, Monzo will POST the transaction data to the URL.",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
account_id: z
|
|
9
|
+
.string()
|
|
10
|
+
.describe("The account ID to register the webhook for"),
|
|
11
|
+
url: z
|
|
12
|
+
.string()
|
|
13
|
+
.describe("The URL that Monzo will POST transaction events to"),
|
|
14
|
+
},
|
|
15
|
+
}, async ({ account_id, url }) => {
|
|
16
|
+
logToolCall("monzo_register_webhook", { account_id, url });
|
|
17
|
+
try {
|
|
18
|
+
const result = await client.postForm("/webhooks", { account_id, url });
|
|
19
|
+
return jsonResponse(result);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
return errorResponse(error);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
server.registerTool("monzo_list_webhooks", {
|
|
26
|
+
title: "List Webhooks",
|
|
27
|
+
description: "List all registered webhooks for a Monzo account.",
|
|
28
|
+
inputSchema: {
|
|
29
|
+
account_id: z
|
|
30
|
+
.string()
|
|
31
|
+
.describe("The account ID to list webhooks for"),
|
|
32
|
+
},
|
|
33
|
+
}, async ({ account_id }) => {
|
|
34
|
+
logToolCall("monzo_list_webhooks", { account_id });
|
|
35
|
+
try {
|
|
36
|
+
const result = await client.get("/webhooks", { account_id });
|
|
37
|
+
return jsonResponse(result);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
return errorResponse(error);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
server.registerTool("monzo_delete_webhook", {
|
|
44
|
+
title: "Delete Webhook",
|
|
45
|
+
description: "Delete a registered webhook by its ID.",
|
|
46
|
+
inputSchema: {
|
|
47
|
+
webhook_id: z
|
|
48
|
+
.string()
|
|
49
|
+
.describe("The webhook ID to delete"),
|
|
50
|
+
},
|
|
51
|
+
}, async ({ webhook_id }) => {
|
|
52
|
+
logToolCall("monzo_delete_webhook", { webhook_id });
|
|
53
|
+
try {
|
|
54
|
+
const result = await client.deleteReq(`/webhooks/${webhook_id}`);
|
|
55
|
+
return jsonResponse(result);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
return errorResponse(error);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=webhooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/tools/webhooks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEvE,MAAM,UAAU,oBAAoB,CAClC,MAAiB,EACjB,MAAmB;IAEnB,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;QACE,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,qKAAqK;QACvK,WAAW,EAAE;YACX,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,CAAC,4CAA4C,CAAC;YACzD,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,QAAQ,CAAC,oDAAoD,CAAC;SAClE;KACF,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,EAAE;QAC5B,WAAW,CAAC,wBAAwB,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;YACvE,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,mDAAmD;QACrD,WAAW,EAAE;YACX,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,CAAC,qCAAqC,CAAC;SACnD;KACF,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;QACvB,WAAW,CAAC,qBAAqB,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;YAC7D,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,gBAAgB;QACvB,WAAW,EACT,wCAAwC;QAC1C,WAAW,EAAE;YACX,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,CAAC,0BAA0B,CAAC;SACxC;KACF,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;QACvB,WAAW,CAAC,sBAAsB,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QACpD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,aAAa,UAAU,EAAE,CAAC,CAAC;YACjE,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
package/build/utils.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const TOKEN_BUFFER_MS = 60000;
|
|
2
|
+
export declare function jsonResponse(data: unknown): {
|
|
3
|
+
content: {
|
|
4
|
+
type: "text";
|
|
5
|
+
text: string;
|
|
6
|
+
}[];
|
|
7
|
+
};
|
|
8
|
+
export declare function errorResponse(error: unknown): {
|
|
9
|
+
content: {
|
|
10
|
+
type: "text";
|
|
11
|
+
text: string;
|
|
12
|
+
}[];
|
|
13
|
+
isError: boolean;
|
|
14
|
+
};
|
|
15
|
+
export declare function buildParams(obj: Record<string, unknown>): Record<string, string>;
|
|
16
|
+
export declare function logToolCall(tool: string, params?: Record<string, unknown>): void;
|
package/build/utils.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const TOKEN_BUFFER_MS = 60_000;
|
|
2
|
+
export function jsonResponse(data) {
|
|
3
|
+
return {
|
|
4
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
5
|
+
};
|
|
6
|
+
}
|
|
7
|
+
export function errorResponse(error) {
|
|
8
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
9
|
+
return {
|
|
10
|
+
content: [{ type: "text", text: `Error: ${msg}` }],
|
|
11
|
+
isError: true,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function buildParams(obj) {
|
|
15
|
+
const params = {};
|
|
16
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
17
|
+
if (v !== undefined && v !== null)
|
|
18
|
+
params[k] = String(v);
|
|
19
|
+
}
|
|
20
|
+
return params;
|
|
21
|
+
}
|
|
22
|
+
export function logToolCall(tool, params) {
|
|
23
|
+
const sanitized = { ts: new Date().toISOString(), tool };
|
|
24
|
+
if (params) {
|
|
25
|
+
for (const [k, v] of Object.entries(params)) {
|
|
26
|
+
sanitized[k] = typeof v === "string" && v.length > 100
|
|
27
|
+
? v.slice(0, 20) + "..."
|
|
28
|
+
: v;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
console.error(JSON.stringify(sanitized));
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC;AAEtC,MAAM,UAAU,YAAY,CAAC,IAAa;IACxC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;KAC1E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACnE,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,GAAG,EAAE,EAAE,CAAC;QAC3D,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,GAA4B;IAE5B,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI;YAAE,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,MAAgC;IACxE,MAAM,SAAS,GAA4B,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC;IAClF,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5C,SAAS,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,GAAG;gBACpD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK;gBACxB,CAAC,CAAC,CAAC,CAAC;QACR,CAAC;IACH,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;AAC3C,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "monzo-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for the Monzo banking API",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"monzo",
|
|
9
|
+
"mcp",
|
|
10
|
+
"model-context-protocol",
|
|
11
|
+
"banking",
|
|
12
|
+
"ai",
|
|
13
|
+
"claude",
|
|
14
|
+
"llm"
|
|
15
|
+
],
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/samaxbytez/monzo-mcp-server.git"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/samaxbytez/monzo-mcp-server#readme",
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/samaxbytez/monzo-mcp-server/issues"
|
|
23
|
+
},
|
|
24
|
+
"bin": {
|
|
25
|
+
"monzo-mcp-server": "build/index.js"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"build"
|
|
29
|
+
],
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=18"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsc && chmod 755 build/index.js",
|
|
35
|
+
"dev": "tsc --watch",
|
|
36
|
+
"start": "node build/index.js",
|
|
37
|
+
"type-check": "tsc --noEmit",
|
|
38
|
+
"test": "vitest run",
|
|
39
|
+
"test:watch": "vitest",
|
|
40
|
+
"prepublishOnly": "npm run build"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
44
|
+
"zod": "^3.25.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "^22.16.0",
|
|
48
|
+
"typescript": "^5.8.3",
|
|
49
|
+
"vitest": "^4.0.18"
|
|
50
|
+
}
|
|
51
|
+
}
|