@dizzlkheinz/ynab-mcpb 0.16.1 → 0.17.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 (92) hide show
  1. package/.code/agents/0098661e-0fa3-4990-beb9-c0cbf3f123aa/status.txt +1 -0
  2. package/.code/agents/1324/exec-call_tIpx9uV1TpARbAMZonRQm8AO.txt +757 -0
  3. package/.code/agents/1572/exec-call_GjVFBFOWcY7lE0idc5nWlLNh.txt +781 -0
  4. package/.code/agents/1846/exec-call_1YNAVD18RjrMN7JnfkkQhUP3.txt +766 -0
  5. package/.code/agents/1846/exec-call_lh3lDzE4WJAh1lFiomiiZ73D.txt +766 -0
  6. package/.code/agents/2038/exec-call_DYwOukaYsL8VCONWmV2rUW5u.txt +766 -0
  7. package/.code/agents/2038/exec-call_c7fOQ7UrpVcTtvdfGBRM146V.txt +652 -0
  8. package/.code/agents/2038/exec-call_ySNyq9Mm55jWE480s54r5QcA.txt +766 -0
  9. package/.code/agents/2256/exec-call_AtPcRWPmFPMcmX6qOFm1fCEY.txt +766 -0
  10. package/.code/agents/2454/exec-call_aFJpupwjfZeOBm7ixI5Vc8z2.txt +766 -0
  11. package/.code/agents/2454/exec-call_wogZ4HfXTodTEXvdgXlVUBpv.txt +766 -0
  12. package/.code/agents/2e905864-aa07-4314-bcf9-c5b32277e4ac/result.txt +36 -0
  13. package/.code/agents/3073/exec-call_Peeagc9DxGYLgE6pNdMZhqIE.txt +766 -0
  14. package/.code/agents/3073/exec-call_d2YSE3hXF08KRSoUM3qd8Z3x.txt +766 -0
  15. package/.code/agents/335aa031-466d-4fb7-925f-3cd864e264d0/result.txt +191 -0
  16. package/.code/agents/3364/exec-call_NbhIrsM5HhyDZDmJZG5CuCYL.txt +766 -0
  17. package/.code/agents/3364/exec-call_cKtJg0NrXiwXEFwlsE3uPZRA.txt +766 -0
  18. package/.code/agents/36d98414-5cde-4d9d-9a67-a240a18c1f07/result.txt +189 -0
  19. package/.code/agents/4604e866-b7b8-44f5-992f-2f683b0a523b/status.txt +1 -0
  20. package/.code/agents/5f8dc01c-47b3-4163-b0b3-aa31be89fcdc/status.txt +1 -0
  21. package/.code/agents/7/exec-call_HltHpkDox0Zm1vGEjdksUgpE.txt +1120 -0
  22. package/.code/agents/7/exec-call_LCATrOPPAgbxW9Q1z0XaVi2E.txt +2646 -0
  23. package/.code/agents/7/exec-call_W8DeRfNG9hvbgVFvf0clBf6R.txt +2646 -0
  24. package/.code/agents/94a0ddf3-a304-4ec3-913e-3cceef509948/error.txt +1 -0
  25. package/.code/agents/e2c752b7-711d-423a-af57-f53c809deb84/result.txt +160 -0
  26. package/.code/agents/e6601719-c31f-4a0e-8c71-d70787d0ab71/status.txt +1 -0
  27. package/.code/agents/f250b7ed-5bd5-4036-aa8c-ce63caee7d61/result.txt +20 -0
  28. package/AGENTS.md +1 -36
  29. package/CLAUDE.md +28 -43
  30. package/NUL +0 -1
  31. package/README.md +8 -10
  32. package/dist/bundle/index.cjs +41 -41
  33. package/dist/server/YNABMCPServer.js +28 -381
  34. package/dist/server/config.d.ts +2 -0
  35. package/dist/server/config.js +1 -0
  36. package/dist/tools/accountTools.d.ts +2 -0
  37. package/dist/tools/accountTools.js +45 -0
  38. package/dist/tools/adapters.d.ts +12 -0
  39. package/dist/tools/adapters.js +25 -0
  40. package/dist/tools/budgetTools.d.ts +2 -0
  41. package/dist/tools/budgetTools.js +30 -0
  42. package/dist/tools/categoryTools.d.ts +2 -0
  43. package/dist/tools/categoryTools.js +45 -0
  44. package/dist/tools/monthTools.d.ts +2 -0
  45. package/dist/tools/monthTools.js +32 -0
  46. package/dist/tools/payeeTools.d.ts +2 -0
  47. package/dist/tools/payeeTools.js +32 -0
  48. package/dist/tools/reconciliation/index.d.ts +2 -0
  49. package/dist/tools/reconciliation/index.js +33 -0
  50. package/dist/tools/schemas/common.d.ts +3 -0
  51. package/dist/tools/schemas/common.js +3 -0
  52. package/dist/tools/schemas/outputs/comparisonOutputs.d.ts +1 -1
  53. package/dist/tools/transactionTools.d.ts +2 -0
  54. package/dist/tools/transactionTools.js +124 -0
  55. package/dist/tools/utilityTools.d.ts +3 -1
  56. package/dist/tools/utilityTools.js +32 -2
  57. package/dist/types/index.d.ts +1 -0
  58. package/dist/types/toolRegistration.d.ts +27 -0
  59. package/dist/types/toolRegistration.js +1 -0
  60. package/package.json +2 -2
  61. package/scripts/run-domain-integration-tests.js +4 -1
  62. package/src/__tests__/workflows.e2e.test.ts +1 -7
  63. package/src/server/YNABMCPServer.ts +33 -519
  64. package/src/server/__tests__/toolRegistration.test.ts +236 -0
  65. package/src/server/config.ts +1 -0
  66. package/src/tools/__tests__/adapters.test.ts +113 -0
  67. package/src/tools/__tests__/utilityTools.test.ts +7 -7
  68. package/src/tools/accountTools.ts +53 -0
  69. package/src/tools/adapters.ts +74 -0
  70. package/src/tools/budgetTools.ts +37 -0
  71. package/src/tools/categoryTools.ts +53 -0
  72. package/src/tools/monthTools.ts +39 -0
  73. package/src/tools/payeeTools.ts +39 -0
  74. package/src/tools/reconciliation/index.ts +45 -0
  75. package/src/tools/schemas/common.ts +18 -0
  76. package/src/tools/transactionTools.ts +140 -0
  77. package/src/tools/utilityTools.ts +42 -2
  78. package/src/types/index.ts +3 -0
  79. package/src/types/toolRegistration.ts +88 -0
  80. package/.github/workflows/pr-description-check.yml +0 -88
  81. package/docs/README.md +0 -72
  82. package/docs/getting-started/CONFIGURATION.md +0 -175
  83. package/docs/getting-started/INSTALLATION.md +0 -333
  84. package/docs/getting-started/QUICKSTART.md +0 -282
  85. package/docs/guides/ARCHITECTURE.md +0 -533
  86. package/docs/guides/DEPLOYMENT.md +0 -189
  87. package/docs/guides/INTEGRATION_TESTING.md +0 -730
  88. package/docs/guides/TESTING.md +0 -591
  89. package/docs/reconciliation-flow.md +0 -83
  90. package/docs/reference/EXAMPLES.md +0 -946
  91. package/docs/reference/TOOLS.md +0 -348
  92. package/docs/reference/TROUBLESHOOTING.md +0 -481
