@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,65 @@
1
+ import { z } from "zod";
2
+ import { listTransactions } from "./list-transactions.js";
3
+ export const spendingSummarySchema = z.object({
4
+ connectionId: z.string().optional(),
5
+ dateFrom: z.string().optional(),
6
+ dateTo: z.string().optional(),
7
+ groupBy: z
8
+ .enum(["merchant", "category"])
9
+ .optional()
10
+ .describe('Group expenses by "merchant" (default) or "category".'),
11
+ limit: z
12
+ .number()
13
+ .optional()
14
+ .describe("Max groups to return (default 20, sorted by total spent)."),
15
+ });
16
+ export async function spendingSummary(args) {
17
+ const transactions = await listTransactions({
18
+ connectionId: args.connectionId,
19
+ dateFrom: args.dateFrom,
20
+ dateTo: args.dateTo,
21
+ type: "debit",
22
+ });
23
+ const groupBy = args.groupBy || "merchant";
24
+ const limit = args.limit || 20;
25
+ // Group expenses
26
+ const groups = new Map();
27
+ for (const tx of transactions) {
28
+ const key = groupBy === "merchant"
29
+ ? tx.merchantName || tx.description || "Unknown"
30
+ : tx.category || "uncategorized";
31
+ const existing = groups.get(key) || { total: 0, count: 0, currency: tx.currency };
32
+ existing.total += Math.abs(tx.amount);
33
+ existing.count += 1;
34
+ groups.set(key, existing);
35
+ }
36
+ // Sort by total spent descending
37
+ const sorted = [...groups.entries()]
38
+ .map(([name, data]) => ({
39
+ name,
40
+ totalSpent: Math.round(data.total * 100) / 100,
41
+ transactionCount: data.count,
42
+ currency: data.currency,
43
+ }))
44
+ .sort((a, b) => b.totalSpent - a.totalSpent)
45
+ .slice(0, limit);
46
+ const totalSpent = Math.round(transactions.reduce((sum, t) => sum + Math.abs(t.amount), 0) * 100) / 100;
47
+ const currency = transactions[0]?.currency || "PLN";
48
+ const dateFrom = args.dateFrom || defaultDateFrom(90);
49
+ const dateTo = args.dateTo || today();
50
+ return {
51
+ groups: sorted,
52
+ totalSpent,
53
+ currency,
54
+ period: `${dateFrom} to ${dateTo}`,
55
+ };
56
+ }
57
+ function defaultDateFrom(days) {
58
+ const d = new Date();
59
+ d.setDate(d.getDate() - days);
60
+ return d.toISOString().slice(0, 10);
61
+ }
62
+ function today() {
63
+ return new Date().toISOString().slice(0, 10);
64
+ }
65
+ //# sourceMappingURL=spending-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spending-summary.js","sourceRoot":"","sources":["../../src/tools/spending-summary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Normalized banking types — all providers map to these.
3
+ */
4
+ export interface BankAccount {
5
+ uid: string;
6
+ iban: string;
7
+ name: string;
8
+ currency: string;
9
+ connectionId: string;
10
+ }
11
+ export interface Transaction {
12
+ id: string;
13
+ accountId: string;
14
+ date: string;
15
+ amount: number;
16
+ currency: string;
17
+ description: string;
18
+ merchantName?: string;
19
+ category?: string;
20
+ type: "debit" | "credit";
21
+ reference?: string;
22
+ rawData?: Record<string, unknown>;
23
+ }
24
+ export interface Balance {
25
+ accountId: string;
26
+ amount: number;
27
+ currency: string;
28
+ type: string;
29
+ }
30
+ export interface TransactionFilter {
31
+ dateFrom?: string;
32
+ dateTo?: string;
33
+ amountMin?: number;
34
+ amountMax?: number;
35
+ type?: "debit" | "credit";
36
+ limit?: number;
37
+ }
38
+ export interface ConfigField {
39
+ name: string;
40
+ label: string;
41
+ type: "string" | "path" | "select";
42
+ required: boolean;
43
+ secret?: boolean;
44
+ options?: string[];
45
+ default?: string;
46
+ }
47
+ export interface ConnectionConfig {
48
+ id: string;
49
+ provider: string;
50
+ label: string;
51
+ config: Record<string, unknown>;
52
+ }
53
+ export interface AppConfig {
54
+ version: number;
55
+ connections: ConnectionConfig[];
56
+ defaults: {
57
+ transactionDays: number;
58
+ currency: string;
59
+ };
60
+ }
61
+ export declare const EXPENSE_CATEGORIES: readonly ["housing", "transportation", "food", "utilities", "insurance", "healthcare", "entertainment", "other"];
62
+ export declare const INCOME_CATEGORIES: readonly ["salary", "freelance", "investments", "rental", "other"];
63
+ export type ExpenseCategory = (typeof EXPENSE_CATEGORIES)[number];
64
+ export type IncomeCategory = (typeof INCOME_CATEGORIES)[number];
65
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,QAAQ,EAAE;QACR,eAAe,EAAE,MAAM,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,eAAO,MAAM,kBAAkB,kHASrB,CAAC;AAEX,eAAO,MAAM,iBAAiB,oEAMpB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAClE,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Normalized banking types — all providers map to these.
3
+ */
4
+ export const EXPENSE_CATEGORIES = [
5
+ "housing",
6
+ "transportation",
7
+ "food",
8
+ "utilities",
9
+ "insurance",
10
+ "healthcare",
11
+ "entertainment",
12
+ "other",
13
+ ];
14
+ export const INCOME_CATEGORIES = [
15
+ "salary",
16
+ "freelance",
17
+ "investments",
18
+ "rental",
19
+ "other",
20
+ ];
21
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkEH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,SAAS;IACT,gBAAgB;IAChB,MAAM;IACN,WAAW;IACX,WAAW;IACX,YAAY;IACZ,eAAe;IACf,OAAO;CACC,CAAC;AAEX,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,QAAQ;IACR,WAAW;IACX,aAAa;IACb,QAAQ;IACR,OAAO;CACC,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Simple in-memory TTL cache.
3
+ *
4
+ * Dies with the process — no disk persistence.
5
+ * TTLs: balances 5min, transactions 15min, accounts 1hr.
6
+ */
7
+ export declare class Cache {
8
+ private store;
9
+ get<T>(key: string): T | undefined;
10
+ set<T>(key: string, value: T, ttlMs: number): void;
11
+ clear(): void;
12
+ }
13
+ export declare const cache: Cache;
14
+ export declare const TTL: {
15
+ readonly ACCOUNTS: number;
16
+ readonly TRANSACTIONS: number;
17
+ readonly BALANCES: number;
18
+ };
19
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAA0C;IAEvD,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAUlC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIlD,KAAK,IAAI,IAAI;CAGd;AAGD,eAAO,MAAM,KAAK,OAAc,CAAC;AAEjC,eAAO,MAAM,GAAG;;;;CAIN,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Simple in-memory TTL cache.
3
+ *
4
+ * Dies with the process — no disk persistence.
5
+ * TTLs: balances 5min, transactions 15min, accounts 1hr.
6
+ */
7
+ export class Cache {
8
+ store = new Map();
9
+ get(key) {
10
+ const entry = this.store.get(key);
11
+ if (!entry)
12
+ return undefined;
13
+ if (Date.now() > entry.expiresAt) {
14
+ this.store.delete(key);
15
+ return undefined;
16
+ }
17
+ return entry.value;
18
+ }
19
+ set(key, value, ttlMs) {
20
+ this.store.set(key, { value, expiresAt: Date.now() + ttlMs });
21
+ }
22
+ clear() {
23
+ this.store.clear();
24
+ }
25
+ }
26
+ // Singleton + TTL constants
27
+ export const cache = new Cache();
28
+ export const TTL = {
29
+ ACCOUNTS: 60 * 60 * 1000, // 1 hour
30
+ TRANSACTIONS: 15 * 60 * 1000, // 15 minutes
31
+ BALANCES: 5 * 60 * 1000, // 5 minutes
32
+ };
33
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,MAAM,OAAO,KAAK;IACR,KAAK,GAAG,IAAI,GAAG,EAA+B,CAAC;IAEvD,GAAG,CAAI,GAAW;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,KAAK,CAAC,KAAU,CAAC;IAC1B,CAAC;IAED,GAAG,CAAI,GAAW,EAAE,KAAQ,EAAE,KAAa;QACzC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF;AAED,4BAA4B;AAC5B,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;AAEjC,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,SAAS;IACnC,YAAY,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;IAC3C,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,YAAY;CAC7B,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Minimal fetch wrapper with timeout and retry for banking APIs.
3
+ */
4
+ export interface FetchOptions {
5
+ method?: string;
6
+ headers?: Record<string, string>;
7
+ body?: string;
8
+ timeoutMs?: number;
9
+ retries?: number;
10
+ }
11
+ export declare function httpFetch(url: string, opts?: FetchOptions): Promise<unknown>;
12
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/utils/http.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,OAAO,CAAC,CAqClB"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Minimal fetch wrapper with timeout and retry for banking APIs.
3
+ */
4
+ export async function httpFetch(url, opts = {}) {
5
+ const { method = "GET", headers, body, timeoutMs = 30000, retries = 1 } = opts;
6
+ let lastError;
7
+ for (let attempt = 0; attempt < retries; attempt++) {
8
+ const controller = new AbortController();
9
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
10
+ try {
11
+ const res = await fetch(url, {
12
+ method,
13
+ headers,
14
+ body,
15
+ signal: controller.signal,
16
+ });
17
+ clearTimeout(timer);
18
+ if (!res.ok) {
19
+ const text = await res.text().catch(() => "");
20
+ throw new Error(`HTTP ${res.status} ${res.statusText}: ${text.slice(0, 200)}`);
21
+ }
22
+ return await res.json();
23
+ }
24
+ catch (err) {
25
+ clearTimeout(timer);
26
+ lastError = err instanceof Error ? err : new Error(String(err));
27
+ // Don't retry on 4xx (client errors)
28
+ if (lastError.message.includes("HTTP 4"))
29
+ break;
30
+ }
31
+ }
32
+ throw lastError;
33
+ }
34
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/utils/http.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,GAAW,EACX,OAAqB,EAAE;IAEvB,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,GAAG,KAAK,EAAE,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC;IAE/E,IAAI,SAA4B,CAAC;IAEjC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;QACnD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;QAE9D,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAC3B,MAAM;gBACN,OAAO;gBACP,IAAI;gBACJ,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YAEH,YAAY,CAAC,KAAK,CAAC,CAAC;YAEpB,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC9C,MAAM,IAAI,KAAK,CACb,QAAQ,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAC9D,CAAC;YACJ,CAAC;YAED,OAAO,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,SAAS,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAEhE,qCAAqC;YACrC,IAAI,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,MAAM;QAClD,CAAC;IACH,CAAC;IAED,MAAM,SAAU,CAAC;AACnB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ZodObject, ZodRawShape } from "zod";
2
+ /**
3
+ * Minimal Zod → JSON Schema converter for MCP tool inputSchema.
4
+ *
5
+ * Handles the subset we actually use: objects with string, number,
6
+ * enum, and optional fields. No need for a full library.
7
+ */
8
+ export declare function zodToJsonSchema(schema: ZodObject<ZodRawShape>): Record<string, unknown>;
9
+ //# sourceMappingURL=zod-to-json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod-to-json.d.ts","sourceRoot":"","sources":["../../src/utils/zod-to-json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAc,MAAM,KAAK,CAAC;AAE9D;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,CAAC,WAAW,CAAC,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuBzB"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Minimal Zod → JSON Schema converter for MCP tool inputSchema.
3
+ *
4
+ * Handles the subset we actually use: objects with string, number,
5
+ * enum, and optional fields. No need for a full library.
6
+ */
7
+ export function zodToJsonSchema(schema) {
8
+ const shape = schema.shape;
9
+ const properties = {};
10
+ const required = [];
11
+ for (const [key, fieldDef] of Object.entries(shape)) {
12
+ const field = fieldDef;
13
+ const prop = zodFieldToJson(field);
14
+ properties[key] = prop;
15
+ if (!field.isOptional()) {
16
+ required.push(key);
17
+ }
18
+ }
19
+ const result = {
20
+ type: "object",
21
+ properties,
22
+ };
23
+ if (required.length > 0) {
24
+ result.required = required;
25
+ }
26
+ return result;
27
+ }
28
+ function zodFieldToJson(field) {
29
+ const def = field._def;
30
+ // Unwrap optional
31
+ if (def.typeName === "ZodOptional") {
32
+ return zodFieldToJson(def.innerType);
33
+ }
34
+ // Unwrap default
35
+ if (def.typeName === "ZodDefault") {
36
+ return zodFieldToJson(def.innerType);
37
+ }
38
+ const result = {};
39
+ // Extract description
40
+ if (def.description) {
41
+ result.description = def.description;
42
+ }
43
+ switch (def.typeName) {
44
+ case "ZodString":
45
+ result.type = "string";
46
+ break;
47
+ case "ZodNumber":
48
+ result.type = "number";
49
+ break;
50
+ case "ZodBoolean":
51
+ result.type = "boolean";
52
+ break;
53
+ case "ZodEnum":
54
+ result.type = "string";
55
+ result.enum = def.values;
56
+ break;
57
+ default:
58
+ result.type = "string";
59
+ }
60
+ return result;
61
+ }
62
+ //# sourceMappingURL=zod-to-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod-to-json.js","sourceRoot":"","sources":["../../src/utils/zod-to-json.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,MAA8B;IAE9B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,MAAM,UAAU,GAA4C,EAAE,CAAC;IAC/D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACpD,MAAM,KAAK,GAAG,QAAsB,CAAC;QACrC,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACnC,UAAU,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QAEvB,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAA4B;QACtC,IAAI,EAAE,QAAQ;QACd,UAAU;KACX,CAAC;IACF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,cAAc,CAAC,KAAiB;IACvC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC;IAEvB,kBAAkB;IAClB,IAAI,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;QACnC,OAAO,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;IAED,iBAAiB;IACjB,IAAI,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;QAClC,OAAO,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,MAAM,GAA4B,EAAE,CAAC;IAE3C,sBAAsB;IACtB,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;QACpB,MAAM,CAAC,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC;IACvC,CAAC;IAED,QAAQ,GAAG,CAAC,QAAQ,EAAE,CAAC;QACrB,KAAK,WAAW;YACd,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;YACvB,MAAM;QACR,KAAK,WAAW;YACd,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;YACvB,MAAM;QACR,KAAK,YAAY;YACf,MAAM,CAAC,IAAI,GAAG,SAAS,CAAC;YACxB,MAAM;QACR,KAAK,SAAS;YACZ,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;YACvB,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC;YACzB,MAAM;QACR;YACE,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@bank-mcp/server",
3
+ "version": "0.1.0",
4
+ "description": "Banking data MCP server — give your AI assistant read-only access to bank accounts via pluggable providers",
5
+ "type": "module",
6
+ "bin": {
7
+ "bank-mcp": "./dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "start": "node dist/index.js",
14
+ "test": "vitest run",
15
+ "test:watch": "vitest",
16
+ "lint": "eslint src/ tests/",
17
+ "prepublishOnly": "npm run build"
18
+ },
19
+ "keywords": [
20
+ "mcp",
21
+ "banking",
22
+ "psd2",
23
+ "enable-banking",
24
+ "ai",
25
+ "llm",
26
+ "claude"
27
+ ],
28
+ "author": "Luke",
29
+ "license": "MIT",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/elcukro/bank-mcp.git"
33
+ },
34
+ "bugs": {
35
+ "url": "https://github.com/elcukro/bank-mcp/issues"
36
+ },
37
+ "homepage": "https://github.com/elcukro/bank-mcp#readme",
38
+ "dependencies": {
39
+ "@modelcontextprotocol/sdk": "^1.25.0",
40
+ "jsonwebtoken": "^9.0.0",
41
+ "zod": "^4.3.6"
42
+ },
43
+ "devDependencies": {
44
+ "@types/jsonwebtoken": "^9.0.0",
45
+ "@types/node": "^22.0.0",
46
+ "eslint": "^9.0.0",
47
+ "typescript": "^5.7.0",
48
+ "vitest": "^3.0.0"
49
+ },
50
+ "engines": {
51
+ "node": ">=18.0.0"
52
+ },
53
+ "files": [
54
+ "dist",
55
+ "README.md",
56
+ "LICENSE"
57
+ ]
58
+ }