@bank-mcp/server 0.1.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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +564 -0
  3. package/dist/config.d.ts +11 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +79 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/index.d.ts +11 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +33 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/init.d.ts +6 -0
  12. package/dist/init.d.ts.map +1 -0
  13. package/dist/init.js +96 -0
  14. package/dist/init.js.map +1 -0
  15. package/dist/providers/base.d.ts +22 -0
  16. package/dist/providers/base.d.ts.map +1 -0
  17. package/dist/providers/base.js +9 -0
  18. package/dist/providers/base.js.map +1 -0
  19. package/dist/providers/enable-banking/auth.d.ts +9 -0
  20. package/dist/providers/enable-banking/auth.d.ts.map +1 -0
  21. package/dist/providers/enable-banking/auth.js +30 -0
  22. package/dist/providers/enable-banking/auth.js.map +1 -0
  23. package/dist/providers/enable-banking/index.d.ts +12 -0
  24. package/dist/providers/enable-banking/index.d.ts.map +1 -0
  25. package/dist/providers/enable-banking/index.js +171 -0
  26. package/dist/providers/enable-banking/index.js.map +1 -0
  27. package/dist/providers/mock/index.d.ts +18 -0
  28. package/dist/providers/mock/index.d.ts.map +1 -0
  29. package/dist/providers/mock/index.js +151 -0
  30. package/dist/providers/mock/index.js.map +1 -0
  31. package/dist/providers/plaid/index.d.ts +12 -0
  32. package/dist/providers/plaid/index.d.ts.map +1 -0
  33. package/dist/providers/plaid/index.js +213 -0
  34. package/dist/providers/plaid/index.js.map +1 -0
  35. package/dist/providers/registry.d.ts +4 -0
  36. package/dist/providers/registry.d.ts.map +1 -0
  37. package/dist/providers/registry.js +26 -0
  38. package/dist/providers/registry.js.map +1 -0
  39. package/dist/providers/teller/index.d.ts +12 -0
  40. package/dist/providers/teller/index.d.ts.map +1 -0
  41. package/dist/providers/teller/index.js +215 -0
  42. package/dist/providers/teller/index.js.map +1 -0
  43. package/dist/providers/tink/index.d.ts +12 -0
  44. package/dist/providers/tink/index.d.ts.map +1 -0
  45. package/dist/providers/tink/index.js +169 -0
  46. package/dist/providers/tink/index.js.map +1 -0
  47. package/dist/server.d.ts +2 -0
  48. package/dist/server.d.ts.map +1 -0
  49. package/dist/server.js +90 -0
  50. package/dist/server.js.map +1 -0
  51. package/dist/tools/get-balance.d.ts +8 -0
  52. package/dist/tools/get-balance.d.ts.map +1 -0
  53. package/dist/tools/get-balance.js +39 -0
  54. package/dist/tools/get-balance.js.map +1 -0
  55. package/dist/tools/list-accounts.d.ts +7 -0
  56. package/dist/tools/list-accounts.d.ts.map +1 -0
  57. package/dist/tools/list-accounts.js +33 -0
  58. package/dist/tools/list-accounts.js.map +1 -0
  59. package/dist/tools/list-transactions.d.ts +17 -0
  60. package/dist/tools/list-transactions.d.ts.map +1 -0
  61. package/dist/tools/list-transactions.js +104 -0
  62. package/dist/tools/list-transactions.js.map +1 -0
  63. package/dist/tools/search-transactions.d.ts +10 -0
  64. package/dist/tools/search-transactions.d.ts.map +1 -0
  65. package/dist/tools/search-transactions.js +27 -0
  66. package/dist/tools/search-transactions.js.map +1 -0
  67. package/dist/tools/spending-summary.d.ts +25 -0
  68. package/dist/tools/spending-summary.d.ts.map +1 -0
  69. package/dist/tools/spending-summary.js +65 -0
  70. package/dist/tools/spending-summary.js.map +1 -0
  71. package/dist/types.d.ts +65 -0
  72. package/dist/types.d.ts.map +1 -0
  73. package/dist/types.js +21 -0
  74. package/dist/types.js.map +1 -0
  75. package/dist/utils/cache.d.ts +19 -0
  76. package/dist/utils/cache.d.ts.map +1 -0
  77. package/dist/utils/cache.js +33 -0
  78. package/dist/utils/cache.js.map +1 -0
  79. package/dist/utils/http.d.ts +12 -0
  80. package/dist/utils/http.d.ts.map +1 -0
  81. package/dist/utils/http.js +34 -0
  82. package/dist/utils/http.js.map +1 -0
  83. package/dist/utils/zod-to-json.d.ts +9 -0
  84. package/dist/utils/zod-to-json.d.ts.map +1 -0
  85. package/dist/utils/zod-to-json.js +62 -0
  86. package/dist/utils/zod-to-json.js.map +1 -0
  87. package/package.json +58 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 bank-mcp contributors
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,564 @@
1
+ # 🏦 bank-mcp
2
+
3
+ <p align="center">
4
+ <img src="bank-mcp.png" alt="bank-mcp — Banking data for AI assistants" width="700">
5
+ </p>
6
+
7
+ **Give your AI assistant secure, read-only access to your bank accounts.**
8
+
9
+ [![npm version](https://img.shields.io/npm/v/@bank-mcp/server.svg)](https://www.npmjs.com/package/@bank-mcp/server)
10
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
11
+ [![CI](https://github.com/elcukro/bank-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/elcukro/bank-mcp/actions/workflows/ci.yml)
12
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D18-brightgreen.svg)](https://nodejs.org/)
13
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue.svg)](https://www.typescriptlang.org/)
14
+
15
+ ---
16
+
17
+ Most people manage their finances by logging into bank portals, downloading CSVs, and building spreadsheets. bank-mcp eliminates that friction by letting your AI assistant query your bank accounts directly — balances, transactions, spending breakdowns — through natural conversation. It connects to real bank APIs via the [Model Context Protocol](https://modelcontextprotocol.io) so any MCP-compatible client (Claude Code, Claude Desktop, and others) can understand your finances.
18
+
19
+ - **5 providers, 15,000+ institutions** — US and European banks covered
20
+ - **Read-only by design** — no write access, no transfers, no modifications
21
+ - **Works with any MCP client** — Claude Code, Claude Desktop, Cursor, and more
22
+ - **Pluggable architecture** — add your own provider in under 100 lines
23
+
24
+ ## Table of Contents
25
+
26
+ - [Supported Providers](#supported-providers)
27
+ - [Quick Start](#quick-start)
28
+ - [Client Setup](#client-setup)
29
+ - [Available Tools](#available-tools)
30
+ - [Architecture](#architecture)
31
+ - [Provider Setup Guides](#provider-setup-guides)
32
+ - [Caching](#caching)
33
+ - [Multiple Connections](#multiple-connections)
34
+ - [Security](#security)
35
+ - [Adding a New Provider](#adding-a-new-provider)
36
+ - [Troubleshooting](#troubleshooting)
37
+ - [Development](#development)
38
+ - [Contributing](#contributing)
39
+ - [License](#license)
40
+
41
+ ## Supported Providers
42
+
43
+ | Provider | Region | Institutions | Auth Method | Setup Difficulty |
44
+ |----------|--------|-------------|-------------|-----------------|
45
+ | **[Enable Banking](https://enablebanking.com)** | Europe | 2,000+ | RSA key + session | Medium |
46
+ | **[Teller](https://teller.io)** | US | 7,000+ | mTLS certificate | Medium |
47
+ | **[Plaid](https://plaid.com)** | US / CA / EU | 12,000+ | Client ID + secret | Easy |
48
+ | **[Tink](https://tink.com)** | Europe | 3,400+ | OAuth2 token | Easy |
49
+ | **Mock** | Demo | — | None | Instant |
50
+
51
+ ### US Banks
52
+
53
+ Supported through Plaid and Teller — covering the top 20 US institutions and thousands more:
54
+
55
+ JPMorgan Chase · Bank of America · Wells Fargo · Citibank · Capital One · U.S. Bank · PNC · Truist · Goldman Sachs · TD Bank · Citizens · Fifth Third · M&T Bank · Huntington · KeyBank · Ally · Regions · BMO · American Express · USAA
56
+
57
+ ### European Banks
58
+
59
+ Supported through Enable Banking and Tink — covering major banks across the EU and UK:
60
+
61
+ HSBC · BNP Paribas · Deutsche Bank · ING · Crédit Agricole · Santander · Société Générale · UniCredit · Intesa Sanpaolo · Barclays · Lloyds · BBVA · CaixaBank · Commerzbank · Rabobank · ABN AMRO · Swedbank · Handelsbanken · Nordea · PKO Bank Polski
62
+
63
+ ## Quick Start
64
+
65
+ ### 1. Configure a bank connection
66
+
67
+ ```bash
68
+ npx @bank-mcp/server init
69
+ ```
70
+
71
+ The interactive wizard walks you through selecting a provider and entering credentials. It validates your connection by fetching accounts before saving.
72
+
73
+ ### 2. Add to your MCP client
74
+
75
+ Add bank-mcp to your AI tool's MCP configuration. Here's the most common setup:
76
+
77
+ **Claude Code** (`.mcp.json` in your project root or `~/.claude/.mcp.json` globally):
78
+
79
+ ```json
80
+ {
81
+ "mcpServers": {
82
+ "bank": {
83
+ "command": "npx",
84
+ "args": ["@bank-mcp/server"]
85
+ }
86
+ }
87
+ }
88
+ ```
89
+
90
+ > **Using a different tool?** See [Client Setup](#client-setup) for Claude Desktop, Cursor, VS Code, Windsurf, Codex CLI, Gemini CLI, and Zed.
91
+
92
+ ### 3. Try it
93
+
94
+ Ask your AI assistant about your finances in natural language:
95
+
96
+ ```
97
+ "What's my checking account balance?"
98
+ "Show my spending by category this month"
99
+ "Find all Amazon purchases over $50"
100
+ "Compare my spending this month vs last month"
101
+ ```
102
+
103
+ ### Demo Mode
104
+
105
+ Don't have bank credentials yet? Start with realistic fake data:
106
+
107
+ ```bash
108
+ npx @bank-mcp/server --mock
109
+ ```
110
+
111
+ This launches with a mock provider that generates deterministic sample accounts and transactions — perfect for testing your setup or building on top of bank-mcp before connecting real accounts.
112
+
113
+ ## Client Setup
114
+
115
+ bank-mcp works with any MCP-compatible client. Pick your tool below.
116
+
117
+ ### Claude Code
118
+
119
+ Add to `.mcp.json` in your project root (or `~/.claude/.mcp.json` for all projects):
120
+
121
+ ```json
122
+ {
123
+ "mcpServers": {
124
+ "bank": {
125
+ "command": "npx",
126
+ "args": ["@bank-mcp/server"]
127
+ }
128
+ }
129
+ }
130
+ ```
131
+
132
+ Or add via the CLI:
133
+
134
+ ```bash
135
+ claude mcp add bank -- npx @bank-mcp/server
136
+ ```
137
+
138
+ ### Claude Desktop
139
+
140
+ Add to your `claude_desktop_config.json`:
141
+
142
+ ```json
143
+ {
144
+ "mcpServers": {
145
+ "bank": {
146
+ "command": "npx",
147
+ "args": ["@bank-mcp/server"]
148
+ }
149
+ }
150
+ }
151
+ ```
152
+
153
+ Config file location:
154
+ - **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
155
+ - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
156
+
157
+ ### Cursor
158
+
159
+ Add to `.cursor/mcp.json` in your project root (or `~/.cursor/mcp.json` globally):
160
+
161
+ ```json
162
+ {
163
+ "mcpServers": {
164
+ "bank": {
165
+ "command": "npx",
166
+ "args": ["@bank-mcp/server"]
167
+ }
168
+ }
169
+ }
170
+ ```
171
+
172
+ ### VS Code (Copilot)
173
+
174
+ Add to `.vscode/mcp.json` in your workspace:
175
+
176
+ ```json
177
+ {
178
+ "servers": {
179
+ "bank": {
180
+ "type": "stdio",
181
+ "command": "npx",
182
+ "args": ["@bank-mcp/server"]
183
+ }
184
+ }
185
+ }
186
+ ```
187
+
188
+ ### Windsurf
189
+
190
+ Add to `~/.codeium/windsurf/mcp_config.json`:
191
+
192
+ ```json
193
+ {
194
+ "mcpServers": {
195
+ "bank": {
196
+ "command": "npx",
197
+ "args": ["@bank-mcp/server"]
198
+ }
199
+ }
200
+ }
201
+ ```
202
+
203
+ ### OpenAI Codex CLI
204
+
205
+ Add to `~/.codex/config.toml` (or `.codex/config.toml` in your project):
206
+
207
+ ```toml
208
+ [mcp_servers.bank]
209
+ command = "npx"
210
+ args = ["@bank-mcp/server"]
211
+ ```
212
+
213
+ Or add via the CLI:
214
+
215
+ ```bash
216
+ codex mcp add bank -- npx @bank-mcp/server
217
+ ```
218
+
219
+ ### Gemini CLI
220
+
221
+ Add to `~/.gemini/settings.json` (or `.gemini/settings.json` in your project):
222
+
223
+ ```json
224
+ {
225
+ "mcpServers": {
226
+ "bank": {
227
+ "command": "npx",
228
+ "args": ["@bank-mcp/server"]
229
+ }
230
+ }
231
+ }
232
+ ```
233
+
234
+ ### Zed
235
+
236
+ Add to your Zed `settings.json`:
237
+
238
+ ```json
239
+ {
240
+ "context_servers": {
241
+ "bank": {
242
+ "command": {
243
+ "path": "npx",
244
+ "args": ["@bank-mcp/server"]
245
+ }
246
+ }
247
+ }
248
+ }
249
+ ```
250
+
251
+ > **Don't see your tool?** bank-mcp uses standard MCP stdio transport. Any client that supports MCP stdio servers can connect using `npx @bank-mcp/server` as the command.
252
+
253
+ ## Available Tools
254
+
255
+ | Tool | Description | Key Parameters |
256
+ |------|-------------|----------------|
257
+ | `list_accounts` | List all bank accounts across connections | `connectionId?` |
258
+ | `list_transactions` | Fetch transactions with filtering | `accountId`, `from?`, `to?`, `minAmount?`, `maxAmount?` |
259
+ | `search_transactions` | Full-text search on descriptions and merchants | `query`, `accountId?`, `from?`, `to?` |
260
+ | `get_balance` | Current and available balances | `accountId`, `connectionId?` |
261
+ | `spending_summary` | Expenses grouped by merchant or category | `accountId`, `from?`, `to?`, `groupBy?` |
262
+
263
+ ### Example Conversations
264
+
265
+ Here's what real interactions look like:
266
+
267
+ **Checking balances:**
268
+ > **You:** What's in my bank accounts?
269
+ >
270
+ > **Claude:** You have 3 accounts across 2 connections:
271
+ > | Account | Balance | Available |
272
+ > |---------|---------|-----------|
273
+ > | ING Checking | €3,241.50 | €3,141.50 |
274
+ > | ING Savings | €12,800.00 | €12,800.00 |
275
+ > | Revolut Main | €891.23 | €891.23 |
276
+
277
+ **Spending analysis:**
278
+ > **You:** Show my spending by category this month
279
+ >
280
+ > **Claude:** Here's your spending breakdown for February 2026:
281
+ > | Category | Amount | Transactions |
282
+ > |----------|--------|-------------|
283
+ > | Groceries | €487.30 | 12 |
284
+ > | Restaurants | €213.50 | 8 |
285
+ > | Transport | €156.00 | 5 |
286
+ > | Subscriptions | €89.97 | 4 |
287
+
288
+ **Searching transactions:**
289
+ > **You:** Find all Amazon purchases over $50 in the last 3 months
290
+ >
291
+ > **Claude:** Found 7 Amazon transactions over $50 since November:
292
+ > - Dec 15: Amazon.com — $129.99 (Electronics)
293
+ > - Dec 3: Amazon.com — $67.50 (Books)
294
+ > - ...
295
+
296
+ ## Architecture
297
+
298
+ <p align="center">
299
+ <img src="architecture.png" alt="bank-mcp architecture diagram" width="700">
300
+ </p>
301
+
302
+ ### File Structure
303
+
304
+ ```
305
+ ~/.bank-mcp/
306
+ config.json # Connections & credentials (permissions: 600)
307
+ keys/ # RSA keys and certificates
308
+
309
+ src/
310
+ providers/
311
+ base.ts # Abstract BankProvider class
312
+ registry.ts # Provider registration
313
+ enable-banking/ # PSD2 via Enable Banking API
314
+ teller/ # US banks via mTLS
315
+ plaid/ # US/CA/EU via Plaid API
316
+ tink/ # EU Open Banking via Tink API
317
+ mock/ # Deterministic fake data
318
+ tools/ # MCP tool implementations
319
+ utils/
320
+ cache.ts # In-memory TTL cache
321
+ http.ts # Fetch with timeout + retry
322
+ ```
323
+
324
+ ### Provider Interface
325
+
326
+ Every provider extends the same abstract class, making it straightforward to add new integrations:
327
+
328
+ ```typescript
329
+ abstract class BankProvider {
330
+ abstract listAccounts(config): Promise<BankAccount[]>;
331
+ abstract listTransactions(config, accountId, filter?): Promise<Transaction[]>;
332
+ abstract getBalance(config, accountId): Promise<Balance[]>;
333
+ abstract getConfigSchema(): ConfigField[];
334
+ }
335
+ ```
336
+
337
+ ## Provider Setup Guides
338
+
339
+ ### Enable Banking (PSD2)
340
+
341
+ **What you need:**
342
+ - [ ] An [Enable Banking](https://enablebanking.com) account with a registered app
343
+ - [ ] Your RSA private key (`.pem` file)
344
+ - [ ] An active session ID from the OAuth consent flow
345
+
346
+ ```bash
347
+ npx @bank-mcp/server init
348
+ # Select: Enable Banking (PSD2)
349
+ # Enter: App ID, key path, session ID
350
+ ```
351
+
352
+ > **Tip:** Sessions expire after 90 days (PSD2 regulation). You'll need to re-authenticate through the consent flow periodically. The server logs a clear message when a session expires.
353
+
354
+ ### Teller (US Banks)
355
+
356
+ **What you need:**
357
+ - [ ] A [Teller](https://teller.io) developer account
358
+ - [ ] Your client certificate and private key (`.zip` download from the Teller dashboard)
359
+ - [ ] An access token from a Teller Connect enrollment
360
+
361
+ ```bash
362
+ # Extract your certificate
363
+ mkdir -p ~/.bank-mcp/keys/teller
364
+ unzip ~/Downloads/teller.zip -d ~/.bank-mcp/keys/teller/
365
+ chmod 600 ~/.bank-mcp/keys/teller/*.pem
366
+
367
+ # Run setup
368
+ npx @bank-mcp/server init
369
+ # Select: Teller (US Banks)
370
+ # Enter: certificate path, key path, access token
371
+ ```
372
+
373
+ > **Tip:** Teller uses mutual TLS (mTLS) — your app authenticates at the TLS layer via client certificate, then individual enrollments authenticate via access token. Free tier supports up to 100 live connections.
374
+
375
+ ### Plaid (US/CA/EU)
376
+
377
+ **What you need:**
378
+ - [ ] A [Plaid](https://plaid.com) developer account (free signup)
379
+ - [ ] Your Client ID and Secret (from the Plaid dashboard)
380
+ - [ ] An access token from a Plaid Link enrollment
381
+
382
+ ```bash
383
+ npx @bank-mcp/server init
384
+ # Select: Plaid (US/CA/EU)
385
+ # Enter: client ID, secret, access token, environment
386
+ ```
387
+
388
+ > **Tip:** Start with the `sandbox` environment (fake data, instant setup). Plaid provides the richest transaction categorization — 104 sub-categories with confidence scores — which makes it ideal for LLM-driven spending analysis.
389
+
390
+ ### Tink (EU Open Banking)
391
+
392
+ **What you need:**
393
+ - [ ] A [Tink](https://tink.com) developer account (free for testing)
394
+ - [ ] An OAuth2 access token (from the Tink Console or your OAuth2 flow)
395
+
396
+ ```bash
397
+ npx @bank-mcp/server init
398
+ # Select: Tink (EU Open Banking)
399
+ # Enter: access token
400
+ ```
401
+
402
+ > **Tip:** Tink covers 3,400+ banks across Europe. Transactions include PFM (Personal Finance Management) categories with merchant enrichment, and amounts use fixed-point decimals — no floating-point rounding surprises.
403
+
404
+ ## Caching
405
+
406
+ All data is cached in-memory (no disk persistence — cache dies with the process):
407
+
408
+ | Data | TTL | Why |
409
+ |------|-----|-----|
410
+ | Account list | 1 hour | Accounts rarely change; minimizes API calls |
411
+ | Transactions | 15 minutes | Balances new transactions vs freshness |
412
+ | Balances | 5 minutes | Most time-sensitive; users expect current data |
413
+
414
+ Cache is per-connection and per-account. Restarting the server clears all caches.
415
+
416
+ ## Multiple Connections
417
+
418
+ Configure as many bank connections as you need — even across different providers:
419
+
420
+ ```json
421
+ {
422
+ "connections": [
423
+ { "id": "ing-main", "provider": "enable-banking", "..." : "..." },
424
+ { "id": "chase-checking", "provider": "plaid", "..." : "..." },
425
+ { "id": "revolut", "provider": "tink", "..." : "..." }
426
+ ]
427
+ }
428
+ ```
429
+
430
+ All tools accept an optional `connectionId` parameter to target a specific connection. When omitted, every connection is queried and results are merged — so "show all my balances" works across banks automatically.
431
+
432
+ ## Security
433
+
434
+ ### Design Principles
435
+
436
+ bank-mcp handles sensitive financial credentials. Its security posture is built on minimizing attack surface:
437
+
438
+ - **Read-only by design** — the `BankProvider` interface exposes only read methods (`listAccounts`, `listTransactions`, `getBalance`). There are no write methods — no transfers, no account modifications, no payment initiation. This is enforced at the type level, not by convention.
439
+ - **No network listener** — bank-mcp runs as a stdio process (stdin/stdout), not an HTTP server. There is no open port, no attack surface from the network.
440
+ - **Minimal dependencies** — only 3 runtime dependencies (`@modelcontextprotocol/sdk`, `jsonwebtoken`, `zod`). Fewer dependencies means fewer supply chain risks.
441
+ - **Open source** — every line is auditable. No obfuscated code, no compiled blobs, no telemetry.
442
+
443
+ ### Credential Storage
444
+
445
+ - Config file at `~/.bank-mcp/config.json` is created with **`600` permissions** (owner read/write only)
446
+ - RSA keys and certificates are stored in `~/.bank-mcp/keys/` with the same restrictive permissions
447
+ - Credentials are **never logged** — the server sanitizes config objects before any debug output
448
+ - No credential caching beyond the process lifetime — when the server stops, credentials exist only on disk
449
+
450
+ ### Data Flow
451
+
452
+ ```
453
+ Your Bank's API ← HTTPS → bank-mcp (local process) ← stdio → MCP Client (local)
454
+ ```
455
+
456
+ - Transaction data flows directly from your bank's API to your local MCP client
457
+ - **Nothing is stored remotely** — no cloud relay, no proxy server, no intermediate storage
458
+ - **No telemetry** — zero analytics, no crash reports, no usage tracking, no phone-home
459
+ - In-memory cache is per-process and dies when the server stops
460
+
461
+ ### What Your MCP Client Sees
462
+
463
+ The MCP client (Claude, Cursor, etc.) receives structured tool results containing:
464
+ - Account names, types, and balances
465
+ - Transaction descriptions, amounts, dates, and categories
466
+ - Spending summaries
467
+
468
+ The LLM processes this in its context window. Be aware that cloud-hosted LLMs send your conversation (including tool results) to their servers. If this is a concern, use a local model or review your provider's data retention policy.
469
+
470
+ ### Recommendations
471
+
472
+ - **Rotate tokens** — if your banking provider supports token rotation, enable it
473
+ - **Use sandbox first** — test your setup with mock data or Plaid sandbox before connecting live accounts
474
+ - **Review permissions** — ensure `~/.bank-mcp/` is not world-readable (`ls -la ~/.bank-mcp/`)
475
+ - **Scope access** — if your provider supports it, request the minimum scopes needed (read-only account and transaction access)
476
+
477
+ ### Reporting Vulnerabilities
478
+
479
+ If you discover a security issue, please email the maintainer directly rather than opening a public issue. See [CONTRIBUTING.md](CONTRIBUTING.md) for contact details.
480
+
481
+ ## Adding a New Provider
482
+
483
+ The pluggable architecture makes it straightforward to add support for additional banking APIs:
484
+
485
+ 1. **Create your provider** at `src/providers/your-provider/index.ts`
486
+ 2. **Extend `BankProvider`** — implement `listAccounts`, `listTransactions`, `getBalance`, and `getConfigSchema`
487
+ 3. **Register it** in `src/providers/registry.ts`
488
+ 4. **Add config fields** for the init wizard (the schema drives the interactive prompts automatically)
489
+
490
+ See [`src/providers/enable-banking/`](src/providers/enable-banking/) as a reference implementation. The mock provider at [`src/providers/mock/`](src/providers/mock/) is also useful for understanding the expected data shapes.
491
+
492
+ ## Troubleshooting
493
+
494
+ **`npx` is running an old version**
495
+
496
+ npx caches packages. Force the latest:
497
+
498
+ ```bash
499
+ npx @bank-mcp/server@latest
500
+ ```
501
+
502
+ **"Permission denied" reading config**
503
+
504
+ The config file should be readable by your user:
505
+
506
+ ```bash
507
+ ls -la ~/.bank-mcp/config.json
508
+ # Should show: -rw------- (600)
509
+ # Fix: chmod 600 ~/.bank-mcp/config.json
510
+ ```
511
+
512
+ **"Session expired" (Enable Banking)**
513
+
514
+ PSD2 sessions expire after 90 days. Re-run the init wizard:
515
+
516
+ ```bash
517
+ npx @bank-mcp/server init
518
+ # Select your existing Enable Banking connection to update the session
519
+ ```
520
+
521
+ **Tools not showing up in your MCP client**
522
+
523
+ 1. Verify the server starts: `npx @bank-mcp/server --mock` (should output MCP protocol on stdout)
524
+ 2. Check your config file path matches your client's expected location
525
+ 3. Restart your MCP client after adding the config
526
+ 4. Check your client's MCP logs for connection errors
527
+
528
+ **"ETLS" or certificate errors (Teller)**
529
+
530
+ Teller requires mTLS. Verify your certificate files:
531
+
532
+ ```bash
533
+ ls -la ~/.bank-mcp/keys/teller/
534
+ # Should contain: certificate.pem, private_key.pem
535
+ # Both should be chmod 600
536
+ ```
537
+
538
+ ## Development
539
+
540
+ ```bash
541
+ git clone https://github.com/elcukro/bank-mcp.git
542
+ cd bank-mcp
543
+ npm install
544
+ npm test # Run tests (vitest)
545
+ npm run build # Compile TypeScript
546
+ npm run dev # Watch mode (recompile on change)
547
+ npm run lint # ESLint
548
+ ```
549
+
550
+ ## Contributing
551
+
552
+ Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
553
+
554
+ If you're adding a new provider, open an issue first to discuss the approach — we want to make sure the integration fits the project's architecture.
555
+
556
+ ## License
557
+
558
+ [MIT](LICENSE) — use it however you want.
559
+
560
+ ---
561
+
562
+ <p align="center">
563
+ Built for the <a href="https://modelcontextprotocol.io">Model Context Protocol</a> ecosystem
564
+ </p>
@@ -0,0 +1,11 @@
1
+ import type { AppConfig, ConnectionConfig } from "./types.js";
2
+ export declare function getConfigPath(): string;
3
+ export declare function loadConfig(): AppConfig;
4
+ export declare function saveConfig(config: AppConfig): void;
5
+ export declare function getConnection(config: AppConfig, connectionId?: string): ConnectionConfig;
6
+ export declare function getAllConnections(config: AppConfig): ConnectionConfig[];
7
+ /**
8
+ * Expand ~ in paths within a config object.
9
+ */
10
+ export declare function expandPaths(config: Record<string, unknown>): Record<string, unknown>;
11
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAW9D,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,UAAU,IAAI,SAAS,CAuBtC;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAMlD;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,SAAS,EACjB,YAAY,CAAC,EAAE,MAAM,GACpB,gBAAgB,CAkBlB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,gBAAgB,EAAE,CAEvE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAWpF"}
package/dist/config.js ADDED
@@ -0,0 +1,79 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, chmodSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { homedir } from "node:os";
4
+ const CONFIG_DIR = resolve(homedir(), ".bank-mcp");
5
+ const CONFIG_PATH = resolve(CONFIG_DIR, "config.json");
6
+ const DEFAULT_CONFIG = {
7
+ version: 1,
8
+ connections: [],
9
+ defaults: { transactionDays: 90, currency: "PLN" },
10
+ };
11
+ export function getConfigPath() {
12
+ return CONFIG_PATH;
13
+ }
14
+ export function loadConfig() {
15
+ // Mock mode: return a synthetic config with mock provider
16
+ if (process.env.BANK_MCP_MOCK === "1") {
17
+ return {
18
+ version: 1,
19
+ connections: [
20
+ {
21
+ id: "mock",
22
+ provider: "mock",
23
+ label: "Mock Bank (Demo)",
24
+ config: {},
25
+ },
26
+ ],
27
+ defaults: { transactionDays: 90, currency: "PLN" },
28
+ };
29
+ }
30
+ try {
31
+ const raw = readFileSync(CONFIG_PATH, "utf-8");
32
+ return JSON.parse(raw);
33
+ }
34
+ catch {
35
+ return { ...DEFAULT_CONFIG, connections: [] };
36
+ }
37
+ }
38
+ export function saveConfig(config) {
39
+ mkdirSync(CONFIG_DIR, { recursive: true });
40
+ const data = JSON.stringify(config, null, 2) + "\n";
41
+ writeFileSync(CONFIG_PATH, data, { mode: 0o600 });
42
+ // Ensure permissions even if file existed
43
+ chmodSync(CONFIG_PATH, 0o600);
44
+ }
45
+ export function getConnection(config, connectionId) {
46
+ if (config.connections.length === 0) {
47
+ throw new Error("No connections configured. Run: npx @bank-mcp/server init");
48
+ }
49
+ if (connectionId) {
50
+ const conn = config.connections.find((c) => c.id === connectionId);
51
+ if (!conn) {
52
+ const ids = config.connections.map((c) => c.id).join(", ");
53
+ throw new Error(`Connection "${connectionId}" not found. Available: ${ids}`);
54
+ }
55
+ return conn;
56
+ }
57
+ // Default to first connection
58
+ return config.connections[0];
59
+ }
60
+ export function getAllConnections(config) {
61
+ return config.connections;
62
+ }
63
+ /**
64
+ * Expand ~ in paths within a config object.
65
+ */
66
+ export function expandPaths(config) {
67
+ const home = homedir();
68
+ const result = {};
69
+ for (const [key, value] of Object.entries(config)) {
70
+ if (typeof value === "string" && value.startsWith("~")) {
71
+ result[key] = value.replace(/^~/, home);
72
+ }
73
+ else {
74
+ result[key] = value;
75
+ }
76
+ }
77
+ return result;
78
+ }
79
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC5E,OAAO,EAAW,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGlC,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AACnD,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEvD,MAAM,cAAc,GAAc;IAChC,OAAO,EAAE,CAAC;IACV,WAAW,EAAE,EAAE;IACf,QAAQ,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;CACnD,CAAC;AAEF,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,0DAA0D;IAC1D,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,GAAG,EAAE,CAAC;QACtC,OAAO;YACL,OAAO,EAAE,CAAC;YACV,WAAW,EAAE;gBACX;oBACE,EAAE,EAAE,MAAM;oBACV,QAAQ,EAAE,MAAM;oBAChB,KAAK,EAAE,kBAAkB;oBACzB,MAAM,EAAE,EAAE;iBACX;aACF;YACD,QAAQ,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;SACnD,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,cAAc,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAChD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAiB;IAC1C,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IACpD,aAAa,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAClD,0CAA0C;IAC1C,SAAS,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,MAAiB,EACjB,YAAqB;IAErB,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC/E,CAAC;IAED,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,YAAY,CAAC,CAAC;QACnE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3D,MAAM,IAAI,KAAK,CACb,eAAe,YAAY,2BAA2B,GAAG,EAAE,CAC5D,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8BAA8B;IAC9B,OAAO,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,OAAO,MAAM,CAAC,WAAW,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,MAA+B;IACzD,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACvD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * bank-mcp — Banking data MCP server
4
+ *
5
+ * Usage:
6
+ * npx @bank-mcp/server Start MCP server (for MCP clients)
7
+ * npx @bank-mcp/server init Interactive setup wizard
8
+ * npx @bank-mcp/server --mock Start with mock data (no config needed)
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=index.d.ts.map