@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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG"}
package/dist/index.js ADDED
@@ -0,0 +1,33 @@
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
+ import { startServer } from "./server.js";
11
+ import { runInit } from "./init.js";
12
+ const args = process.argv.slice(2);
13
+ if (args.includes("init")) {
14
+ runInit().catch((err) => {
15
+ console.error("Init failed:", err);
16
+ process.exit(1);
17
+ });
18
+ }
19
+ else if (args.includes("--mock")) {
20
+ // Force mock provider: override config to use mock connection
21
+ process.env.BANK_MCP_MOCK = "1";
22
+ startServer().catch((err) => {
23
+ console.error("Server failed:", err);
24
+ process.exit(1);
25
+ });
26
+ }
27
+ else {
28
+ startServer().catch((err) => {
29
+ console.error("Server failed:", err);
30
+ process.exit(1);
31
+ });
32
+ }
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;IAC1B,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACtB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;KAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IACnC,8DAA8D;IAC9D,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,GAAG,CAAC;IAChC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QAC1B,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;KAAM,CAAC;IACN,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QAC1B,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
package/dist/init.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Interactive setup wizard — walks the user through configuring a
3
+ * bank connection. Uses plain readline (no heavy dependencies).
4
+ */
5
+ export declare function runInit(): Promise<void>;
6
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,wBAAsB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAkG7C"}
package/dist/init.js ADDED
@@ -0,0 +1,96 @@
1
+ import { createInterface } from "node:readline/promises";
2
+ import { stdin, stdout } from "node:process";
3
+ import { loadConfig, saveConfig, getConfigPath } from "./config.js";
4
+ import { listProviders } from "./providers/registry.js";
5
+ /**
6
+ * Interactive setup wizard — walks the user through configuring a
7
+ * bank connection. Uses plain readline (no heavy dependencies).
8
+ */
9
+ export async function runInit() {
10
+ const rl = createInterface({ input: stdin, output: stdout });
11
+ try {
12
+ console.log("\n bank-mcp — Banking data for your AI assistant\n");
13
+ // 1. Select provider
14
+ const providers = listProviders();
15
+ console.log(" Available providers:");
16
+ providers.forEach((p, i) => {
17
+ console.log(` ${i + 1}. ${p.displayName}`);
18
+ });
19
+ const providerIdx = parseInt(await rl.question("\n? Select provider (number): "), 10) - 1;
20
+ const provider = providers[providerIdx];
21
+ if (!provider) {
22
+ console.error(" Invalid selection.");
23
+ return;
24
+ }
25
+ // 2. Collect config fields
26
+ const schema = provider.getConfigSchema();
27
+ const config = {};
28
+ for (const field of schema) {
29
+ const label = field.required ? field.label : `${field.label} (optional)`;
30
+ const defaultHint = field.default ? ` [${field.default}]` : "";
31
+ const answer = await rl.question(`? ${label}${defaultHint}: `);
32
+ config[field.name] = answer || field.default || "";
33
+ }
34
+ // 3. Connection label
35
+ const label = await rl.question("? Connection label (e.g. ING Bank - Main): ");
36
+ // 4. Connection ID (slug from label)
37
+ const id = (label || provider.name)
38
+ .toLowerCase()
39
+ .replace(/[^a-z0-9]+/g, "-")
40
+ .replace(/^-|-$/g, "");
41
+ // 5. Validate by fetching accounts
42
+ console.log("\n Validating connection...");
43
+ try {
44
+ provider.validateConfig(config);
45
+ const accounts = await provider.listAccounts(config);
46
+ if (accounts.length === 0) {
47
+ console.log(" Warning: No accounts found. Config saved anyway.\n");
48
+ }
49
+ else {
50
+ console.log(` Found ${accounts.length} account(s):`);
51
+ for (const acc of accounts) {
52
+ console.log(` - ${acc.iban} (${acc.name}, ${acc.currency})`);
53
+ }
54
+ // Store fetched accounts in config for faster subsequent access
55
+ config.accounts = accounts.map((a) => ({
56
+ uid: a.uid,
57
+ iban: a.iban,
58
+ name: a.name,
59
+ currency: a.currency,
60
+ }));
61
+ }
62
+ }
63
+ catch (err) {
64
+ const msg = err instanceof Error ? err.message : String(err);
65
+ console.error(` Validation failed: ${msg}`);
66
+ const proceed = await rl.question(" Save anyway? (y/N): ");
67
+ if (proceed.toLowerCase() !== "y")
68
+ return;
69
+ }
70
+ // 6. Save config
71
+ const appConfig = loadConfig();
72
+ const connection = {
73
+ id,
74
+ provider: provider.name,
75
+ label: label || provider.displayName,
76
+ config,
77
+ };
78
+ // Replace if same ID exists, otherwise append
79
+ const existing = appConfig.connections.findIndex((c) => c.id === id);
80
+ if (existing >= 0) {
81
+ appConfig.connections[existing] = connection;
82
+ }
83
+ else {
84
+ appConfig.connections.push(connection);
85
+ }
86
+ saveConfig(appConfig);
87
+ console.log(`\n Config saved to ${getConfigPath()}`);
88
+ console.log(`\n Add to your MCP client config (.mcp.json):`);
89
+ console.log(` { "mcpServers": { "bank": { "command": "npx", "args": ["@bank-mcp/server"] } } }`);
90
+ console.log();
91
+ }
92
+ finally {
93
+ rl.close();
94
+ }
95
+ }
96
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,aAAa,EAAe,MAAM,yBAAyB,CAAC;AAGrE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAE7D,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;QAEnE,qBAAqB;QACrB,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QACtC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACzB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,MAAM,WAAW,GACf,QAAQ,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;QACxE,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;YACtC,OAAO;QACT,CAAC;QAED,2BAA2B;QAC3B,MAAM,MAAM,GAAG,QAAQ,CAAC,eAAe,EAAE,CAAC;QAC1C,MAAM,MAAM,GAA4B,EAAE,CAAC;QAE3C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,aAAa,CAAC;YACzE,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,KAAK,GAAG,WAAW,IAAI,CAAC,CAAC;YAC/D,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;QACrD,CAAC;QAED,sBAAsB;QACtB,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC,CAAC;QAE/E,qCAAqC;QACrC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC;aAChC,WAAW,EAAE;aACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;aAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAEzB,mCAAmC;QACnC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC5C,IAAI,CAAC;YACH,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YAChC,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAErD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;YACtE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,WAAW,QAAQ,CAAC,MAAM,cAAc,CAAC,CAAC;gBACtD,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;oBAC3B,OAAO,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC;gBAClE,CAAC;gBAED,gEAAgE;gBAChE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACrC,GAAG,EAAE,CAAC,CAAC,GAAG;oBACV,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;iBACrB,CAAC,CAAC,CAAC;YACN,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;YAC7C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC;YAC5D,IAAI,OAAO,CAAC,WAAW,EAAE,KAAK,GAAG;gBAAE,OAAO;QAC5C,CAAC;QAED,iBAAiB;QACjB,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAqB;YACnC,EAAE;YACF,QAAQ,EAAE,QAAQ,CAAC,IAAI;YACvB,KAAK,EAAE,KAAK,IAAI,QAAQ,CAAC,WAAW;YACpC,MAAM;SACP,CAAC;QAEF,8CAA8C;QAC9C,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACrE,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;YAClB,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,UAAU,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACzC,CAAC;QAED,UAAU,CAAC,SAAS,CAAC,CAAC;QAEtB,OAAO,CAAC,GAAG,CAAC,uBAAuB,aAAa,EAAE,EAAE,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CACT,oFAAoF,CACrF,CAAC;QACF,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { BankAccount, Transaction, Balance, TransactionFilter, ConfigField } from "../types.js";
2
+ /**
3
+ * Abstract base for all bank providers.
4
+ *
5
+ * Each provider translates a specific banking API into the normalized
6
+ * BankAccount / Transaction / Balance types.
7
+ */
8
+ export declare abstract class BankProvider {
9
+ abstract readonly name: string;
10
+ abstract readonly displayName: string;
11
+ /** Throw if required config fields are missing or invalid. */
12
+ abstract validateConfig(config: Record<string, unknown>): void;
13
+ /** Fetch all accounts accessible via this connection. */
14
+ abstract listAccounts(config: Record<string, unknown>): Promise<BankAccount[]>;
15
+ /** Fetch transactions with optional filtering. */
16
+ abstract listTransactions(config: Record<string, unknown>, accountId: string, filter?: TransactionFilter): Promise<Transaction[]>;
17
+ /** Fetch current balance(s) for an account. */
18
+ abstract getBalance(config: Record<string, unknown>, accountId: string): Promise<Balance[]>;
19
+ /** Describe config fields for the init wizard. */
20
+ abstract getConfigSchema(): ConfigField[];
21
+ }
22
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/providers/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,OAAO,EACP,iBAAiB,EACjB,WAAW,EACZ,MAAM,aAAa,CAAC;AAErB;;;;;GAKG;AACH,8BAAsB,YAAY;IAChC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAEtC,8DAA8D;IAC9D,QAAQ,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAE9D,yDAAyD;IACzD,QAAQ,CAAC,YAAY,CACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,WAAW,EAAE,CAAC;IAEzB,kDAAkD;IAClD,QAAQ,CAAC,gBAAgB,CACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,iBAAiB,GACzB,OAAO,CAAC,WAAW,EAAE,CAAC;IAEzB,+CAA+C;IAC/C,QAAQ,CAAC,UAAU,CACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,EAAE,CAAC;IAErB,kDAAkD;IAClD,QAAQ,CAAC,eAAe,IAAI,WAAW,EAAE;CAC1C"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Abstract base for all bank providers.
3
+ *
4
+ * Each provider translates a specific banking API into the normalized
5
+ * BankAccount / Transaction / Balance types.
6
+ */
7
+ export class BankProvider {
8
+ }
9
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/providers/base.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,MAAM,OAAgB,YAAY;CA2BjC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Generate a JWT for Enable Banking API authentication.
3
+ *
4
+ * RS256 with kid=appId in the header. Tokens live 1 hour.
5
+ * A fresh token is generated per request — no caching needed
6
+ * since generation is sub-millisecond.
7
+ */
8
+ export declare function generateJwt(appId: string, privateKeyPath: string): string;
9
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/providers/enable-banking/auth.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAoBzE"}
@@ -0,0 +1,30 @@
1
+ import jwt from "jsonwebtoken";
2
+ import { readFileSync } from "node:fs";
3
+ import { resolve } from "node:path";
4
+ /**
5
+ * Generate a JWT for Enable Banking API authentication.
6
+ *
7
+ * RS256 with kid=appId in the header. Tokens live 1 hour.
8
+ * A fresh token is generated per request — no caching needed
9
+ * since generation is sub-millisecond.
10
+ */
11
+ export function generateJwt(appId, privateKeyPath) {
12
+ const expandedPath = privateKeyPath.replace(/^~/, process.env.HOME || "");
13
+ const privateKey = readFileSync(resolve(expandedPath), "utf-8");
14
+ const now = Math.floor(Date.now() / 1000);
15
+ const payload = {
16
+ iss: "enablebanking.com",
17
+ aud: "api.enablebanking.com",
18
+ iat: now,
19
+ exp: now + 3600,
20
+ };
21
+ return jwt.sign(payload, privateKey, {
22
+ algorithm: "RS256",
23
+ header: {
24
+ alg: "RS256",
25
+ typ: "JWT",
26
+ kid: appId,
27
+ },
28
+ });
29
+ }
30
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/providers/enable-banking/auth.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,cAAc,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,cAAsB;IAC/D,MAAM,YAAY,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC1E,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC;IAEhE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG;QACd,GAAG,EAAE,mBAAmB;QACxB,GAAG,EAAE,uBAAuB;QAC5B,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG,GAAG,IAAI;KAChB,CAAC;IAEF,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE;QACnC,SAAS,EAAE,OAAO;QAClB,MAAM,EAAE;YACN,GAAG,EAAE,OAAO;YACZ,GAAG,EAAE,KAAK;YACV,GAAG,EAAE,KAAK;SACX;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { BankProvider } from "../base.js";
2
+ import type { BankAccount, Transaction, Balance, TransactionFilter, ConfigField } from "../../types.js";
3
+ export declare class EnableBankingProvider extends BankProvider {
4
+ readonly name = "enable-banking";
5
+ readonly displayName = "Enable Banking (PSD2)";
6
+ validateConfig(config: Record<string, unknown>): void;
7
+ getConfigSchema(): ConfigField[];
8
+ listAccounts(config: Record<string, unknown>): Promise<BankAccount[]>;
9
+ listTransactions(config: Record<string, unknown>, accountId: string, filter?: TransactionFilter): Promise<Transaction[]>;
10
+ getBalance(config: Record<string, unknown>, accountId: string): Promise<Balance[]>;
11
+ }
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/enable-banking/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,OAAO,EACP,iBAAiB,EACjB,WAAW,EACZ,MAAM,gBAAgB,CAAC;AA8BxB,qBAAa,qBAAsB,SAAQ,YAAY;IACrD,QAAQ,CAAC,IAAI,oBAAoB;IACjC,QAAQ,CAAC,WAAW,2BAA2B;IAE/C,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIrD,eAAe,IAAI,WAAW,EAAE;IAuB1B,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA6BrE,gBAAgB,CACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,iBAAiB,GACzB,OAAO,CAAC,WAAW,EAAE,CAAC;IAwDnB,UAAU,CACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,EAAE,CAAC;CAqBtB"}
@@ -0,0 +1,171 @@
1
+ import { BankProvider } from "../base.js";
2
+ import { generateJwt } from "./auth.js";
3
+ import { httpFetch } from "../../utils/http.js";
4
+ const API_BASE = "https://api.enablebanking.com";
5
+ function parseConfig(raw) {
6
+ const appId = raw.appId;
7
+ const privateKeyPath = raw.privateKeyPath;
8
+ const sessionId = raw.sessionId;
9
+ if (!appId || !privateKeyPath || !sessionId) {
10
+ throw new Error("Enable Banking config requires: appId, privateKeyPath, sessionId");
11
+ }
12
+ return {
13
+ appId,
14
+ privateKeyPath,
15
+ sessionId,
16
+ validUntil: raw.validUntil,
17
+ accounts: raw.accounts,
18
+ };
19
+ }
20
+ export class EnableBankingProvider extends BankProvider {
21
+ name = "enable-banking";
22
+ displayName = "Enable Banking (PSD2)";
23
+ validateConfig(config) {
24
+ parseConfig(config);
25
+ }
26
+ getConfigSchema() {
27
+ return [
28
+ {
29
+ name: "appId",
30
+ label: "App ID",
31
+ type: "string",
32
+ required: true,
33
+ },
34
+ {
35
+ name: "privateKeyPath",
36
+ label: "Path to RSA private key (.pem)",
37
+ type: "path",
38
+ required: true,
39
+ },
40
+ {
41
+ name: "sessionId",
42
+ label: "Session ID",
43
+ type: "string",
44
+ required: true,
45
+ },
46
+ ];
47
+ }
48
+ async listAccounts(config) {
49
+ const eb = parseConfig(config);
50
+ // If accounts are cached in config, return those
51
+ if (eb.accounts?.length) {
52
+ return eb.accounts.map((a) => ({
53
+ uid: a.uid,
54
+ iban: a.iban,
55
+ name: a.name,
56
+ currency: a.currency,
57
+ connectionId: "", // filled by caller
58
+ }));
59
+ }
60
+ // Otherwise fetch from API
61
+ const token = generateJwt(eb.appId, eb.privateKeyPath);
62
+ const data = (await httpFetch(`${API_BASE}/sessions/${eb.sessionId}`, {
63
+ headers: authHeaders(token),
64
+ }));
65
+ return data.accounts.map((a) => ({
66
+ uid: a.uid,
67
+ iban: a.iban,
68
+ name: a.account_name || a.iban,
69
+ currency: a.currency || "EUR",
70
+ connectionId: "",
71
+ }));
72
+ }
73
+ async listTransactions(config, accountId, filter) {
74
+ const eb = parseConfig(config);
75
+ const token = generateJwt(eb.appId, eb.privateKeyPath);
76
+ const headers = authHeaders(token);
77
+ const allTx = [];
78
+ let continuationKey;
79
+ // Pagination loop — Enable Banking uses continuation_key cursor
80
+ do {
81
+ const params = new URLSearchParams();
82
+ if (filter?.dateFrom)
83
+ params.set("date_from", filter.dateFrom);
84
+ if (filter?.dateTo)
85
+ params.set("date_to", filter.dateTo);
86
+ if (continuationKey)
87
+ params.set("continuation_key", continuationKey);
88
+ const qs = params.toString();
89
+ const url = `${API_BASE}/accounts/${accountId}/transactions${qs ? `?${qs}` : ""}`;
90
+ const data = (await httpFetch(url, {
91
+ headers,
92
+ timeoutMs: 60000,
93
+ }));
94
+ for (const raw of data.transactions) {
95
+ allTx.push(normalizeTransaction(raw, accountId));
96
+ }
97
+ continuationKey = data.continuation_key;
98
+ } while (continuationKey);
99
+ // Apply local filters the API doesn't support natively
100
+ let filtered = allTx;
101
+ if (filter?.amountMin !== undefined) {
102
+ filtered = filtered.filter((t) => Math.abs(t.amount) >= filter.amountMin);
103
+ }
104
+ if (filter?.amountMax !== undefined) {
105
+ filtered = filtered.filter((t) => Math.abs(t.amount) <= filter.amountMax);
106
+ }
107
+ if (filter?.type) {
108
+ filtered = filtered.filter((t) => t.type === filter.type);
109
+ }
110
+ if (filter?.limit) {
111
+ filtered = filtered.slice(0, filter.limit);
112
+ }
113
+ return filtered;
114
+ }
115
+ async getBalance(config, accountId) {
116
+ const eb = parseConfig(config);
117
+ const token = generateJwt(eb.appId, eb.privateKeyPath);
118
+ const data = (await httpFetch(`${API_BASE}/accounts/${accountId}/balances`, { headers: authHeaders(token) }));
119
+ return data.balances.map((b) => ({
120
+ accountId,
121
+ amount: parseFloat(b.balance_amount.amount),
122
+ currency: b.balance_amount.currency,
123
+ type: b.balance_type,
124
+ }));
125
+ }
126
+ }
127
+ // --- Internal helpers ---
128
+ function authHeaders(token) {
129
+ return {
130
+ Authorization: `Bearer ${token}`,
131
+ "Content-Type": "application/json",
132
+ Accept: "application/json",
133
+ };
134
+ }
135
+ /**
136
+ * Normalize an Enable Banking raw transaction into our standard format.
137
+ *
138
+ * Direction logic:
139
+ * DBIT → expense: merchant = creditor.name (who you paid)
140
+ * CRDT → income: merchant = debtor.name (who paid you)
141
+ *
142
+ * Description priority: counterpart name > remittance text > "Unknown"
143
+ */
144
+ function normalizeTransaction(raw, accountId) {
145
+ const amount = parseFloat(raw.transaction_amount.amount);
146
+ const cdi = raw.credit_debit_indicator || "";
147
+ const isDebit = cdi === "DBIT" || amount < 0;
148
+ // Build remittance text (defensive: can be array or string)
149
+ const remittance = Array.isArray(raw.remittance_information)
150
+ ? raw.remittance_information.join(" ")
151
+ : String(raw.remittance_information || "");
152
+ // Counterpart name depends on direction
153
+ const merchantName = isDebit ? raw.creditor?.name : raw.debtor?.name;
154
+ const description = merchantName || remittance || "Unknown transaction";
155
+ // Unique ID: entry_reference preferred, fallback to composed ID
156
+ const id = raw.entry_reference ||
157
+ `eb:${accountId}:${raw.transaction_id || Date.now()}`;
158
+ return {
159
+ id,
160
+ accountId,
161
+ date: raw.booking_date || new Date().toISOString().slice(0, 10),
162
+ amount: isDebit ? -Math.abs(amount) : Math.abs(amount),
163
+ currency: raw.transaction_amount.currency,
164
+ description,
165
+ merchantName: merchantName || undefined,
166
+ type: isDebit ? "debit" : "credit",
167
+ reference: remittance || undefined,
168
+ rawData: raw,
169
+ };
170
+ }
171
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/enable-banking/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { BankProvider } from "../base.js";
2
+ import type { BankAccount, Transaction, Balance, TransactionFilter, ConfigField } from "../../types.js";
3
+ /**
4
+ * Mock provider with deterministic fake data.
5
+ * Used for demos, testing, and development without real bank credentials.
6
+ *
7
+ * Run with: npx @bank-mcp/server --mock
8
+ */
9
+ export declare class MockProvider extends BankProvider {
10
+ readonly name = "mock";
11
+ readonly displayName = "Mock Bank (Demo Data)";
12
+ validateConfig(): void;
13
+ getConfigSchema(): ConfigField[];
14
+ listAccounts(): Promise<BankAccount[]>;
15
+ listTransactions(_config: Record<string, unknown>, accountId: string, filter?: TransactionFilter): Promise<Transaction[]>;
16
+ getBalance(_config: Record<string, unknown>, accountId: string): Promise<Balance[]>;
17
+ }
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/mock/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,OAAO,EACP,iBAAiB,EACjB,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAExB;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,YAAY;IAC5C,QAAQ,CAAC,IAAI,UAAU;IACvB,QAAQ,CAAC,WAAW,2BAA2B;IAE/C,cAAc,IAAI,IAAI;IAItB,eAAe,IAAI,WAAW,EAAE;IAI1B,YAAY,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAmBtC,gBAAgB,CACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,iBAAiB,GACzB,OAAO,CAAC,WAAW,EAAE,CAAC;IAyBnB,UAAU,CACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,EAAE,CAAC;CAqBtB"}
@@ -0,0 +1,151 @@
1
+ import { BankProvider } from "../base.js";
2
+ /**
3
+ * Mock provider with deterministic fake data.
4
+ * Used for demos, testing, and development without real bank credentials.
5
+ *
6
+ * Run with: npx @bank-mcp/server --mock
7
+ */
8
+ export class MockProvider extends BankProvider {
9
+ name = "mock";
10
+ displayName = "Mock Bank (Demo Data)";
11
+ validateConfig() {
12
+ // No config needed
13
+ }
14
+ getConfigSchema() {
15
+ return [];
16
+ }
17
+ async listAccounts() {
18
+ return [
19
+ {
20
+ uid: "mock-checking-001",
21
+ iban: "PL61109010140000071219812874",
22
+ name: "Konto Direct",
23
+ currency: "PLN",
24
+ connectionId: "",
25
+ },
26
+ {
27
+ uid: "mock-savings-001",
28
+ iban: "PL72109010140000071219812999",
29
+ name: "Konto Oszczednosciowe",
30
+ currency: "PLN",
31
+ connectionId: "",
32
+ },
33
+ ];
34
+ }
35
+ async listTransactions(_config, accountId, filter) {
36
+ let txs = generateMockTransactions(accountId);
37
+ if (filter?.dateFrom) {
38
+ txs = txs.filter((t) => t.date >= filter.dateFrom);
39
+ }
40
+ if (filter?.dateTo) {
41
+ txs = txs.filter((t) => t.date <= filter.dateTo);
42
+ }
43
+ if (filter?.amountMin !== undefined) {
44
+ txs = txs.filter((t) => Math.abs(t.amount) >= filter.amountMin);
45
+ }
46
+ if (filter?.amountMax !== undefined) {
47
+ txs = txs.filter((t) => Math.abs(t.amount) <= filter.amountMax);
48
+ }
49
+ if (filter?.type) {
50
+ txs = txs.filter((t) => t.type === filter.type);
51
+ }
52
+ if (filter?.limit) {
53
+ txs = txs.slice(0, filter.limit);
54
+ }
55
+ return txs;
56
+ }
57
+ async getBalance(_config, accountId) {
58
+ const amounts = {
59
+ "mock-checking-001": 12450.67,
60
+ "mock-savings-001": 45000.0,
61
+ };
62
+ return [
63
+ {
64
+ accountId,
65
+ amount: amounts[accountId] || 1000.0,
66
+ currency: "PLN",
67
+ type: "closingBooked",
68
+ },
69
+ {
70
+ accountId,
71
+ amount: (amounts[accountId] || 1000.0) + 250.0,
72
+ currency: "PLN",
73
+ type: "expected",
74
+ },
75
+ ];
76
+ }
77
+ }
78
+ function generateMockTransactions(accountId) {
79
+ const today = new Date();
80
+ const txs = [];
81
+ const merchants = [
82
+ { name: "Biedronka", min: 30, max: 180 },
83
+ { name: "Lidl", min: 40, max: 200 },
84
+ { name: "Żabka", min: 5, max: 45 },
85
+ { name: "Orlen", min: 150, max: 350 },
86
+ { name: "Allegro", min: 20, max: 500 },
87
+ { name: "Netflix", min: 43, max: 43 },
88
+ { name: "Spotify", min: 29.99, max: 29.99 },
89
+ { name: "PZU Ubezpieczenie", min: 180, max: 180 },
90
+ { name: "Orange Polska", min: 79, max: 79 },
91
+ { name: "Inea Internet", min: 69, max: 69 },
92
+ ];
93
+ const incomes = [
94
+ { name: "TechCorp Sp. z o.o.", amount: 12500, desc: "Wynagrodzenie" },
95
+ { name: "Freelance Client", amount: 3500, desc: "Faktura 2026/02" },
96
+ ];
97
+ // Generate 90 days of transactions (deterministic via simple seed)
98
+ for (let day = 0; day < 90; day++) {
99
+ const date = new Date(today);
100
+ date.setDate(date.getDate() - day);
101
+ const dateStr = date.toISOString().slice(0, 10);
102
+ // 1-3 expenses per day
103
+ const txCount = (day % 3) + 1;
104
+ for (let i = 0; i < txCount; i++) {
105
+ const merchant = merchants[(day * 3 + i) % merchants.length];
106
+ const amount = merchant.min === merchant.max
107
+ ? merchant.min
108
+ : merchant.min +
109
+ ((day * 7 + i * 13) % (merchant.max - merchant.min));
110
+ txs.push({
111
+ id: `mock-tx-${accountId}-${day}-${i}`,
112
+ accountId,
113
+ date: dateStr,
114
+ amount: -Math.round(amount * 100) / 100,
115
+ currency: "PLN",
116
+ description: merchant.name,
117
+ merchantName: merchant.name,
118
+ type: "debit",
119
+ });
120
+ }
121
+ // Salary on the 10th, freelance on the 25th
122
+ if (date.getDate() === 10) {
123
+ txs.push({
124
+ id: `mock-tx-${accountId}-salary-${dateStr}`,
125
+ accountId,
126
+ date: dateStr,
127
+ amount: incomes[0].amount,
128
+ currency: "PLN",
129
+ description: incomes[0].desc,
130
+ merchantName: incomes[0].name,
131
+ type: "credit",
132
+ });
133
+ }
134
+ if (date.getDate() === 25) {
135
+ txs.push({
136
+ id: `mock-tx-${accountId}-freelance-${dateStr}`,
137
+ accountId,
138
+ date: dateStr,
139
+ amount: incomes[1].amount,
140
+ currency: "PLN",
141
+ description: incomes[1].desc,
142
+ merchantName: incomes[1].name,
143
+ type: "credit",
144
+ });
145
+ }
146
+ }
147
+ // Sort by date descending
148
+ txs.sort((a, b) => b.date.localeCompare(a.date));
149
+ return txs;
150
+ }
151
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/mock/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { BankProvider } from "../base.js";
2
+ import type { BankAccount, Transaction, Balance, TransactionFilter, ConfigField } from "../../types.js";
3
+ export declare class PlaidProvider extends BankProvider {
4
+ readonly name = "plaid";
5
+ readonly displayName = "Plaid (US/CA/EU)";
6
+ validateConfig(config: Record<string, unknown>): void;
7
+ getConfigSchema(): ConfigField[];
8
+ listAccounts(config: Record<string, unknown>): Promise<BankAccount[]>;
9
+ listTransactions(config: Record<string, unknown>, accountId: string, filter?: TransactionFilter): Promise<Transaction[]>;
10
+ getBalance(config: Record<string, unknown>, accountId: string): Promise<Balance[]>;
11
+ }
12
+ //# sourceMappingURL=index.d.ts.map