@@ -8,6 +8,9 @@ import { cacheManager, CACHE_TTLS, CacheManager } from '../server/cacheManager.j
8
8
  import type { DeltaFetcher } from './deltaFetcher.js';
9
9
  import { CacheKeys } from '../server/cacheKeys.js';
10
10
  import { resolveDeltaFetcherArgs } from './deltaSupport.js';
11
+ import type { ToolFactory } from '../types/toolRegistration.js';
12
+ import { createAdapters, createBudgetResolver } from './adapters.js';
13
+ import { ToolAnnotationPresets } from './toolCategories.js';
11
14
 
12
15
  /**
13
16
  * Schema for ynab:get_month tool parameters
@@ -168,3 +171,39 @@ export async function handleListMonths(
168
171
  'listing months',
169
172
  );
170
173
  }
174
+
175
+ /**
176
+ * Registers all month-related tools with the registry.
177
+ */
178
+ export const registerMonthTools: ToolFactory = (registry, context) => {
179
+ const { adapt, adaptWithDelta } = createAdapters(context);
180
+ const budgetResolver = createBudgetResolver(context);
181
+
182
+ registry.register({
183
+ name: 'get_month',
184
+ description: 'Get budget data for a specific month',
185
+ inputSchema: GetMonthSchema,
186
+ handler: adapt(handleGetMonth),
187
+ defaultArgumentResolver: budgetResolver<z.infer<typeof GetMonthSchema>>(),
188
+ metadata: {
189
+ annotations: {
190
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
191
+ title: 'YNAB: Get Month Details',
192
+ },
193
+ },
194
+ });
195
+
196
+ registry.register({
197
+ name: 'list_months',
198
+ description: 'List all months summary data for a budget',
199
+ inputSchema: ListMonthsSchema,
200
+ handler: adaptWithDelta(handleListMonths),
201
+ defaultArgumentResolver: budgetResolver<z.infer<typeof ListMonthsSchema>>(),
202
+ metadata: {
203
+ annotations: {
204
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
205
+ title: 'YNAB: List Months',
206
+ },
207
+ },
208
+ });
209
+ };
@@ -7,6 +7,9 @@ import { cacheManager, CACHE_TTLS, CacheManager } from '../server/cacheManager.j
7
7
  import type { DeltaFetcher } from './deltaFetcher.js';
