@dizzlkheinz/ynab-mcpb 0.16.1 → 0.17.1

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 (169) hide show
  1. package/.env.example +33 -33
  2. package/.github/workflows/ci-tests.yml +45 -45
  3. package/.github/workflows/claude-code-review.yml +57 -57
  4. package/.github/workflows/claude.yml +50 -50
  5. package/.github/workflows/full-integration.yml +22 -22
  6. package/.github/workflows/publish.yml +11 -2
  7. package/CLAUDE.md +33 -47
  8. package/README.md +8 -10
  9. package/dist/bundle/index.cjs +54 -54
  10. package/dist/server/YNABMCPServer.d.ts +120 -54
  11. package/dist/server/YNABMCPServer.js +28 -381
  12. package/dist/server/config.d.ts +2 -0
  13. package/dist/server/config.js +1 -0
  14. package/dist/server/securityMiddleware.d.ts +37 -8
  15. package/dist/tools/accountTools.d.ts +2 -0
  16. package/dist/tools/accountTools.js +45 -0
  17. package/dist/tools/adapters.d.ts +12 -0
  18. package/dist/tools/adapters.js +25 -0
  19. package/dist/tools/budgetTools.d.ts +2 -0
  20. package/dist/tools/budgetTools.js +30 -0
  21. package/dist/tools/categoryTools.d.ts +2 -0
  22. package/dist/tools/categoryTools.js +45 -0
  23. package/dist/tools/monthTools.d.ts +2 -0
  24. package/dist/tools/monthTools.js +32 -0
  25. package/dist/tools/payeeTools.d.ts +2 -0
  26. package/dist/tools/payeeTools.js +32 -0
  27. package/dist/tools/reconciliation/index.d.ts +2 -0
  28. package/dist/tools/reconciliation/index.js +33 -0
  29. package/dist/tools/schemas/common.d.ts +3 -0
  30. package/dist/tools/schemas/common.js +3 -0
  31. package/dist/tools/schemas/outputs/comparisonOutputs.d.ts +1 -1
  32. package/dist/tools/schemas/outputs/index.d.ts +2 -2
  33. package/dist/tools/schemas/outputs/index.js +2 -2
  34. package/dist/tools/schemas/outputs/utilityOutputs.d.ts +0 -15
  35. package/dist/tools/schemas/outputs/utilityOutputs.js +0 -9
  36. package/dist/tools/transactionTools.d.ts +2 -0
  37. package/dist/tools/transactionTools.js +124 -0
  38. package/dist/tools/utilityTools.d.ts +2 -7
  39. package/dist/tools/utilityTools.js +19 -38
  40. package/dist/types/index.d.ts +1 -0
  41. package/dist/types/toolRegistration.d.ts +27 -0
  42. package/dist/types/toolRegistration.js +1 -0
  43. package/docs/maintainers/npm-publishing.md +27 -0
  44. package/docs/reference/API.md +15 -70
  45. package/docs/technical/reconciliation-system-architecture.md +2251 -2251
  46. package/package.json +6 -6
  47. package/scripts/analyze-bundle.mjs +41 -41
  48. package/scripts/generate-mcpb.ps1 +95 -95
  49. package/scripts/run-domain-integration-tests.js +4 -1
  50. package/scripts/watch-and-restart.ps1 +49 -49
  51. package/src/__tests__/comprehensive.integration.test.ts +0 -28
  52. package/src/__tests__/performance.test.ts +4 -12
  53. package/src/__tests__/setup.ts +45 -14
  54. package/src/__tests__/workflows.e2e.test.ts +1 -51
  55. package/src/server/YNABMCPServer.ts +33 -519
  56. package/src/server/__tests__/YNABMCPServer.test.ts +0 -1
  57. package/src/server/__tests__/toolRegistration.test.ts +236 -0
  58. package/src/server/config.ts +1 -0
  59. package/src/tools/__tests__/adapters.test.ts +113 -0
  60. package/src/tools/__tests__/transactionTools.integration.test.ts +63 -3
  61. package/src/tools/__tests__/utilityTools.integration.test.ts +1 -85
  62. package/src/tools/__tests__/utilityTools.test.ts +1 -123
  63. package/src/tools/accountTools.ts +53 -0
  64. package/src/tools/adapters.ts +74 -0
  65. package/src/tools/budgetTools.ts +37 -0
  66. package/src/tools/categoryTools.ts +53 -0
  67. package/src/tools/monthTools.ts +39 -0
  68. package/src/tools/payeeTools.ts +39 -0
  69. package/src/tools/reconciliation/index.ts +45 -0
  70. package/src/tools/schemas/common.ts +18 -0
  71. package/src/tools/schemas/outputs/index.ts +0 -3
  72. package/src/tools/schemas/outputs/utilityOutputs.ts +2 -43
  73. package/src/tools/toolCategories.ts +0 -1
  74. package/src/tools/transactionTools.ts +140 -0
  75. package/src/tools/utilityTools.ts +24 -55
  76. package/src/types/index.ts +3 -0
  77. package/src/types/toolRegistration.ts +88 -0
  78. package/vitest.config.ts +2 -1
  79. package/.chunkhound.json +0 -11
  80. package/.code/agents/01a13ef4-3f23-4f52-b33b-3585b73cfa60/error.txt +0 -3
  81. package/.code/agents/084fd32f-e298-4728-9103-a78d7dc39613/error.txt +0 -3
  82. package/.code/agents/0fed51e1-a943-4b97-a2a8-a6f0f27c844d/status.txt +0 -1
  83. package/.code/agents/1059b6bd-5ccd-4d83-a12c-7c9d89137399/error.txt +0 -5
  84. package/.code/agents/110/exec-call_F9BDNG7JfxKkq7Vc8ESAvdft.txt +0 -1569
  85. package/.code/agents/11ebcef3-b13f-4e44-ad80-d94a866804b7/error.txt +0 -3
  86. package/.code/agents/1398/exec-call_CjItcWMU1G6JoPshX62QvpaR.txt +0 -2832
  87. package/.code/agents/1398/exec-call_SUVq2ivmONQ5LMCmd7ngmOqr.txt +0 -2709
  88. package/.code/agents/1398/exec-call_SdNY4NOffdcC5pRYjVXHjPCK.txt +0 -2832
  89. package/.code/agents/1398/exec-call_qblJo9et1gsFFB63TtLOiji2.txt +0 -2832
  90. package/.code/agents/1398/exec-call_zaRrzlGz7GJcNzVfkAmML7Zg.txt +0 -2709
  91. package/.code/agents/171834fd-5905-42fc-bbcc-2c755145b0fc/status.txt +0 -1
  92. package/.code/agents/1724/exec-call_HvHQe0w5CCG3T7Q3ULT6MO3g.txt +0 -5217
  93. package/.code/agents/1724/exec-call_QwUNESVzfxxk78K1frh1Vahb.txt +0 -2594
  94. package/.code/agents/1724/exec-call_aJ1Xwz71XmIpD4SBxSHERzLe.txt +0 -2594
  95. package/.code/agents/1d7d7ab7-7473-4b69-8b97-6e914f56056a/result.txt +0 -231
  96. package/.code/agents/210/exec-call_0tQCsKNJ1WTuIchb8wlcFJpW.txt +0 -2590
  97. package/.code/agents/210/exec-call_8ZlY9cUc8Ft1twi4ch8UJ6IN.txt +0 -5195
  98. package/.code/agents/2188/exec-call_5HqayBxIteJtoI8oPTiLWgvJ.txt +0 -286
  99. package/.code/agents/2188/exec-call_XRbBKBq3adZe6dcppAvQtM7G.txt +0 -218
  100. package/.code/agents/2188/exec-call_ehA0SjpYtrUi6GJXmibLjp4i.txt +0 -180
  101. package/.code/agents/21902821-ecaf-4759-bb9d-222b90921af5/error.txt +0 -3
  102. package/.code/agents/232073be-aa0e-46da-b478-5b64dbf03cf5/status.txt +0 -1
  103. package/.code/agents/234ff534-2336-4771-a8d9-aa04421a63be/result.txt +0 -747
  104. package/.code/agents/253e2695-dc36-4022-b436-27655e0fc6c7/status.txt +0 -1
  105. package/.code/agents/2583/exec-call_M59I4eDjpjlBIWBiSxyS0YlJ.txt +0 -2594
  106. package/.code/agents/2583/exec-call_usLRGh7OhVHtsRBL4iUwRhjq.txt +0 -2594
  107. package/.code/agents/292aa3ff-dbab-470f-97c9-e7e8fd65e0db/result.txt +0 -144
  108. package/.code/agents/3134/exec-call_IgCAMGx19lWfuo8zfYIt5FFC.txt +0 -416
  109. package/.code/agents/3134/exec-call_IxvLR2Oo7kba2QTsI1gHVko8.txt +0 -2590
  110. package/.code/agents/3134/exec-call_jYvc8hksZChSiysbzKjl2ZbB.txt +0 -2590
  111. package/.code/agents/329/exec-call_4QdP3SfSO7HGPCwVcqZIth6s.txt +0 -2590
  112. package/.code/agents/472/exec-call_4AxzEEcWwkKhpqRB3bE8Ha4L.txt +0 -790
  113. package/.code/agents/472/exec-call_CB3LPYQA8QIZRi8I6kj4J17A.txt +0 -766
  114. package/.code/agents/472/exec-call_YeoUWvaFoktay2nqVUsa9KKX.txt +0 -790
  115. package/.code/agents/472/exec-call_jPWgKVquBBXTg0T3Lks5ZfkK.txt +0 -2594
  116. package/.code/agents/472/exec-call_qBkvunpGBDEHph2jPmTwtcsb.txt +0 -1000
  117. package/.code/agents/472/exec-call_v0ffRV1p0kTckBmJPzzHAEy0.txt +0 -3489
  118. package/.code/agents/472/exec-call_xAX5FXqWIlk02d9WubHbHWh8.txt +0 -766
  119. package/.code/agents/5346/exec-call_9q0muXUuLaucwEqI51Pt7idT.txt +0 -2594
  120. package/.code/agents/5346/exec-call_B2el3B79rVkq9LhWTI2VYlz7.txt +0 -2456
  121. package/.code/agents/5346/exec-call_BfX08f02qkZI9uJD5dvCvuoj.txt +0 -2594
  122. package/.code/agents/543328d0-61d6-4fd1-a723-bb168656e2e2/error.txt +0 -18
  123. package/.code/agents/5580c02c-1383-4d18-9cbd-cc8a06e3408d/result.txt +0 -48
  124. package/.code/agents/60ce1a22-5126-44b2-b977-1d5b56142a7b/status.txt +0 -1
  125. package/.code/agents/6215d9db-7fa9-4429-aeec-3835c3212291/error.txt +0 -1
  126. package/.code/agents/6743db55-30e5-4b4e-9366-a8214fc7f714/error.txt +0 -1
  127. package/.code/agents/6bf9591b-b9c9-422c-b0a5-e968c7d8422a/status.txt +0 -1
  128. package/.code/agents/7/exec-call_eww3GfdEiJZx61sJEQ9wNmt3.txt +0 -1271
  129. package/.code/agents/70/exec-call_owUtDMYiVgqDf8vsz1i32PFf.txt +0 -1570
  130. package/.code/agents/8/exec-call_UtrjAcLbhYLatxR4O97fZgnm.txt +0 -2590
  131. package/.code/agents/82490bc9-f34e-4b1b-8a8e-bccc2e6254f5/error.txt +0 -3
  132. package/.code/agents/841/exec-call_7nTNhSBCNjTDUIJv7py6CepO.txt +0 -3299
  133. package/.code/agents/841/exec-call_TLI0yUdUijuUAvI4o3DXEvHO.txt +0 -3299
  134. package/.code/agents/9/exec-call_XaABQT1hIlRpnKZ2uyBMWsTC.txt +0 -1882
  135. package/.code/agents/941/exec-call_GuGHRx7NNXWIDAnxUG2NEWPa.txt +0 -2594
  136. package/.code/agents/95d9fbab-19a2-48af-83f9-c792566a347f/error.txt +0 -1
  137. package/.code/agents/b0098cb8-cb32-4ada-9bc4-37c587518896/result.txt +0 -170
  138. package/.code/agents/b4fe59a4-81df-42e2-a112-0153e504faca/error.txt +0 -1
  139. package/.code/agents/bf4ce152-f623-49d7-aa52-c18631625c3c/error.txt +0 -3
  140. package/.code/agents/d7d1db75-d7eb-468e-adea-4ef4d916d187/status.txt +0 -1
  141. package/.code/agents/e2baa9c8-bac3-49e3-a39d-024333e6a990/status.txt +0 -1
  142. package/.code/agents/e350b8c3-8483-408c-b2bb-94515f492a11/error.txt +0 -3
  143. package/.code/agents/e63f9919-719f-4ad0-bccf-01b1a596e1e9/status.txt +0 -1
  144. package/.code/agents/e71695a8-3044-478d-8f12-ed13d02884c7/status.txt +0 -1
  145. package/.code/agents/f95b7464-3e25-4897-b153-c8dfd63fd605/error.txt +0 -5
  146. package/.code/agents/fa3c5ddf-cdf7-47a2-930a-b806c6363689/status.txt +0 -1
  147. package/.github/workflows/pr-description-check.yml +0 -88
  148. package/AGENTS.md +0 -36
  149. package/NUL +0 -1
  150. package/docs/README.md +0 -72
  151. package/docs/getting-started/CONFIGURATION.md +0 -175
  152. package/docs/getting-started/INSTALLATION.md +0 -333
  153. package/docs/getting-started/QUICKSTART.md +0 -282
  154. package/docs/guides/ARCHITECTURE.md +0 -533
  155. package/docs/guides/DEPLOYMENT.md +0 -189
  156. package/docs/guides/INTEGRATION_TESTING.md +0 -730
  157. package/docs/guides/TESTING.md +0 -591
  158. package/docs/reconciliation-flow.md +0 -83
  159. package/docs/reference/EXAMPLES.md +0 -946
  160. package/docs/reference/TOOLS.md +0 -348
  161. package/docs/reference/TROUBLESHOOTING.md +0 -481
  162. package/package.json.tmp +0 -105
  163. package/temp-recon.ts +0 -126
  164. package/test-exports/ynab_account_e9ddc2a6_minimal_1items_2025-11-19_09-04-53.json +0 -23
  165. package/test-exports/ynab_account_e9ddc2a6_minimal_1items_2025-11-19_10-37-42.json +0 -23
  166. package/test-exports/ynab_account_e9ddc2a6_minimal_4items_2025-11-19_09-02-09.json +0 -44
  167. package/test-exports/ynab_account_e9ddc2a6_minimal_6items_2025-11-19_10-37-52.json +0 -58
  168. package/test-exports/ynab_since_2025-10-16_account_53298e13_238items_2025-11-28_13-46-20.json +0 -3662
  169. package/test-exports/ynab_since_2025-11-01_account_4c18e9f0_minimal_14items_2025-11-16_10-07-10.json +0 -115
@@ -0,0 +1,12 @@
1
+ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
2
+ import type { ToolExecutionPayload, DefaultArgumentResolver } from '../server/toolRegistry.js';
3
+ import type { ToolContext, Handler, DeltaHandler, WriteHandler, NoInputHandler } from '../types/toolRegistration.js';
4
+ export declare function createAdapters(context: ToolContext): {
5
+ adapt: <TInput extends Record<string, unknown>>(handler: Handler<TInput>) => ({ input }: ToolExecutionPayload<TInput>) => Promise<CallToolResult>;
6
+ adaptNoInput: (handler: NoInputHandler) => (_payload: ToolExecutionPayload<Record<string, unknown>>) => Promise<CallToolResult>;
7
+ adaptWithDelta: <TInput extends Record<string, unknown>>(handler: DeltaHandler<TInput>) => ({ input }: ToolExecutionPayload<TInput>) => Promise<CallToolResult>;
8
+ adaptWrite: <TInput extends Record<string, unknown>>(handler: WriteHandler<TInput>) => ({ input }: ToolExecutionPayload<TInput>) => Promise<CallToolResult>;
9
+ };
10
+ export declare function createBudgetResolver(context: ToolContext): <TInput extends {
11
+ budget_id?: string | undefined;
12
+ }>() => DefaultArgumentResolver<TInput>;
@@ -0,0 +1,25 @@
1
+ import { BudgetResolver } from '../server/budgetResolver.js';
2
+ import { DefaultArgumentResolutionError } from '../server/toolRegistry.js';
3
+ export function createAdapters(context) {
4
+ const { ynabAPI, deltaFetcher, deltaCache, serverKnowledgeStore } = context;
5
+ return {
6
+ adapt: (handler) => async ({ input }) => handler(ynabAPI, input),
7
+ adaptNoInput: (handler) => async (_payload) => handler(ynabAPI),
8
+ adaptWithDelta: (handler) => async ({ input }) => handler(ynabAPI, deltaFetcher, input),
9
+ adaptWrite: (handler) => async ({ input }) => handler(ynabAPI, deltaCache, serverKnowledgeStore, input),
10
+ };
11
+ }
12
+ export function createBudgetResolver(context) {
13
+ return () => {
14
+ return ({ rawArguments }) => {
15
+ const provided = typeof rawArguments['budget_id'] === 'string' && rawArguments['budget_id'].length > 0
16
+ ? rawArguments['budget_id']
17
+ : undefined;
18
+ const result = BudgetResolver.resolveBudgetId(provided, context.getDefaultBudgetId());
19
+ if (typeof result === 'string') {
20
+ return { budget_id: result };
21
+ }
22
+ throw new DefaultArgumentResolutionError(result);
23
+ };
24
+ };
25
+ }
@@ -2,9 +2,11 @@ import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
2
2
  import * as ynab from 'ynab';