8
8
  import { CacheKeys } from '../server/cacheKeys.js';
9
9
  import { resolveDeltaFetcherArgs } from './deltaSupport.js';
10
+ import type { ToolFactory } from '../types/toolRegistration.js';
11
+ import { createAdapters, createBudgetResolver } from './adapters.js';
12
+ import { ToolAnnotationPresets } from './toolCategories.js';
10
13
 
11
14
  /**
12
15
  * Schema for ynab:list_payees tool parameters
@@ -144,3 +147,39 @@ export async function handleGetPayee(
144
147
  'getting payee details',
145
148
  );
146
149
  }
150
+
151
+ /**
152
+ * Registers all payee-related tools with the registry.
153
+ */
154
+ export const registerPayeeTools: ToolFactory = (registry, context) => {
155
+ const { adapt, adaptWithDelta } = createAdapters(context);
156
+ const budgetResolver = createBudgetResolver(context);
157
+
158
+ registry.register({
159
+ name: 'list_payees',
160
+ description: 'List all payees for a specific budget',
161
+ inputSchema: ListPayeesSchema,
162
+ handler: adaptWithDelta(handleListPayees),
163
+ defaultArgumentResolver: budgetResolver<z.infer<typeof ListPayeesSchema>>(),
164
+ metadata: {
165
+ annotations: {
166
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
167
+ title: 'YNAB: List Payees',
168
+ },
169
+ },
170
+ });
171
+
172
+ registry.register({
173
+ name: 'get_payee',
174
+ description: 'Get detailed information for a specific payee',
175
+ inputSchema: GetPayeeSchema,
176
+ handler: adapt(handleGetPayee),
177
+ defaultArgumentResolver: budgetResolver<z.infer<typeof GetPayeeSchema>>(),
178
+ metadata: {
179
+ annotations: {
180
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
181
+ title: 'YNAB: Get Payee Details',
182
+ },
183
+ },
184
+ });
185
+ };
@@ -8,6 +8,13 @@ import { z } from 'zod/v4';
8
8
  import type * as ynab from 'ynab';
9
9
  import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
10
10
  import { withToolErrorHandling } from '../../types/index.js';
11
+ import type { ToolFactory } from '../../types/toolRegistration.js';
12
+ import { createAdapters, createBudgetResolver } from '../adapters.js';
13
+ import { ToolAnnotationPresets } from '../toolCategories.js';
14
+ import {
15
+ CompareTransactionsSchema,
16
+ handleCompareTransactions,
17
+ } from '../compareTransactions/index.js';
11
18
  import { analyzeReconciliation } from './analyzer.js';
12
19
  import type { MatchingConfig } from './matcher.js';
13
20
  import { buildReconciliationPayload } from '../reconcileAdapter.js';
@@ -457,6 +464,44 @@ export async function handleReconcileAccount(
457
464
  );
458
465
  }
459
466
 