3
3
  import { z } from 'zod/v4';
4
4
  import type { DeltaFetcher } from './deltaFetcher.js';
5
+ import type { ToolFactory } from '../types/toolRegistration.js';
5
6
  export declare const GetBudgetSchema: z.ZodObject<{
6
7
  budget_id: z.ZodString;
7
8
  }, z.core.$strict>;
8
9
  export type GetBudgetParams = z.infer<typeof GetBudgetSchema>;
9
10
  export declare function handleListBudgets(ynabAPI: ynab.API, deltaFetcherOrParams?: DeltaFetcher | Record<string, unknown>, maybeParams?: Record<string, unknown>): Promise<CallToolResult>;
10
11
  export declare function handleGetBudget(ynabAPI: ynab.API, params: GetBudgetParams): Promise<CallToolResult>;
12
+ export declare const registerBudgetTools: ToolFactory;
@@ -2,6 +2,9 @@ import { z } from 'zod/v4';
2
2
  import { withToolErrorHandling } from '../types/index.js';
3
3
  import { responseFormatter } from '../server/responseFormatter.js';
4
4
  import { resolveDeltaFetcherArgs } from './deltaSupport.js';
5
+ import { createAdapters } from './adapters.js';
6
+ import { ToolAnnotationPresets } from './toolCategories.js';
7
+ import { emptyObjectSchema } from './schemas/common.js';
5
8
  export const GetBudgetSchema = z
6
9
  .object({
7
10
  budget_id: z.string().min(1, 'Budget ID is required'),
@@ -66,3 +69,30 @@ export async function handleGetBudget(ynabAPI, params) {
66
69
  };
67
70
  }, 'ynab:get_budget', 'getting budget details');
68
71
  }
72
+ export const registerBudgetTools = (registry, context) => {
73
+ const { adapt, adaptWithDelta } = createAdapters(context);
74
+ registry.register({
75
+ name: 'list_budgets',
76
+ description: "List all budgets associated with the user's account",
77
+ inputSchema: emptyObjectSchema,
78
+ handler: adaptWithDelta(handleListBudgets),
79
+ metadata: {
80
+ annotations: {
81
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
82
+ title: 'YNAB: List Budgets',
83
+ },
84
+ },
85
+ });
86
+ registry.register({
87
+ name: 'get_budget',
88
+ description: 'Get detailed information for a specific budget',
89
+ inputSchema: GetBudgetSchema,
90
+ handler: adapt(handleGetBudget),
91
+ metadata: {
92
+ annotations: {
93
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
94
+ title: 'YNAB: Get Budget Details',
95
+ },
96
+ },
97
+ });
98
+ };
@@ -4,6 +4,7 @@ import { z } from 'zod/v4';
4
4
  import type { DeltaFetcher } from './deltaFetcher.js';
5
5
  import type { DeltaCache } from '../server/deltaCache.js';
6
6
  import type { ServerKnowledgeStore } from '../server/serverKnowledgeStore.js';
7
+ import type { ToolFactory } from '../types/toolRegistration.js';
7
8
  export declare const ListCategoriesSchema: z.ZodObject<{
8
9
  budget_id: z.ZodString;
9
10
  }, z.core.$strict>;