467
+ /**
468
+ * Registers reconciliation-domain tools (compare + reconcile) with the registry.
469
+ */
470
+ export const registerReconciliationTools: ToolFactory = (registry, context) => {
471
+ const { adapt, adaptWithDelta } = createAdapters(context);
472
+ const budgetResolver = createBudgetResolver(context);
473
+
474
+ registry.register({
475
+ name: 'compare_transactions',
476
+ description:
477
+ 'Compare bank transactions from CSV with YNAB transactions to find missing entries',
478
+ inputSchema: CompareTransactionsSchema,
479
+ handler: adapt(handleCompareTransactions),
480
+ defaultArgumentResolver: budgetResolver<z.infer<typeof CompareTransactionsSchema>>(),
481
+ metadata: {
482
+ annotations: {
483
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
484
+ title: 'YNAB: Compare Transactions',
485
+ },
486
+ },
487
+ });
488
+
489
+ registry.register({
490
+ name: 'reconcile_account',
491
+ description:
492
+ 'Guided reconciliation workflow with human narrative, insight detection, and optional execution (create/update/unclear). Set include_structured_data=true to also get full JSON output (large).',
493
+ inputSchema: ReconcileAccountSchema,
494
+ handler: adaptWithDelta(handleReconcileAccount),
495
+ defaultArgumentResolver: budgetResolver<z.infer<typeof ReconcileAccountSchema>>(),
496
+ metadata: {
497
+ annotations: {
498
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_UPDATE,
499
+ title: 'YNAB: Reconcile Account',
500
+ },
501
+ },
502
+ });
503
+ };
504
+
460
505
  function mapCsvDateFormatToHint(
461
506
  format: string | undefined,
462
507
  ): ParseCSVOptions['dateFormat'] | undefined {
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @fileoverview Shared Zod schemas used across multiple tool domains.
3
+ * @module tools/schemas/common
4
+ */
5
+
6
+ import { z } from 'zod/v4';
7
+
8
+ /**
9
+ * Strict empty object schema used for tools that do not accept input params.
10
+ * Examples: list_budgets, get_user, get_default_budget, clear_cache
11
+ */
12
+ export const emptyObjectSchema = z.object({}).strict();
13
+
14
+ /**
15
+ * Permissive object schema used when hosts require a top-level object but we
16
+ * intentionally allow passthrough properties (e.g., mutation tool outputs).
17
+ */
18
+ export const looseObjectSchema = z.object({}).passthrough();
@@ -6,6 +6,9 @@ import type { SaveTransactionsResponseData } from 'ynab/dist/models/SaveTransact
6
6
  import { z } from 'zod/v4';
7
7
  import { createHash } from 'crypto';
8
8
  import { ValidationError, withToolErrorHandling } from '../types/index.js';
9
+ import type { ToolFactory } from '../types/toolRegistration.js';
10
+ import { createAdapters, createBudgetResolver } from './adapters.js';
11
+ import { ToolAnnotationPresets } from './toolCategories.js';
9
12
  import { responseFormatter } from '../server/responseFormatter.js';
10
13
  import { amountToMilliunits, milliunitsToAmount } from '../utils/amountUtils.js';
11
14
  import { cacheManager, CACHE_TTLS, CacheManager } from '../server/cacheManager.js';
@@ -14,6 +17,7 @@ import type { DeltaFetcher } from './deltaFetcher.js';
14
17
  import type { DeltaCache } from '../server/deltaCache.js';
15
18
  import type { ServerKnowledgeStore } from '../server/serverKnowledgeStore.js';
16
19
  import { resolveDeltaFetcherArgs, resolveDeltaWriteArgs } from './deltaSupport.js';
20
+ import { handleExportTransactions, ExportTransactionsSchema } from './exportTransactions.js';
17
21
 
18
22
  /**
19
23
  * Utility function to ensure transaction is not null/undefined
@@ -2506,3 +2510,139 @@ function handleTransactionError(error: unknown, defaultMessage: string): CallToo
2506
2510
  ],
2507
2511
  };
2508
2512
  }
2513
+
2514
+ /**
2515
+ * Registers transaction-domain tools with the provided registry.
2516
+ */
2517
+ export const registerTransactionTools: ToolFactory = (registry, context) => {
2518
+ const { adapt, adaptWithDelta, adaptWrite } = createAdapters(context);
2519
+ const budgetResolver = createBudgetResolver(context);
2520
+
2521
+ registry.register({
2522
+ name: 'list_transactions',
2523
+ description: 'List transactions for a budget with optional filtering',
2524
+ inputSchema: ListTransactionsSchema,
2525
+ handler: adaptWithDelta(handleListTransactions),
2526
+ defaultArgumentResolver: budgetResolver<z.infer<typeof ListTransactionsSchema>>(),
2527
+ metadata: {
2528
+ annotations: {
2529
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
2530
+ title: 'YNAB: List Transactions',
2531
+ },
2532
+ },
2533
+ });
2534
+
2535
+ registry.register({
2536
+ name: 'export_transactions',
2537
+ description: 'Export all transactions to a JSON file with descriptive filename',
2538
+ inputSchema: ExportTransactionsSchema,
2539
+ handler: adapt(handleExportTransactions),
2540
+ defaultArgumentResolver: budgetResolver<z.infer<typeof ExportTransactionsSchema>>(),
2541
+ metadata: {
2542
+ annotations: {
2543
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
2544
+ title: 'YNAB: Export Transactions',
2545
+ },
2546
+ },
2547
+ });
2548
+
2549
+ registry.register({
2550
+ name: 'get_transaction',
2551
+ description: 'Get detailed information for a specific transaction',
2552
+ inputSchema: GetTransactionSchema,
2553
+ handler: adapt(handleGetTransaction),
2554
+ defaultArgumentResolver: budgetResolver<z.infer<typeof GetTransactionSchema>>(),
2555
+ metadata: {
2556
+ annotations: {
2557
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
2558
+ title: 'YNAB: Get Transaction Details',
2559
+ },
2560
+ },
2561
+ });
2562
+
2563
+ registry.register({
2564
+ name: 'create_transaction',
2565
+ description: 'Create a new transaction in the specified budget and account',
2566
+ inputSchema: CreateTransactionSchema,
2567
+ handler: adaptWrite(handleCreateTransaction),
2568
+ defaultArgumentResolver: budgetResolver<z.infer<typeof CreateTransactionSchema>>(),
2569
+ metadata: {
2570
+ annotations: {
2571
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_CREATE,
2572
+ title: 'YNAB: Create Transaction',
2573
+ },
2574
+ },
2575
+ });
2576
+
2577
+ registry.register({
2578
+ name: 'create_transactions',
2579
+ description:
2580
+ 'Create multiple transactions in a single batch (1-100 items) with duplicate detection, dry-run validation, and automatic response size management with correlation metadata.',
2581
+ inputSchema: CreateTransactionsSchema,
2582
+ handler: adaptWrite(handleCreateTransactions),
2583
+ defaultArgumentResolver: budgetResolver<z.infer<typeof CreateTransactionsSchema>>(),
2584
+ metadata: {
2585
+ annotations: {
2586
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_CREATE,
2587
+ title: 'YNAB: Create Multiple Transactions',
2588
+ },
2589
+ },
2590
+ });
2591
+
2592
+ registry.register({
2593
+ name: 'create_receipt_split_transaction',
2594
+ description: 'Create a split transaction from receipt items with proportional tax allocation',
2595
+ inputSchema: CreateReceiptSplitTransactionSchema,
2596
+ handler: adaptWrite(handleCreateReceiptSplitTransaction),
2597
+ defaultArgumentResolver: budgetResolver<z.infer<typeof CreateReceiptSplitTransactionSchema>>(),
2598
+ metadata: {
2599
+ annotations: {
2600
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_CREATE,
2601
+ title: 'YNAB: Create Split Transaction from Receipt',
2602
+ },
2603
+ },
2604
+ });
2605
+
2606
+ registry.register({
2607
+ name: 'update_transaction',
2608
+ description: 'Update an existing transaction',
2609
+ inputSchema: UpdateTransactionSchema,
2610
+ handler: adaptWrite(handleUpdateTransaction),
2611
+ defaultArgumentResolver: budgetResolver<z.infer<typeof UpdateTransactionSchema>>(),
2612
+ metadata: {
2613
+ annotations: {
2614
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_UPDATE,
2615
+ title: 'YNAB: Update Transaction',
2616
+ },
2617
+ },
2618
+ });
2619
+
2620
+ registry.register({
2621
+ name: 'update_transactions',
2622
+ description:
2623
+ 'Update multiple transactions in a single batch (1-100 items) with dry-run validation, automatic cache invalidation, and response size management. Supports optional original_account_id and original_date metadata for efficient cache invalidation.',
2624
+ inputSchema: UpdateTransactionsSchema,
2625
+ handler: adaptWrite(handleUpdateTransactions),
2626
+ defaultArgumentResolver: budgetResolver<z.infer<typeof UpdateTransactionsSchema>>(),
2627
+ metadata: {
2628
+ annotations: {
2629
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_UPDATE,
2630
+ title: 'YNAB: Update Multiple Transactions',
2631
+ },
2632
+ },
2633
+ });
2634
+
2635
+ registry.register({
2636
+ name: 'delete_transaction',
2637
+ description: 'Delete a transaction from the specified budget',
2638
+ inputSchema: DeleteTransactionSchema,
2639
+ handler: adaptWrite(handleDeleteTransaction),
2640
+ defaultArgumentResolver: budgetResolver<z.infer<typeof DeleteTransactionSchema>>(),
2641
+ metadata: {
2642
+ annotations: {
2643
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_DELETE,
2644
+ title: 'YNAB: Delete Transaction',
2645
+ },
2646
+ },
2647
+ });
2648
+ };
@@ -1,8 +1,12 @@
1
1
  import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
2
2
  import * as ynab from 'ynab';
3
3
  import { z } from 'zod/v4';
4
- import { withToolErrorHandling } from '../types/index.js';
5
4
  import { responseFormatter } from '../server/responseFormatter.js';
5
+ import { withToolErrorHandling } from '../types/index.js';
6
+ import { createAdapters } from './adapters.js';
7
+ import { emptyObjectSchema } from './schemas/common.js';
8
+ import { ToolAnnotationPresets } from './toolCategories.js';
9
+ import type { ToolFactory } from '../types/toolRegistration.js';
6
10
 
7
11
  /**
8
12
  * Schema for ynab:convert_amount tool parameters
@@ -48,7 +52,10 @@ export async function handleGetUser(ynabAPI: ynab.API): Promise<CallToolResult>
48
52
  * Handles the ynab:convert_amount tool call
49
53
  * Converts between dollars and milliunits with integer arithmetic for precision
50
54
  */
51
- export async function handleConvertAmount(params: ConvertAmountParams): Promise<CallToolResult> {
55
+ export async function handleConvertAmount(
56
+ _ynabAPI: ynab.API,
57
+ params: ConvertAmountParams,
58
+ ): Promise<CallToolResult> {
52
59
  return await withToolErrorHandling(
53
60
  async () => {
54
61
  const { amount, to_milliunits } = params;
@@ -88,3 +95,36 @@ export async function handleConvertAmount(params: ConvertAmountParams): Promise<
88
95
  'converting amount',
89
96
  );
90
97
  }
98
+
99
+ /**
100
+ * Registers utility tools (get_user, convert_amount) using the shared factory pattern.
101
+ */
102
+ export const registerUtilityTools: ToolFactory = (registry, context) => {
103
+ const { adapt, adaptNoInput } = createAdapters(context);
104
+
105
+ registry.register({
106
+ name: 'get_user',
107
+ description: 'Get information about the authenticated user',
108
+ inputSchema: emptyObjectSchema,
109
+ handler: adaptNoInput(handleGetUser),
110
+ metadata: {
111
+ annotations: {
112
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
113
+ title: 'YNAB: Get User Information',
114
+ },
115
+ },
116
+ });
117
+
118
+ registry.register({
119
+ name: 'convert_amount',
120
+ description: 'Convert between dollars and milliunits with integer arithmetic for precision',
121
+ inputSchema: ConvertAmountSchema,
122
+ handler: adapt(handleConvertAmount),
123
+ metadata: {
124
+ annotations: {
125
+ ...ToolAnnotationPresets.UTILITY_LOCAL,
126
+ title: 'YNAB: Convert Amount',
127
+ },
128
+ },
129
+ });
130
+ };
@@ -65,3 +65,6 @@ export type { MCPToolAnnotations } from './toolAnnotations.js';
65
65
 
66
66
  // Re-export tool registry types for convenience
67
67
  export type { ToolDefinition } from '../server/toolRegistry.js';
68
+
69
+ // Re-export tool registration factory types
70
+ export type { ToolContext, ToolFactory, BudgetIdResolverFactory } from './toolRegistration.js';
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @fileoverview Type definitions for the tool factory registration pattern.
3
+ * Provides ToolContext for dependency injection and typed handler signatures
4
+ * used by domain-specific tool factory functions.
5
+ * @module types/toolRegistration
6
+ */
7
+
8
+ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
9
+ import * as ynab from 'ynab';
10
+ import type {
11
+ ToolRegistry,
12
+ ToolExecutionPayload,
13
+ DefaultArgumentResolver,
14
+ } from '../server/toolRegistry.js';
15
+ import type { DeltaFetcher } from '../tools/deltaFetcher.js';
16
+ import type { DeltaCache } from '../server/deltaCache.js';
17
+ import type { ServerKnowledgeStore } from '../server/serverKnowledgeStore.js';
18
+ import type { DiagnosticManager } from '../server/diagnostics.js';
19
+ import type { CacheManager } from '../server/cacheManager.js';
20
+
21
+ /**
22
+ * Context object passed to tool factory functions. Contains the dependencies
23
+ * required by tool adapters and handlers.
24
+ *
25
+ * @stable This interface is part of the public tool registration contract.
26
+ * Changes to this interface may affect all domain tool factories.
27
+ */
28
+ export interface ToolContext {
29
+ ynabAPI: ynab.API;
30
+ deltaFetcher: DeltaFetcher;
31
+ deltaCache: DeltaCache;
32
+ serverKnowledgeStore: ServerKnowledgeStore;
33
+ getDefaultBudgetId: () => string | undefined;
34
+ setDefaultBudget: (budgetId: string) => void;
35
+ cacheManager: CacheManager;
36
+ diagnosticManager?: DiagnosticManager;
37
+ }
38
+
39
+ /**
40
+ * Factory function signature for registering a domain's tools.
41
+ */
42
+ export type ToolFactory = (registry: ToolRegistry, context: ToolContext) => void;
43
+
44
+ /**
45
+ * Common adapter signature used within tool factories.
46
+ */
47
+ export type Adapter<TInput extends Record<string, unknown>> = (
48
+ payload: ToolExecutionPayload<TInput>,
49
+ ) => Promise<CallToolResult>;
50
+
51
+ /**
52
+ * Generic handler signature used by adapter helpers.
53
+ */
54
+ export type Handler<TInput extends Record<string, unknown>> = (
55
+ api: ynab.API,
56
+ params: TInput,
57
+ ) => Promise<CallToolResult>;
58
+
59
+ /**
60
+ * Handler signature for operations that require delta fetching.
61
+ */
62
+ export type DeltaHandler<TInput extends Record<string, unknown>> = (
63
+ api: ynab.API,
64
+ deltaFetcher: DeltaFetcher,
65
+ params: TInput,
66
+ ) => Promise<CallToolResult>;
67
+
68
+ /**
69
+ * Handler signature for write operations that update caches and knowledge stores.
70
+ */
71
+ export type WriteHandler<TInput extends Record<string, unknown>> = (
72
+ api: ynab.API,
73
+ deltaCache: DeltaCache,
74
+ serverKnowledgeStore: ServerKnowledgeStore,
75
+ params: TInput,
76
+ ) => Promise<CallToolResult>;
77
+
78
+ /**
79
+ * Handler signature for tools that do not accept input parameters.
80
+ */
81
+ export type NoInputHandler = (api: ynab.API) => Promise<CallToolResult>;
82
+
83
+ /**
84
+ * Helper type for default argument resolver factories.
85
+ */
86
+ export type BudgetIdResolverFactory = <
87
+ TInput extends { budget_id?: string | undefined },
88
+ >() => DefaultArgumentResolver<TInput>;
@@ -1,88 +0,0 @@
1
- name: PR Description Check
2
-
3
- on:
4
- pull_request:
5
- types: [opened, edited, synchronize]
6
-
7
- permissions:
8
- contents: read
9
- issues: write
10
- pull-requests: read
11
-
12
- jobs:
13
- check-description:
14
- runs-on: ubuntu-latest
15
- steps:
16
- - name: Check PR Description Format
17
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
18
- with:
19
- script: |
20
- const body = context.payload.pull_request.body || '';
21
-
22
- // Required sections from template
23
- const requiredSections = [
24
- 'Type of change',
25
- 'Public API surface checklist',
26
- 'Versioning and release'
27
- ];
28
-
29
- const missingSections = requiredSections.filter(section =>
30
- !body.includes(section)
31
- );
32
-
33
- if (missingSections.length > 0) {
34
- // Build comment as array to avoid YAML indentation issues
35
- const commentLines = [
36
- '⚠️ **PR Description Check Failed**',
37
- '',
38
- 'The PR description is missing required sections from the template:',
39
- ...missingSections.map(s => `- ${s}`),
40
- '',
41
- 'Please update the description to include these sections. You can view the template at:',
42
- `https://github.com/${context.repo.owner}/${context.repo.repo}/blob/master/.github/pull_request_template.md`,
43
- '',
44
- 'Or run this command to update it:',
45
- '```bash',
46
- `gh pr edit ${context.payload.pull_request.number} --body-file .github/pull_request_template.md`,
47
- '```'
48
- ];
49
- const comment = commentLines.join('\n');
50
-
51
- // Upsert comment: update existing bot comment or create new one
52
- const botCommentPrefix = '⚠️ **PR Description Check Failed**';
53
- // Paginate through all comments to handle PRs with >30 comments
54
- const comments = await github.paginate(
55
- github.rest.issues.listComments,
56
- {
57
- owner: context.repo.owner,
58
- repo: context.repo.repo,
59
- issue_number: context.payload.pull_request.number,
60
- per_page: 100
61
- }
62
- );
63
-
64
- const existingComment = comments.find(
65
- c => c.user.type === 'Bot' && c.body.startsWith(botCommentPrefix)
66
- );
67
-
68
- if (existingComment) {
69
- await github.rest.issues.updateComment({
70
- owner: context.repo.owner,
71
- repo: context.repo.repo,
72
- comment_id: existingComment.id,
73
- body: comment
74
- });
75
- } else {
76
- await github.rest.issues.createComment({
77
- owner: context.repo.owner,
78
- repo: context.repo.repo,
79
- issue_number: context.payload.pull_request.number,
80
- body: comment
81
- });
82
- }
83
-
84
- // Fail the check
85
- core.setFailed(`Missing required sections: ${missingSections.join(', ')}`);
86
- } else {
87
- console.log('✅ All required sections present in PR description');
88
- }
package/docs/README.md DELETED
@@ -1,72 +0,0 @@
1
- # YNAB MCP Server Documentation
2
-
3
- Complete documentation for the YNAB Model Context Protocol Server.
4
-
5
- ## 📚 Documentation Overview
6
-
7
- ### Getting Started
8
- New to the YNAB MCP Server? Start here:
9
-
10
- - **[Quick Start](getting-started/QUICKSTART.md)** - Fast path to testing with Claude Desktop
11
- - **[Installation](getting-started/INSTALLATION.md)** - Detailed installation instructions
12
- - **[Configuration](getting-started/CONFIGURATION.md)** - Environment variables and settings
13
-
14
- ### Guides
15
- Learn how to develop with and extend the server:
16
-
17
- - **[Architecture](guides/ARCHITECTURE.md)** - Server architecture and core components
18
- - **[Testing](guides/TESTING.md)** - Automated and manual testing strategies
19
- - **[Deployment](guides/DEPLOYMENT.md)** - Production deployment instructions
20
-
21
- ### Reference
22
- Complete API and technical reference:
23
-
24
- - **[API Reference](reference/API.md)** - Complete tool documentation with examples
25
- - **[Tools Quick Reference](reference/TOOLS.md)** - Quick tool catalog and parameter guide
26
- - **[Examples](reference/EXAMPLES.md)** - Practical usage examples and workflows
27
- - **[Troubleshooting](reference/TROUBLESHOOTING.md)** - Common issues, solutions, and debugging
28
-
29
- ## 🎯 Quick Navigation by Task
30
-
31
- ### I want to...
32
-
33
- **Get Started**
34
- - Install and configure → [Installation](getting-started/INSTALLATION.md)
35
- - Test quickly → [Quick Start](getting-started/QUICKSTART.md)
36
- - Understand the architecture → [Architecture](guides/ARCHITECTURE.md)
37
-
38
- **Develop**
39
- - Create a new tool → [Architecture Guide](guides/ARCHITECTURE.md#developing-tools-with-v08x)
40
- - Understand the architecture → [Architecture](guides/ARCHITECTURE.md)
41
-
42
- **Troubleshoot**
43
- - Common issues → [Troubleshooting](reference/TROUBLESHOOTING.md)
44
-
45
- **Test**
46
- - Run automated tests → [Testing Guide](guides/TESTING.md)
47
-
48
- **Deploy**
49
- - Deploy to production → [Deployment Guide](guides/DEPLOYMENT.md)
50
- - Configure for Claude Desktop → [Quick Start](getting-started/QUICKSTART.md#claude-desktop-integration)
51
-
52
- ## 🔗 External Resources
53
-
54
- - **[YNAB API Documentation](https://api.youneedabudget.com/)** - Official YNAB API docs
55
- - **[Model Context Protocol](https://modelcontextprotocol.io/)** - MCP specification
56
- - **[Project Repository](https://github.com/dizzlkheinz/mcp-for-ynab)** - GitHub repository
57
- - **[Release Notes](https://github.com/dizzlkheinz/mcp-for-ynab/releases)** - Version history and changelog
58
-
59
- ## 💡 Need Help?
60
-
61
- - **Documentation Issue?** Check the [Troubleshooting Guide](reference/TROUBLESHOOTING.md)
62
- - **Bug Report?** [Open an issue](https://github.com/dizzlkheinz/mcp-for-ynab/issues/new?template=bug_report.md)
63
- - **Feature Request?** [Request a feature](https://github.com/dizzlkheinz/mcp-for-ynab/issues/new?template=feature_request.md)
64
- - **Question?** Check existing [GitHub Discussions](https://github.com/dizzlkheinz/mcp-for-ynab/discussions)
65
-
66
- ## 📄 License
67
-
68
- This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). See the [LICENSE](../LICENSE) file for details.
69
-
70
- ---
71
-
72
- **Quick Links**: [Main README](../README.md) | [API Reference](reference/API.md) | [Quick Start](getting-started/QUICKSTART.md) | [Architecture](guides/ARCHITECTURE.md)