@@ -25,3 +26,4 @@ export declare function handleListCategories(ynabAPI: ynab.API, params: ListCate
25
26
  export declare function handleGetCategory(ynabAPI: ynab.API, params: GetCategoryParams): Promise<CallToolResult>;
26
27
  export declare function handleUpdateCategory(ynabAPI: ynab.API, deltaCache: DeltaCache, knowledgeStore: ServerKnowledgeStore, params: UpdateCategoryParams): Promise<CallToolResult>;
27
28
  export declare function handleUpdateCategory(ynabAPI: ynab.API, params: UpdateCategoryParams): Promise<CallToolResult>;
29
+ export declare const registerCategoryTools: ToolFactory;
@@ -5,6 +5,8 @@ import { milliunitsToAmount } from '../utils/amountUtils.js';
5
5
  import { cacheManager, CACHE_TTLS, CacheManager } from '../server/cacheManager.js';
6
6
  import { CacheKeys } from '../server/cacheKeys.js';
7
7
  import { resolveDeltaFetcherArgs, resolveDeltaWriteArgs } from './deltaSupport.js';
8
+ import { createAdapters, createBudgetResolver } from './adapters.js';
9
+ import { ToolAnnotationPresets } from './toolCategories.js';
8
10
  export const ListCategoriesSchema = z
9
11
  .object({
10
12
  budget_id: z.string().min(1, 'Budget ID is required'),
@@ -199,6 +201,49 @@ export async function handleUpdateCategory(ynabAPI, deltaCacheOrParams, knowledg
199
201
  return handleCategoryError(error, 'Failed to update category');
200
202
  }
201
203
  }
204
+ export const registerCategoryTools = (registry, context) => {
205
+ const { adapt, adaptWithDelta, adaptWrite } = createAdapters(context);
206
+ const budgetResolver = createBudgetResolver(context);
207
+ registry.register({
208
+ name: 'list_categories',
209
+ description: 'List all categories for a specific budget',
210
+ inputSchema: ListCategoriesSchema,
211
+ handler: adaptWithDelta(handleListCategories),
212
+ defaultArgumentResolver: budgetResolver(),
213
+ metadata: {
214
+ annotations: {
215
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
216
+ title: 'YNAB: List Categories',
217
+ },
218
+ },
219
+ });
220
+ registry.register({
221
+ name: 'get_category',
222
+ description: 'Get detailed information for a specific category',
223
+ inputSchema: GetCategorySchema,
224
+ handler: adapt(handleGetCategory),
225
+ defaultArgumentResolver: budgetResolver(),
226
+ metadata: {
227
+ annotations: {
228
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
229
+ title: 'YNAB: Get Category Details',
230
+ },
231
+ },
232
+ });
233
+ registry.register({
234
+ name: 'update_category',
235
+ description: 'Update the budgeted amount for a category in the current month',
236
+ inputSchema: UpdateCategorySchema,
237
+ handler: adaptWrite(handleUpdateCategory),
238
+ defaultArgumentResolver: budgetResolver(),
239
+ metadata: {
240
+ annotations: {
241
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_UPDATE,
242
+ title: 'YNAB: Update Category Budget',
243
+ },
244
+ },
245
+ });
246
+ };
202
247
  function handleCategoryError(error, defaultMessage) {
203
248
  let errorMessage = defaultMessage;
204
249
  if (error instanceof Error) {
@@ -2,6 +2,7 @@ import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
2
2
  import * as ynab from 'ynab';
3
3
  import { z } from 'zod/v4';
4
4
  import type { DeltaFetcher } from './deltaFetcher.js';
5
+ import type { ToolFactory } from '../types/toolRegistration.js';
5
6
  export declare const GetMonthSchema: z.ZodObject<{
6
7
  budget_id: z.ZodString;
7
8
  month: z.ZodString;
@@ -14,3 +15,4 @@ export type ListMonthsParams = z.infer<typeof ListMonthsSchema>;
14
15
  export declare function handleGetMonth(ynabAPI: ynab.API, params: GetMonthParams): Promise<CallToolResult>;
15
16
  export declare function handleListMonths(ynabAPI: ynab.API, deltaFetcher: DeltaFetcher, params: ListMonthsParams): Promise<CallToolResult>;
16
17
  export declare function handleListMonths(ynabAPI: ynab.API, params: ListMonthsParams): Promise<CallToolResult>;
18
+ export declare const registerMonthTools: ToolFactory;
@@ -5,6 +5,8 @@ import { milliunitsToAmount } from '../utils/amountUtils.js';
5
5
  import { cacheManager, CACHE_TTLS, CacheManager } from '../server/cacheManager.js';
6
6
  import { CacheKeys } from '../server/cacheKeys.js';
7
7
  import { resolveDeltaFetcherArgs } from './deltaSupport.js';
8
+ import { createAdapters, createBudgetResolver } from './adapters.js';
9
+ import { ToolAnnotationPresets } from './toolCategories.js';
8
10
  export const GetMonthSchema = z
9
11
  .object({
10
12
  budget_id: z.string().min(1, 'Budget ID is required'),
@@ -106,3 +108,33 @@ export async function handleListMonths(ynabAPI, deltaFetcherOrParams, maybeParam
106
108
  };
107
109
  }, 'ynab:list_months', 'listing months');
108
110
  }
111
+ export const registerMonthTools = (registry, context) => {
112
+ const { adapt, adaptWithDelta } = createAdapters(context);
113
+ const budgetResolver = createBudgetResolver(context);
114
+ registry.register({
115
+ name: 'get_month',
116
+ description: 'Get budget data for a specific month',
117
+ inputSchema: GetMonthSchema,
118
+ handler: adapt(handleGetMonth),
119
+ defaultArgumentResolver: budgetResolver(),
120
+ metadata: {
121
+ annotations: {
122
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
123
+ title: 'YNAB: Get Month Details',
124
+ },
125
+ },
126
+ });
127
+ registry.register({
128
+ name: 'list_months',
129
+ description: 'List all months summary data for a budget',
130
+ inputSchema: ListMonthsSchema,
131
+ handler: adaptWithDelta(handleListMonths),
132
+ defaultArgumentResolver: budgetResolver(),
133
+ metadata: {
134
+ annotations: {
135
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
136
+ title: 'YNAB: List Months',
137
+ },
138
+ },
139
+ });
140
+ };
@@ -2,6 +2,7 @@ import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
2
2
  import * as ynab from 'ynab';
3
3
  import { z } from 'zod/v4';
4
4
  import type { DeltaFetcher } from './deltaFetcher.js';
5
+ import type { ToolFactory } from '../types/toolRegistration.js';
5
6
  export declare const ListPayeesSchema: z.ZodObject<{
6
7
  budget_id: z.ZodString;
7
8
  limit: z.ZodOptional<z.ZodNumber>;
@@ -15,3 +16,4 @@ export type GetPayeeParams = z.infer<typeof GetPayeeSchema>;
15
16
  export declare function handleListPayees(ynabAPI: ynab.API, deltaFetcher: DeltaFetcher, params: ListPayeesParams): Promise<CallToolResult>;
16
17
  export declare function handleListPayees(ynabAPI: ynab.API, params: ListPayeesParams): Promise<CallToolResult>;
17
18
  export declare function handleGetPayee(ynabAPI: ynab.API, params: GetPayeeParams): Promise<CallToolResult>;
19
+ export declare const registerPayeeTools: ToolFactory;
@@ -4,6 +4,8 @@ import { responseFormatter } from '../server/responseFormatter.js';
4
4
  import { cacheManager, CACHE_TTLS, CacheManager } from '../server/cacheManager.js';
5
5
  import { CacheKeys } from '../server/cacheKeys.js';
6
6
  import { resolveDeltaFetcherArgs } from './deltaSupport.js';
7
+ import { createAdapters, createBudgetResolver } from './adapters.js';
8
+ import { ToolAnnotationPresets } from './toolCategories.js';
7
9
  export const ListPayeesSchema = z
8
10
  .object({
9
11
  budget_id: z.string().min(1, 'Budget ID is required'),
@@ -81,3 +83,33 @@ export async function handleGetPayee(ynabAPI, params) {
81
83
  };
82
84
  }, 'ynab:get_payee', 'getting payee details');
83
85
  }
86
+ export const registerPayeeTools = (registry, context) => {
87
+ const { adapt, adaptWithDelta } = createAdapters(context);
88
+ const budgetResolver = createBudgetResolver(context);
89
+ registry.register({
90
+ name: 'list_payees',
91
+ description: 'List all payees for a specific budget',
92
+ inputSchema: ListPayeesSchema,
93
+ handler: adaptWithDelta(handleListPayees),
94
+ defaultArgumentResolver: budgetResolver(),
95
+ metadata: {
96
+ annotations: {
97
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
98
+ title: 'YNAB: List Payees',
99
+ },
100
+ },
101
+ });
102
+ registry.register({
103
+ name: 'get_payee',
104
+ description: 'Get detailed information for a specific payee',
105
+ inputSchema: GetPayeeSchema,
106
+ handler: adapt(handleGetPayee),
107
+ defaultArgumentResolver: budgetResolver(),
108
+ metadata: {
109
+ annotations: {
110
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
111
+ title: 'YNAB: Get Payee Details',
112
+ },
113
+ },
114
+ });
115
+ };
@@ -1,6 +1,7 @@
1
1
  import { z } from 'zod/v4';
2
2
  import type * as ynab from 'ynab';
3
3
  import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
4
+ import type { ToolFactory } from '../../types/toolRegistration.js';
4
5
  import type { DeltaFetcher } from '../deltaFetcher.js';
5
6
  export type * from './types.js';
6
7
  export { analyzeReconciliation } from './analyzer.js';
@@ -52,3 +53,4 @@ export declare const ReconcileAccountSchema: z.ZodObject<{
52
53
  export type ReconcileAccountRequest = z.infer<typeof ReconcileAccountSchema>;
53
54
  export declare function handleReconcileAccount(ynabAPI: ynab.API, deltaFetcher: DeltaFetcher, params: ReconcileAccountRequest): Promise<CallToolResult>;
54
55
  export declare function handleReconcileAccount(ynabAPI: ynab.API, params: ReconcileAccountRequest): Promise<CallToolResult>;
56
+ export declare const registerReconciliationTools: ToolFactory;
@@ -1,6 +1,9 @@
1
1
  import { promises as fs } from 'fs';
2
2
  import { z } from 'zod/v4';
3
3
  import { withToolErrorHandling } from '../../types/index.js';
4
+ import { createAdapters, createBudgetResolver } from '../adapters.js';
5
+ import { ToolAnnotationPresets } from '../toolCategories.js';
6
+ import { CompareTransactionsSchema, handleCompareTransactions, } from '../compareTransactions/index.js';
4
7
  import { analyzeReconciliation } from './analyzer.js';
5
8
  import { buildReconciliationPayload } from '../reconcileAdapter.js';
6
9
  import { executeReconciliation, } from './executor.js';
@@ -303,6 +306,36 @@ export async function handleReconcileAccount(ynabAPI, deltaFetcherOrParams, mayb
303
306
  };
304
307
  }, 'ynab:reconcile_account', 'analyzing account reconciliation');
305
308
  }
309
+ export const registerReconciliationTools = (registry, context) => {
310
+ const { adapt, adaptWithDelta } = createAdapters(context);
311
+ const budgetResolver = createBudgetResolver(context);
312
+ registry.register({
313
+ name: 'compare_transactions',
314
+ description: 'Compare bank transactions from CSV with YNAB transactions to find missing entries',
315
+ inputSchema: CompareTransactionsSchema,
316
+ handler: adapt(handleCompareTransactions),
317
+ defaultArgumentResolver: budgetResolver(),
318
+ metadata: {
319
+ annotations: {
320
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
321
+ title: 'YNAB: Compare Transactions',
322
+ },
323
+ },
324
+ });
325
+ registry.register({
326
+ name: 'reconcile_account',
327
+ description: '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).',
328
+ inputSchema: ReconcileAccountSchema,
329
+ handler: adaptWithDelta(handleReconcileAccount),
330
+ defaultArgumentResolver: budgetResolver(),
331
+ metadata: {
332
+ annotations: {
333
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_UPDATE,
334
+ title: 'YNAB: Reconcile Account',
335
+ },
336
+ },
337
+ });
338
+ };
306
339
  function mapCsvDateFormatToHint(format) {
307
340
  if (!format) {
308
341
  return undefined;
@@ -0,0 +1,3 @@
1
+ import { z } from 'zod/v4';
2
+ export declare const emptyObjectSchema: z.ZodObject<{}, z.core.$strict>;
3
+ export declare const looseObjectSchema: z.ZodObject<{}, z.core.$loose>;
@@ -0,0 +1,3 @@
1
+ import { z } from 'zod/v4';
2
+ export const emptyObjectSchema = z.object({}).strict();
3
+ export const looseObjectSchema = z.object({}).passthrough();
@@ -250,8 +250,8 @@ export declare const ExportTransactionsOutputSchema: z.ZodObject<{
250
250
  full_path: z.ZodString;
251
251
  export_directory: z.ZodString;
252
252
  export_mode: z.ZodEnum<{
253
- full: "full";
254
253
  minimal: "minimal";
254
+ full: "full";
255
255
  }>;
256
256
  minimal_fields: z.ZodNullable<z.ZodString>;
257
257
  filename_explanation: z.ZodString;
@@ -1,5 +1,5 @@
1
- export { GetUserOutputSchema, type GetUserOutput, ConvertAmountOutputSchema, type ConvertAmountOutput, GetDefaultBudgetOutputSchema, type GetDefaultBudgetOutput, SetDefaultBudgetOutputSchema, type SetDefaultBudgetOutput, ClearCacheOutputSchema, type ClearCacheOutput, SetOutputFormatOutputSchema, type SetOutputFormatOutput, DiagnosticInfoOutputSchema, type DiagnosticInfoOutput, GetBudgetOutputSchema, type GetBudgetOutput, } from './utilityOutputs.js';
2
- export { UserSchema, ConversionSchema, DateFormatSchema, CurrencyFormatSchema, BudgetDetailSchema, ServerInfoSchema, MemoryInfoSchema, EnvironmentInfoSchema, CacheInfoSchema, DeltaInfoSchema, } from './utilityOutputs.js';
1
+ export { GetUserOutputSchema, type GetUserOutput, GetDefaultBudgetOutputSchema, type GetDefaultBudgetOutput, SetDefaultBudgetOutputSchema, type SetDefaultBudgetOutput, ClearCacheOutputSchema, type ClearCacheOutput, SetOutputFormatOutputSchema, type SetOutputFormatOutput, DiagnosticInfoOutputSchema, type DiagnosticInfoOutput, GetBudgetOutputSchema, type GetBudgetOutput, } from './utilityOutputs.js';
2
+ export { UserSchema, DateFormatSchema, CurrencyFormatSchema, BudgetDetailSchema, ServerInfoSchema, MemoryInfoSchema, EnvironmentInfoSchema, CacheInfoSchema, DeltaInfoSchema, } from './utilityOutputs.js';
3
3
  export { ListBudgetsOutputSchema, type ListBudgetsOutput, BudgetSummarySchema, type BudgetSummary, } from './budgetOutputs.js';
4
4
  export { ListAccountsOutputSchema, type ListAccountsOutput, GetAccountOutputSchema, type GetAccountOutput, AccountSchema, type Account, } from './accountOutputs.js';
5
5
  export { ListTransactionsOutputSchema, type ListTransactionsOutput, GetTransactionOutputSchema, type GetTransactionOutput, TransactionSchema, type Transaction, TransactionPreviewSchema, type TransactionPreview, } from './transactionOutputs.js';
@@ -1,5 +1,5 @@
1
- export { GetUserOutputSchema, ConvertAmountOutputSchema, GetDefaultBudgetOutputSchema, SetDefaultBudgetOutputSchema, ClearCacheOutputSchema, SetOutputFormatOutputSchema, DiagnosticInfoOutputSchema, GetBudgetOutputSchema, } from './utilityOutputs.js';
2
- export { UserSchema, ConversionSchema, DateFormatSchema, CurrencyFormatSchema, BudgetDetailSchema, ServerInfoSchema, MemoryInfoSchema, EnvironmentInfoSchema, CacheInfoSchema, DeltaInfoSchema, } from './utilityOutputs.js';
1
+ export { GetUserOutputSchema, GetDefaultBudgetOutputSchema, SetDefaultBudgetOutputSchema, ClearCacheOutputSchema, SetOutputFormatOutputSchema, DiagnosticInfoOutputSchema, GetBudgetOutputSchema, } from './utilityOutputs.js';
2
+ export { UserSchema, DateFormatSchema, CurrencyFormatSchema, BudgetDetailSchema, ServerInfoSchema, MemoryInfoSchema, EnvironmentInfoSchema, CacheInfoSchema, DeltaInfoSchema, } from './utilityOutputs.js';
3
3
  export { ListBudgetsOutputSchema, BudgetSummarySchema, } from './budgetOutputs.js';
4
4
  export { ListAccountsOutputSchema, GetAccountOutputSchema, AccountSchema, } from './accountOutputs.js';
5
5
  export { ListTransactionsOutputSchema, GetTransactionOutputSchema, TransactionSchema, TransactionPreviewSchema, } from './transactionOutputs.js';
@@ -8,21 +8,6 @@ export declare const GetUserOutputSchema: z.ZodObject<{
8
8
  }, z.core.$strip>;
9
9
  }, z.core.$strip>;
10
10
  export type GetUserOutput = z.infer<typeof GetUserOutputSchema>;
11
- export declare const ConversionSchema: z.ZodObject<{
12
- original_amount: z.ZodNumber;
13
- converted_amount: z.ZodNumber;
14
- to_milliunits: z.ZodBoolean;
15
- description: z.ZodString;
16
- }, z.core.$strip>;
17
- export declare const ConvertAmountOutputSchema: z.ZodObject<{
18
- conversion: z.ZodObject<{
19
- original_amount: z.ZodNumber;
20
- converted_amount: z.ZodNumber;
21
- to_milliunits: z.ZodBoolean;
22
- description: z.ZodString;
23
- }, z.core.$strip>;
24
- }, z.core.$strip>;
25
- export type ConvertAmountOutput = z.infer<typeof ConvertAmountOutputSchema>;
26
11
  export declare const GetDefaultBudgetOutputSchema: z.ZodObject<{
27
12
  default_budget_id: z.ZodNullable<z.ZodString>;
28
13
  has_default: z.ZodBoolean;
@@ -6,15 +6,6 @@ export const UserSchema = z.object({
6
6
  export const GetUserOutputSchema = z.object({
7
7
  user: UserSchema,
8
8
  });
9
- export const ConversionSchema = z.object({
10
- original_amount: z.number(),
11
- converted_amount: z.number(),
12
- to_milliunits: z.boolean(),
13
- description: z.string(),
14
- });
15
- export const ConvertAmountOutputSchema = z.object({
16
- conversion: ConversionSchema,
17
- });
18
9
  export const GetDefaultBudgetOutputSchema = z.object({
19
10
  default_budget_id: z.string().nullable(),
20
11
  has_default: z.boolean(),
@@ -2,6 +2,7 @@ import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
2
2
  import * as ynab from 'ynab';
3
3
  import type { SaveTransactionsResponseData } from 'ynab/dist/models/SaveTransactionsResponseData.js';
4
4
  import { z } from 'zod/v4';
5
+ import type { ToolFactory } from '../types/toolRegistration.js';
5
6
  import type { DeltaFetcher } from './deltaFetcher.js';
6
7
  import type { DeltaCache } from '../server/deltaCache.js';
7
8
  import type { ServerKnowledgeStore } from '../server/serverKnowledgeStore.js';
@@ -298,4 +299,5 @@ export declare function handleCreateTransactions(ynabAPI: ynab.API, deltaCache:
298
299
  export declare function handleCreateTransactions(ynabAPI: ynab.API, params: CreateTransactionsParams): Promise<CallToolResult>;
299
300
  export declare function handleUpdateTransactions(ynabAPI: ynab.API, deltaCache: DeltaCache, knowledgeStore: ServerKnowledgeStore, params: UpdateTransactionsParams): Promise<CallToolResult>;
300
301
  export declare function handleUpdateTransactions(ynabAPI: ynab.API, params: UpdateTransactionsParams): Promise<CallToolResult>;
302
+ export declare const registerTransactionTools: ToolFactory;
301
303
  export {};
@@ -1,11 +1,14 @@
1
1
  import { z } from 'zod/v4';
2
2
  import { createHash } from 'crypto';
3
3
  import { ValidationError, withToolErrorHandling } from '../types/index.js';
4
+ import { createAdapters, createBudgetResolver } from './adapters.js';
5
+ import { ToolAnnotationPresets } from './toolCategories.js';
4
6
  import { responseFormatter } from '../server/responseFormatter.js';
5
7
  import { amountToMilliunits, milliunitsToAmount } from '../utils/amountUtils.js';
6
8
  import { cacheManager, CACHE_TTLS, CacheManager } from '../server/cacheManager.js';
7
9
  import { globalRequestLogger } from '../server/requestLogger.js';
8
10
  import { resolveDeltaFetcherArgs, resolveDeltaWriteArgs } from './deltaSupport.js';
11
+ import { handleExportTransactions, ExportTransactionsSchema } from './exportTransactions.js';
9
12
  function ensureTransaction(transaction, errorMessage) {
10
13
  if (!transaction) {
11
14
  throw new Error(errorMessage);
@@ -1713,3 +1716,124 @@ function handleTransactionError(error, defaultMessage) {
1713
1716
  ],
1714
1717
  };
1715
1718
  }
1719
+ export const registerTransactionTools = (registry, context) => {
1720
+ const { adapt, adaptWithDelta, adaptWrite } = createAdapters(context);
1721
+ const budgetResolver = createBudgetResolver(context);
1722
+ registry.register({
1723
+ name: 'list_transactions',
1724
+ description: 'List transactions for a budget with optional filtering',
1725
+ inputSchema: ListTransactionsSchema,
1726
+ handler: adaptWithDelta(handleListTransactions),
1727
+ defaultArgumentResolver: budgetResolver(),
1728
+ metadata: {
1729
+ annotations: {
1730
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
1731
+ title: 'YNAB: List Transactions',
1732
+ },
1733
+ },
1734
+ });
1735
+ registry.register({
1736
+ name: 'export_transactions',
1737
+ description: 'Export all transactions to a JSON file with descriptive filename',
1738
+ inputSchema: ExportTransactionsSchema,
1739
+ handler: adapt(handleExportTransactions),
1740
+ defaultArgumentResolver: budgetResolver(),
1741
+ metadata: {
1742
+ annotations: {
1743
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
1744
+ title: 'YNAB: Export Transactions',
1745
+ },
1746
+ },
1747
+ });
1748
+ registry.register({
1749
+ name: 'get_transaction',
1750
+ description: 'Get detailed information for a specific transaction',
1751
+ inputSchema: GetTransactionSchema,
1752
+ handler: adapt(handleGetTransaction),
1753
+ defaultArgumentResolver: budgetResolver(),
1754
+ metadata: {
1755
+ annotations: {
1756
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
1757
+ title: 'YNAB: Get Transaction Details',
1758
+ },
1759
+ },
1760
+ });
1761
+ registry.register({
1762
+ name: 'create_transaction',
1763
+ description: 'Create a new transaction in the specified budget and account',
1764
+ inputSchema: CreateTransactionSchema,
1765
+ handler: adaptWrite(handleCreateTransaction),
1766
+ defaultArgumentResolver: budgetResolver(),
1767
+ metadata: {
1768
+ annotations: {
1769
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_CREATE,
1770
+ title: 'YNAB: Create Transaction',
1771
+ },
1772
+ },
1773
+ });
1774
+ registry.register({
1775
+ name: 'create_transactions',
1776
+ description: 'Create multiple transactions in a single batch (1-100 items) with duplicate detection, dry-run validation, and automatic response size management with correlation metadata.',
1777
+ inputSchema: CreateTransactionsSchema,
1778
+ handler: adaptWrite(handleCreateTransactions),
1779
+ defaultArgumentResolver: budgetResolver(),
1780
+ metadata: {
1781
+ annotations: {
1782
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_CREATE,
1783
+ title: 'YNAB: Create Multiple Transactions',
1784
+ },
1785
+ },
1786
+ });
1787
+ registry.register({
1788
+ name: 'create_receipt_split_transaction',
1789
+ description: 'Create a split transaction from receipt items with proportional tax allocation',
1790
+ inputSchema: CreateReceiptSplitTransactionSchema,
1791
+ handler: adaptWrite(handleCreateReceiptSplitTransaction),
1792
+ defaultArgumentResolver: budgetResolver(),
1793
+ metadata: {
1794
+ annotations: {
1795
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_CREATE,
1796
+ title: 'YNAB: Create Split Transaction from Receipt',
1797
+ },
1798
+ },
1799
+ });
1800
+ registry.register({
1801
+ name: 'update_transaction',
1802
+ description: 'Update an existing transaction',
1803
+ inputSchema: UpdateTransactionSchema,
1804
+ handler: adaptWrite(handleUpdateTransaction),
1805
+ defaultArgumentResolver: budgetResolver(),
1806
+ metadata: {
1807
+ annotations: {
1808
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_UPDATE,
1809
+ title: 'YNAB: Update Transaction',
1810
+ },
1811
+ },
1812
+ });
1813
+ registry.register({
1814
+ name: 'update_transactions',
1815
+ description: '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.',
1816
+ inputSchema: UpdateTransactionsSchema,
1817
+ handler: adaptWrite(handleUpdateTransactions),
1818
+ defaultArgumentResolver: budgetResolver(),
1819
+ metadata: {
1820
+ annotations: {
1821
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_UPDATE,
1822
+ title: 'YNAB: Update Multiple Transactions',
1823
+ },
1824
+ },
1825
+ });
1826
+ registry.register({
1827
+ name: 'delete_transaction',
1828
+ description: 'Delete a transaction from the specified budget',
1829
+ inputSchema: DeleteTransactionSchema,
1830
+ handler: adaptWrite(handleDeleteTransaction),
1831
+ defaultArgumentResolver: budgetResolver(),
1832
+ metadata: {
1833
+ annotations: {
1834
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_DELETE,
1835
+ title: 'YNAB: Delete Transaction',
1836
+ },
1837
+ },
1838
+ });
1839
+ };
@@ -1,10 +1,5 @@
1
1
  import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
2
2
  import * as ynab from 'ynab';
3
- import { z } from 'zod/v4';
4
- export declare const ConvertAmountSchema: z.ZodObject<{
5
- amount: z.ZodNumber;
6
- to_milliunits: z.ZodBoolean;
7
- }, z.core.$strict>;
8
- export type ConvertAmountParams = z.infer<typeof ConvertAmountSchema>;
3
+ import type { ToolFactory } from '../types/toolRegistration.js';
9
4
  export declare function handleGetUser(ynabAPI: ynab.API): Promise<CallToolResult>;
10
- export declare function handleConvertAmount(params: ConvertAmountParams): Promise<CallToolResult>;
5
+ export declare const registerUtilityTools: ToolFactory;