@dizzlkheinz/ynab-mcpb 0.18.3 → 0.19.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 (346) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/CLAUDE.md +87 -8
  3. package/bin/ynab-mcp-server.cjs +2 -2
  4. package/bin/ynab-mcp-server.js +3 -3
  5. package/biome.json +39 -0
  6. package/dist/bundle/index.cjs +67 -67
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.js +27 -27
  9. package/dist/server/YNABMCPServer.d.ts +3 -4
  10. package/dist/server/YNABMCPServer.js +111 -116
  11. package/dist/server/budgetResolver.d.ts +6 -5
  12. package/dist/server/budgetResolver.js +46 -36
  13. package/dist/server/cacheKeys.js +6 -6
  14. package/dist/server/cacheManager.js +14 -11
  15. package/dist/server/completions.d.ts +2 -2
  16. package/dist/server/completions.js +20 -15
  17. package/dist/server/config.d.ts +10 -5
  18. package/dist/server/config.js +24 -7
  19. package/dist/server/deltaCache.d.ts +2 -2
  20. package/dist/server/deltaCache.js +22 -16
  21. package/dist/server/deltaCache.merge.d.ts +2 -2
  22. package/dist/server/diagnostics.d.ts +4 -4
  23. package/dist/server/diagnostics.js +38 -32
  24. package/dist/server/errorHandler.d.ts +5 -12
  25. package/dist/server/errorHandler.js +219 -217
  26. package/dist/server/prompts.d.ts +2 -2
  27. package/dist/server/prompts.js +45 -45
  28. package/dist/server/rateLimiter.js +4 -4
  29. package/dist/server/requestLogger.d.ts +1 -1
  30. package/dist/server/requestLogger.js +40 -35
  31. package/dist/server/resources.d.ts +3 -3
  32. package/dist/server/resources.js +55 -52
  33. package/dist/server/responseFormatter.js +6 -6
  34. package/dist/server/securityMiddleware.d.ts +2 -2
  35. package/dist/server/securityMiddleware.js +22 -20
  36. package/dist/server/serverKnowledgeStore.js +1 -1
  37. package/dist/server/toolRegistry.d.ts +3 -3
  38. package/dist/server/toolRegistry.js +47 -40
  39. package/dist/tools/__tests__/deltaTestUtils.d.ts +3 -3
  40. package/dist/tools/__tests__/deltaTestUtils.js +2 -2
  41. package/dist/tools/accountTools.d.ts +9 -8
  42. package/dist/tools/accountTools.js +47 -47
  43. package/dist/tools/adapters.d.ts +13 -8
  44. package/dist/tools/adapters.js +21 -11
  45. package/dist/tools/budgetTools.d.ts +8 -7
  46. package/dist/tools/budgetTools.js +22 -22
  47. package/dist/tools/categoryTools.d.ts +9 -8
  48. package/dist/tools/categoryTools.js +68 -59
  49. package/dist/tools/compareTransactions/formatter.d.ts +3 -3
  50. package/dist/tools/compareTransactions/formatter.js +9 -9
  51. package/dist/tools/compareTransactions/index.d.ts +6 -6
  52. package/dist/tools/compareTransactions/index.js +58 -43
  53. package/dist/tools/compareTransactions/matcher.d.ts +1 -1
  54. package/dist/tools/compareTransactions/matcher.js +28 -15
  55. package/dist/tools/compareTransactions/parser.d.ts +2 -2
  56. package/dist/tools/compareTransactions/parser.js +144 -138
  57. package/dist/tools/compareTransactions/types.d.ts +4 -4
  58. package/dist/tools/compareTransactions.d.ts +1 -1
  59. package/dist/tools/compareTransactions.js +1 -1
  60. package/dist/tools/deltaFetcher.d.ts +2 -2
  61. package/dist/tools/deltaFetcher.js +16 -15
  62. package/dist/tools/deltaSupport.d.ts +4 -4
  63. package/dist/tools/deltaSupport.js +35 -41
  64. package/dist/tools/exportTransactions.d.ts +5 -4
  65. package/dist/tools/exportTransactions.js +61 -59
  66. package/dist/tools/monthTools.d.ts +7 -6
  67. package/dist/tools/monthTools.js +31 -29
  68. package/dist/tools/payeeTools.d.ts +7 -6
  69. package/dist/tools/payeeTools.js +28 -28
  70. package/dist/tools/reconcileAdapter.d.ts +2 -2
  71. package/dist/tools/reconcileAdapter.js +21 -11
  72. package/dist/tools/reconciliation/analyzer.d.ts +4 -4
  73. package/dist/tools/reconciliation/analyzer.js +136 -57
  74. package/dist/tools/reconciliation/csvParser.d.ts +3 -3
  75. package/dist/tools/reconciliation/csvParser.js +128 -104
  76. package/dist/tools/reconciliation/executor.d.ts +4 -4
  77. package/dist/tools/reconciliation/executor.js +148 -109
  78. package/dist/tools/reconciliation/index.d.ts +10 -10
  79. package/dist/tools/reconciliation/index.js +96 -83
  80. package/dist/tools/reconciliation/matcher.d.ts +3 -3
  81. package/dist/tools/reconciliation/matcher.js +17 -16
  82. package/dist/tools/reconciliation/payeeNormalizer.js +19 -8
  83. package/dist/tools/reconciliation/recommendationEngine.d.ts +1 -1
  84. package/dist/tools/reconciliation/recommendationEngine.js +40 -40
  85. package/dist/tools/reconciliation/reportFormatter.d.ts +2 -2
  86. package/dist/tools/reconciliation/reportFormatter.js +79 -54
  87. package/dist/tools/reconciliation/signDetector.d.ts +1 -1
  88. package/dist/tools/reconciliation/types.d.ts +19 -16
  89. package/dist/tools/reconciliation/ynabAdapter.d.ts +2 -2
  90. package/dist/tools/schemas/common.d.ts +1 -1
  91. package/dist/tools/schemas/common.js +1 -1
  92. package/dist/tools/schemas/outputs/accountOutputs.d.ts +1 -1
  93. package/dist/tools/schemas/outputs/accountOutputs.js +24 -18
  94. package/dist/tools/schemas/outputs/budgetOutputs.d.ts +1 -1
  95. package/dist/tools/schemas/outputs/budgetOutputs.js +14 -11
  96. package/dist/tools/schemas/outputs/categoryOutputs.d.ts +1 -1
  97. package/dist/tools/schemas/outputs/categoryOutputs.js +49 -29
  98. package/dist/tools/schemas/outputs/comparisonOutputs.d.ts +1 -1
  99. package/dist/tools/schemas/outputs/comparisonOutputs.js +12 -12
  100. package/dist/tools/schemas/outputs/index.d.ts +14 -14
  101. package/dist/tools/schemas/outputs/index.js +14 -14
  102. package/dist/tools/schemas/outputs/monthOutputs.d.ts +1 -1
  103. package/dist/tools/schemas/outputs/monthOutputs.js +56 -41
  104. package/dist/tools/schemas/outputs/payeeOutputs.d.ts +1 -1
  105. package/dist/tools/schemas/outputs/payeeOutputs.js +10 -10
  106. package/dist/tools/schemas/outputs/reconciliationOutputs.d.ts +2 -2
  107. package/dist/tools/schemas/outputs/reconciliationOutputs.js +45 -45
  108. package/dist/tools/schemas/outputs/transactionMutationOutputs.d.ts +1 -1
  109. package/dist/tools/schemas/outputs/transactionMutationOutputs.js +28 -22
  110. package/dist/tools/schemas/outputs/transactionOutputs.d.ts +1 -1
  111. package/dist/tools/schemas/outputs/transactionOutputs.js +43 -35
  112. package/dist/tools/schemas/outputs/utilityOutputs.d.ts +1 -1
  113. package/dist/tools/schemas/outputs/utilityOutputs.js +5 -3
  114. package/dist/tools/schemas/shared/commonOutputs.d.ts +1 -1
  115. package/dist/tools/schemas/shared/commonOutputs.js +15 -9
  116. package/dist/tools/transactionReadTools.d.ts +11 -0
  117. package/dist/tools/transactionReadTools.js +202 -0
  118. package/dist/tools/transactionSchemas.d.ts +309 -0
  119. package/dist/tools/transactionSchemas.js +235 -0
  120. package/dist/tools/transactionTools.d.ts +6 -302
  121. package/dist/tools/transactionTools.js +7 -2054
  122. package/dist/tools/transactionUtils.d.ts +31 -0
  123. package/dist/tools/transactionUtils.js +364 -0
  124. package/dist/tools/transactionWriteTools.d.ts +20 -0
  125. package/dist/tools/transactionWriteTools.js +1342 -0
  126. package/dist/tools/utilityTools.d.ts +5 -4
  127. package/dist/tools/utilityTools.js +11 -11
  128. package/dist/types/index.d.ts +7 -7
  129. package/dist/types/index.js +6 -6
  130. package/dist/types/reconciliation.d.ts +1 -1
  131. package/dist/types/toolRegistration.d.ts +14 -12
  132. package/dist/utils/amountUtils.js +1 -1
  133. package/dist/utils/dateUtils.js +4 -4
  134. package/dist/utils/errors.d.ts +3 -3
  135. package/dist/utils/errors.js +4 -4
  136. package/dist/utils/money.d.ts +2 -2
  137. package/dist/utils/money.js +8 -8
  138. package/dist/utils/validationError.d.ts +1 -1
  139. package/dist/utils/validationError.js +1 -1
  140. package/docs/assets/examples/reconciliation-with-recommendations.json +66 -66
  141. package/docs/assets/schemas/reconciliation-v2.json +360 -336
  142. package/docs/plans/2025-12-25-transaction-tools-refactor-design.md +211 -0
  143. package/docs/plans/2025-12-25-transaction-tools-refactor.md +905 -0
  144. package/esbuild.config.mjs +53 -50
  145. package/meta.json +12548 -12548
  146. package/package.json +98 -109
  147. package/scripts/analyze-bundle.mjs +33 -30
  148. package/scripts/create-pr-description.js +169 -120
  149. package/scripts/run-all-tests.js +205 -0
  150. package/scripts/run-domain-integration-tests.js +28 -18
  151. package/scripts/run-generate-mcpb.js +19 -17
  152. package/scripts/run-throttled-integration-tests.js +92 -83
  153. package/scripts/test-delta-params.mjs +149 -120
  154. package/scripts/test-recommendations.ts +36 -32
  155. package/scripts/tmpTransaction.ts +80 -43
  156. package/scripts/validate-env.js +98 -91
  157. package/scripts/verify-build.js +78 -76
  158. package/src/__tests__/comprehensive.integration.test.ts +1281 -1154
  159. package/src/__tests__/performance.test.ts +723 -671
  160. package/src/__tests__/setup.ts +442 -395
  161. package/src/__tests__/smoke.e2e.test.ts +41 -39
  162. package/src/__tests__/testRunner.ts +314 -295
  163. package/src/__tests__/testUtils.ts +456 -364
  164. package/src/__tests__/tools/reconciliation/csvParser.integration.test.ts +109 -107
  165. package/src/__tests__/tools/reconciliation/real-world.integration.test.ts +41 -41
  166. package/src/index.ts +68 -59
  167. package/src/server/CLAUDE.md +480 -0
  168. package/src/server/YNABMCPServer.ts +821 -794
  169. package/src/server/__tests__/YNABMCPServer.integration.test.ts +929 -893
  170. package/src/server/__tests__/YNABMCPServer.test.ts +903 -899
  171. package/src/server/__tests__/budgetResolver.test.ts +466 -423
  172. package/src/server/__tests__/cacheManager.test.ts +891 -874
  173. package/src/server/__tests__/completions.integration.test.ts +115 -106
  174. package/src/server/__tests__/completions.test.ts +334 -313
  175. package/src/server/__tests__/config.test.ts +98 -86
  176. package/src/server/__tests__/deltaCache.merge.test.ts +774 -703
  177. package/src/server/__tests__/deltaCache.swr.test.ts +198 -153
  178. package/src/server/__tests__/deltaCache.test.ts +946 -759
  179. package/src/server/__tests__/diagnostics.test.ts +825 -792
  180. package/src/server/__tests__/errorHandler.integration.test.ts +512 -462
  181. package/src/server/__tests__/errorHandler.test.ts +402 -397
  182. package/src/server/__tests__/prompts.test.ts +424 -347
  183. package/src/server/__tests__/rateLimiter.test.ts +313 -309
  184. package/src/server/__tests__/requestLogger.test.ts +443 -403
  185. package/src/server/__tests__/resources.template.test.ts +196 -185
  186. package/src/server/__tests__/resources.test.ts +294 -288
  187. package/src/server/__tests__/security.integration.test.ts +487 -421
  188. package/src/server/__tests__/securityMiddleware.test.ts +519 -444
  189. package/src/server/__tests__/server-startup.integration.test.ts +509 -490
  190. package/src/server/__tests__/serverKnowledgeStore.test.ts +174 -173
  191. package/src/server/__tests__/toolRegistration.test.ts +239 -210
  192. package/src/server/__tests__/toolRegistry.test.ts +907 -845
  193. package/src/server/budgetResolver.ts +221 -181
  194. package/src/server/cacheKeys.ts +6 -6
  195. package/src/server/cacheManager.ts +498 -484
  196. package/src/server/completions.ts +267 -243
  197. package/src/server/config.ts +35 -14
  198. package/src/server/deltaCache.merge.ts +146 -128
  199. package/src/server/deltaCache.ts +352 -309
  200. package/src/server/diagnostics.ts +257 -242
  201. package/src/server/errorHandler.ts +747 -744
  202. package/src/server/prompts.ts +181 -176
  203. package/src/server/rateLimiter.ts +131 -129
  204. package/src/server/requestLogger.ts +350 -322
  205. package/src/server/resources.ts +442 -374
  206. package/src/server/responseFormatter.ts +41 -37
  207. package/src/server/securityMiddleware.ts +223 -205
  208. package/src/server/serverKnowledgeStore.ts +67 -67
  209. package/src/server/toolRegistry.ts +508 -474
  210. package/src/tools/CLAUDE.md +604 -0
  211. package/src/tools/__tests__/accountTools.delta.integration.test.ts +128 -111
  212. package/src/tools/__tests__/accountTools.integration.test.ts +129 -111
  213. package/src/tools/__tests__/accountTools.test.ts +685 -638
  214. package/src/tools/__tests__/adapters.test.ts +142 -108
  215. package/src/tools/__tests__/budgetTools.delta.integration.test.ts +73 -73
  216. package/src/tools/__tests__/budgetTools.integration.test.ts +132 -124
  217. package/src/tools/__tests__/budgetTools.test.ts +442 -413
  218. package/src/tools/__tests__/categoryTools.delta.integration.test.ts +76 -68
  219. package/src/tools/__tests__/categoryTools.integration.test.ts +314 -288
  220. package/src/tools/__tests__/categoryTools.test.ts +656 -625
  221. package/src/tools/__tests__/compareTransactions/formatter.test.ts +535 -462
  222. package/src/tools/__tests__/compareTransactions/index.test.ts +378 -358
  223. package/src/tools/__tests__/compareTransactions/matcher.test.ts +497 -398
  224. package/src/tools/__tests__/compareTransactions/parser.test.ts +765 -747
  225. package/src/tools/__tests__/compareTransactions.test.ts +352 -332
  226. package/src/tools/__tests__/compareTransactions.window.test.ts +150 -146
  227. package/src/tools/__tests__/deltaFetcher.scheduled.integration.test.ts +69 -65
  228. package/src/tools/__tests__/deltaFetcher.test.ts +325 -265
  229. package/src/tools/__tests__/deltaSupport.test.ts +211 -184
  230. package/src/tools/__tests__/deltaTestUtils.ts +37 -33
  231. package/src/tools/__tests__/exportTransactions.test.ts +205 -200
  232. package/src/tools/__tests__/monthTools.delta.integration.test.ts +68 -68
  233. package/src/tools/__tests__/monthTools.integration.test.ts +178 -166
  234. package/src/tools/__tests__/monthTools.test.ts +561 -512
  235. package/src/tools/__tests__/payeeTools.delta.integration.test.ts +68 -68
  236. package/src/tools/__tests__/payeeTools.integration.test.ts +158 -142
  237. package/src/tools/__tests__/payeeTools.test.ts +486 -434
  238. package/src/tools/__tests__/transactionSchemas.test.ts +1204 -0
  239. package/src/tools/__tests__/transactionTools.integration.test.ts +875 -825
  240. package/src/tools/__tests__/transactionTools.test.ts +4923 -4366
  241. package/src/tools/__tests__/transactionUtils.test.ts +1016 -0
  242. package/src/tools/__tests__/utilityTools.integration.test.ts +32 -32
  243. package/src/tools/__tests__/utilityTools.test.ts +68 -58
  244. package/src/tools/accountTools.ts +293 -271
  245. package/src/tools/adapters.ts +120 -63
  246. package/src/tools/budgetTools.ts +121 -116
  247. package/src/tools/categoryTools.ts +379 -339
  248. package/src/tools/compareTransactions/formatter.ts +131 -119
  249. package/src/tools/compareTransactions/index.ts +249 -214
  250. package/src/tools/compareTransactions/matcher.ts +259 -209
  251. package/src/tools/compareTransactions/parser.ts +517 -487
  252. package/src/tools/compareTransactions/types.ts +38 -38
  253. package/src/tools/compareTransactions.ts +1 -1
  254. package/src/tools/deltaFetcher.ts +281 -260
  255. package/src/tools/deltaSupport.ts +264 -259
  256. package/src/tools/exportTransactions.ts +230 -218
  257. package/src/tools/monthTools.ts +180 -165
  258. package/src/tools/payeeTools.ts +152 -140
  259. package/src/tools/reconcileAdapter.ts +297 -246
  260. package/src/tools/reconciliation/CLAUDE.md +506 -0
  261. package/src/tools/reconciliation/__tests__/adapter.causes.test.ts +135 -112
  262. package/src/tools/reconciliation/__tests__/adapter.test.ts +249 -227
  263. package/src/tools/reconciliation/__tests__/analyzer.test.ts +408 -335
  264. package/src/tools/reconciliation/__tests__/csvParser.test.ts +71 -69
  265. package/src/tools/reconciliation/__tests__/executor.integration.test.ts +348 -323
  266. package/src/tools/reconciliation/__tests__/executor.progress.test.ts +503 -457
  267. package/src/tools/reconciliation/__tests__/executor.test.ts +898 -831
  268. package/src/tools/reconciliation/__tests__/matcher.test.ts +667 -663
  269. package/src/tools/reconciliation/__tests__/payeeNormalizer.test.ts +296 -276
  270. package/src/tools/reconciliation/__tests__/recommendationEngine.integration.test.ts +692 -624
  271. package/src/tools/reconciliation/__tests__/recommendationEngine.test.ts +1008 -986
  272. package/src/tools/reconciliation/__tests__/reconciliation.delta.integration.test.ts +187 -146
  273. package/src/tools/reconciliation/__tests__/reportFormatter.test.ts +583 -530
  274. package/src/tools/reconciliation/__tests__/scenarios/adapterCurrency.scenario.test.ts +75 -71
  275. package/src/tools/reconciliation/__tests__/scenarios/extremes.scenario.test.ts +70 -58
  276. package/src/tools/reconciliation/__tests__/scenarios/repeatAmount.scenario.test.ts +102 -88
  277. package/src/tools/reconciliation/__tests__/schemaUrl.test.ts +58 -43
  278. package/src/tools/reconciliation/__tests__/signDetector.test.ts +209 -206
  279. package/src/tools/reconciliation/__tests__/ynabAdapter.test.ts +66 -60
  280. package/src/tools/reconciliation/analyzer.ts +582 -406
  281. package/src/tools/reconciliation/csvParser.ts +656 -609
  282. package/src/tools/reconciliation/executor.ts +1290 -1128
  283. package/src/tools/reconciliation/index.ts +580 -528
  284. package/src/tools/reconciliation/matcher.ts +256 -240
  285. package/src/tools/reconciliation/payeeNormalizer.ts +92 -78
  286. package/src/tools/reconciliation/recommendationEngine.ts +357 -345
  287. package/src/tools/reconciliation/reportFormatter.ts +349 -276
  288. package/src/tools/reconciliation/signDetector.ts +89 -83
  289. package/src/tools/reconciliation/types.ts +164 -153
  290. package/src/tools/reconciliation/ynabAdapter.ts +17 -15
  291. package/src/tools/schemas/CLAUDE.md +546 -0
  292. package/src/tools/schemas/common.ts +1 -1
  293. package/src/tools/schemas/outputs/__tests__/accountOutputs.test.ts +410 -409
  294. package/src/tools/schemas/outputs/__tests__/budgetOutputs.test.ts +305 -299
  295. package/src/tools/schemas/outputs/__tests__/categoryOutputs.test.ts +431 -430
  296. package/src/tools/schemas/outputs/__tests__/comparisonOutputs.test.ts +510 -495
  297. package/src/tools/schemas/outputs/__tests__/dateValidation.test.ts +179 -153
  298. package/src/tools/schemas/outputs/__tests__/discrepancyDirection.test.ts +293 -254
  299. package/src/tools/schemas/outputs/__tests__/monthOutputs.test.ts +457 -457
  300. package/src/tools/schemas/outputs/__tests__/payeeOutputs.test.ts +362 -356
  301. package/src/tools/schemas/outputs/__tests__/reconciliationOutputs.test.ts +402 -399
  302. package/src/tools/schemas/outputs/__tests__/transactionMutationSchemas.test.ts +225 -211
  303. package/src/tools/schemas/outputs/__tests__/transactionOutputs.test.ts +457 -454
  304. package/src/tools/schemas/outputs/__tests__/utilityOutputs.test.ts +316 -315
  305. package/src/tools/schemas/outputs/accountOutputs.ts +40 -34
  306. package/src/tools/schemas/outputs/budgetOutputs.ts +24 -19
  307. package/src/tools/schemas/outputs/categoryOutputs.ts +76 -56
  308. package/src/tools/schemas/outputs/comparisonOutputs.ts +192 -169
  309. package/src/tools/schemas/outputs/index.ts +163 -163
  310. package/src/tools/schemas/outputs/monthOutputs.ts +95 -80
  311. package/src/tools/schemas/outputs/payeeOutputs.ts +18 -18
  312. package/src/tools/schemas/outputs/reconciliationOutputs.ts +386 -373
  313. package/src/tools/schemas/outputs/transactionMutationOutputs.ts +259 -231
  314. package/src/tools/schemas/outputs/transactionOutputs.ts +81 -71
  315. package/src/tools/schemas/outputs/utilityOutputs.ts +90 -84
  316. package/src/tools/schemas/shared/commonOutputs.ts +27 -19
  317. package/src/tools/toolCategories.ts +114 -114
  318. package/src/tools/transactionReadTools.ts +327 -0
  319. package/src/tools/transactionSchemas.ts +484 -0
  320. package/src/tools/transactionTools.ts +107 -2990
  321. package/src/tools/transactionUtils.ts +621 -0
  322. package/src/tools/transactionWriteTools.ts +2110 -0
  323. package/src/tools/utilityTools.ts +46 -41
  324. package/src/types/CLAUDE.md +477 -0
  325. package/src/types/__tests__/index.test.ts +51 -51
  326. package/src/types/index.ts +43 -39
  327. package/src/types/integration-tests.d.ts +26 -26
  328. package/src/types/reconciliation.ts +29 -29
  329. package/src/types/toolAnnotations.ts +30 -30
  330. package/src/types/toolRegistration.ts +43 -32
  331. package/src/utils/CLAUDE.md +508 -0
  332. package/src/utils/__tests__/dateUtils.test.ts +174 -168
  333. package/src/utils/__tests__/money.test.ts +193 -187
  334. package/src/utils/amountUtils.ts +5 -5
  335. package/src/utils/baseError.ts +5 -5
  336. package/src/utils/dateUtils.ts +29 -26
  337. package/src/utils/errors.ts +14 -14
  338. package/src/utils/money.ts +66 -52
  339. package/src/utils/validationError.ts +1 -1
  340. package/tsconfig.json +29 -29
  341. package/tsconfig.prod.json +16 -16
  342. package/vitest-reporters/split-json-reporter.ts +247 -204
  343. package/vitest.config.ts +99 -95
  344. package/.prettierignore +0 -10
  345. package/.prettierrc.json +0 -10
  346. package/eslint.config.js +0 -49
@@ -0,0 +1,604 @@
1
+ # Tools - YNAB MCP Server
2
+
3
+ This directory contains all YNAB operations exposed via MCP tools, organized by domain (budget, account, transaction, category, payee, month, utility, reconciliation).
4
+
5
+ ## Purpose & Responsibilities
6
+
7
+ The `src/tools/` directory implements:
8
+
9
+ 1. **YNAB Operations** - CRUD operations for budgets, accounts, transactions, categories, payees
10
+ 2. **Tool Registration** - Domain-specific factory functions that register tools with the ToolRegistry
11
+ 3. **Input Validation** - Zod schemas for type-safe input validation
12
+ 4. **Adapter Pattern** - Consistent handler wrapping with dependency injection
13
+ 5. **Special Operations** - Transaction comparison, export, receipt itemization, reconciliation
14
+
15
+ ## Directory Structure
16
+
17
+ ```
18
+ src/tools/
19
+ ├── budgetTools.ts # Budget listing and retrieval
20
+ ├── accountTools.ts # Account management (list, get, create)
21
+ ├── transactionTools.ts # Transaction CRUD operations (2,274 lines)
22
+ ├── transactionSchemas.ts # Transaction Zod schemas (453 lines, v0.18.4)
23
+ ├── transactionUtils.ts # Transaction utilities (536 lines, v0.18.4)
24
+ ├── categoryTools.ts # Category management (list, get, update)
25
+ ├── payeeTools.ts # Payee listing and retrieval
26
+ ├── monthTools.ts # Monthly budget data (get, list)
27
+ ├── utilityTools.ts # User info and amount conversion
28
+ ├── adapters.ts # Tool adapter implementations
29
+ ├── toolCategories.ts # Tool categorization and annotations
30
+ ├── compareTransactions.ts # CSV comparison tool entry point
31
+ ├── exportTransactions.ts # Transaction export to JSON files
32
+ ├── reconcileAdapter.ts # Legacy adapter for reconciliation tool
33
+ ├── deltaFetcher.ts # Delta request utilities
34
+ ├── deltaSupport.ts # Delta request support utilities
35
+ ├── compareTransactions/ # CSV comparison modular components
36
+ │ ├── parser.ts # CSV parsing
37
+ │ ├── matcher.ts # Transaction matching
38
+ │ └── formatter.ts # Report formatting
39
+ ├── reconciliation/ # Comprehensive reconciliation system (v2)
40
+ │ ├── csvParser.ts # CSV parsing with bank presets
41
+ │ ├── matcher.ts # Fuzzy matching engine
42
+ │ ├── analyzer.ts # Transaction analysis
43
+ │ ├── executor.ts # Bulk transaction operations
44
+ │ ├── recommendationEngine.ts # Smart reconciliation recommendations
45
+ │ ├── reportFormatter.ts # Human-readable reports
46
+ │ ├── signDetector.ts # Auto-detection of debit/credit signs
47
+ │ ├── payeeNormalizer.ts # Payee name normalization
48
+ │ └── ynabAdapter.ts # YNAB API integration layer
49
+ └── schemas/ # Zod schemas for input/output validation
50
+ ├── common.ts # Shared schemas (emptyObject, looseObject)
51
+ └── outputs/ # Output validation schemas (11 files)
52
+ ```
53
+
54
+ ## Key Patterns & Conventions
55
+
56
+ ### 1. Tool Registration Pattern
57
+
58
+ All tools use domain-specific factory functions that register with ToolRegistry:
59
+
60
+ ```typescript
61
+ // In budgetTools.ts
62
+ export function registerBudgetTools(
63
+ registry: ToolRegistry,
64
+ context: ToolContext
65
+ ): void {
66
+ registry.register({
67
+ name: 'list_budgets',
68
+ description: 'List all budgets',
69
+ inputSchema: emptyObjectSchema,
70
+ handler: adaptNoInput(handleListBudgets, context),
71
+ metadata: {
72
+ annotations: {
73
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
74
+ title: 'YNAB: List Budgets',
75
+ },
76
+ },
77
+ });
78
+ }
79
+ ```
80
+
81
+ **Why Critical**: Centralized registration enables consistent validation, security, error handling, and progress notifications.
82
+
83
+ **What Breaks**: Registering tools outside factory functions → bypasses security, no DI, inconsistent error handling.
84
+
85
+ ### 2. Adapter Pattern
86
+
87
+ Use adapter helpers from `adapters.ts` to wrap handlers with dependency injection:
88
+
89
+ ```typescript
90
+ import { adapt, adaptWrite, adaptWithDelta, adaptNoInput } from './adapters.js';
91
+
92
+ // Read-only tool with input
93
+ handler: adapt(handleGetBudget, context);
94
+
95
+ // Write tool (invalidates cache)
96
+ handler: adaptWrite(handleUpdateTransaction, context);
97
+
98
+ // Delta-aware tool
99
+ handler: adaptWithDelta(handleListTransactions, context);
100
+
101
+ // No-input tool
102
+ handler: adaptNoInput(handleGetUser, context);
103
+ ```
104
+
105
+ **Adapter Types**:
106
+
107
+ - `adapt` - Standard read-only handler with input
108
+ - `adaptWrite` - Write handler (invalidates cache, supports progress)
109
+ - `adaptWithDelta` - Delta-aware handler for efficient updates
110
+ - `adaptNoInput` - Handler with no input parameters
111
+
112
+ **Why Critical**: Adapters inject ToolContext dependencies, enable progress notifications, and ensure consistent error handling.
113
+
114
+ **What Breaks**: Not using adapters → no DI, missing errorHandler, no progress support, inconsistent behavior.
115
+
116
+ ### 3. Schema Organization
117
+
118
+ Schemas are organized by domain and strictness:
119
+
120
+ ```typescript
121
+ // Input schemas (in tool files)
122
+ const CreateTransactionSchema = z
123
+ .object({
124
+ budget_id: z.string().optional(),
125
+ account_id: z.string(),
126
+ amount: z.number(),
127
+ date: z.string(),
128
+ // ...
129
+ })
130
+ .strict(); // CRITICAL: Always use .strict()
131
+
132
+ // Shared schemas (in schemas/common.ts)
133
+ export const emptyObjectSchema = z.object({}).strict();
134
+ export const looseObjectSchema = z.object({}).passthrough();
135
+
136
+ // Output schemas (in schemas/outputs/)
137
+ export const BudgetOutputSchema = z.object({
138
+ id: z.string(),
139
+ name: z.string(),
140
+ // ...
141
+ });
142
+ ```
143
+
144
+ **Why Critical**: `.strict()` prevents unknown fields, which is a security concern. Input validation catches errors early.
145
+
146
+ **What Breaks**: Missing `.strict()` → security vulnerability (unknown fields accepted). Missing validation → runtime errors, data corruption.
147
+
148
+ ### 4. Amount Handling (CRITICAL!)
149
+
150
+ YNAB uses **milliunits** (1 dollar = 1000 milliunits). Always convert before API calls:
151
+
152
+ ```typescript
153
+ import { milliunitsToAmount, amountToMilliunits } from '../utils/money.js';
154
+
155
+ // User provides dollars, convert to milliunits for API
156
+ const transaction = {
157
+ amount: amountToMilliunits(userInputDollars), // e.g., 25.50 → 25500
158
+ // ...
159
+ };
160
+
161
+ // API returns milliunits, convert to dollars for display
162
+ const displayAmount = milliunitsToAmount(transaction.amount); // 25500 → 25.50
163
+ ```
164
+
165
+ **Why CRITICAL**: Missing conversion → amounts are 1000x wrong (e.g., $25.50 becomes $0.02550 or $25,500.00).
166
+
167
+ **What Breaks**: Direct dollar amounts to API → wrong values. Missing conversion from API → wrong display.
168
+
169
+ ### 5. Progress Notifications
170
+
171
+ Long-running tools (reconciliation, bulk operations) emit progress updates:
172
+
173
+ ```typescript
174
+ async function handleReconcileAccount(
175
+ input: ReconcileInput,
176
+ sendProgress?: ProgressCallback
177
+ ): Promise<ReconcileResult> {
178
+ await sendProgress?.({
179
+ progress: 10,
180
+ total: 100,
181
+ message: 'Parsing CSV...',
182
+ });
183
+
184
+ // ... parsing logic ...
185
+
186
+ await sendProgress?.({
187
+ progress: 50,
188
+ total: 100,
189
+ message: 'Matching transactions...',
190
+ });
191
+
192
+ // ... matching logic ...
193
+
194
+ await sendProgress?.({
195
+ progress: 100,
196
+ total: 100,
197
+ message: 'Complete',
198
+ });
199
+
200
+ return result;
201
+ }
202
+ ```
203
+
204
+ **Why Critical**: Operations >5 seconds need progress to prevent timeouts and improve UX.
205
+
206
+ **What Breaks**: Missing optional chaining (`?.`) → TypeError. Missing progress updates → poor UX, timeouts.
207
+
208
+ ### 6. Cache Invalidation
209
+
210
+ Write operations must invalidate related caches:
211
+
212
+ ```typescript
213
+ // After creating/updating/deleting a transaction
214
+ await updateTransaction(transactionId, updates);
215
+
216
+ // Invalidate related caches
217
+ context.cacheManager.delete(`transaction:${transactionId}`);
218
+ context.cacheManager.delete(`transactions:${budgetId}`);
219
+ context.cacheManager.delete(`account:${accountId}`); // Account balance changed
220
+ ```
221
+
222
+ **Why Critical**: Stale cache → users see outdated data, inconsistent state.
223
+
224
+ **What Breaks**: Missing invalidation → stale data persists until TTL expires (2-10 minutes).
225
+
226
+ ## Transaction Tools (Special Note)
227
+
228
+ In v0.18.4, transaction tools were refactored into 3 files for maintainability:
229
+
230
+ ### File Breakdown
231
+
232
+ 1. **transactionSchemas.ts** (453 lines)
233
+ - Zod schemas for all transaction operations
234
+ - Input: `CreateTransactionSchema`, `UpdateTransactionSchema`, etc.
235
+ - Shared types: `TransactionInput`, `BulkTransactionInput`
236
+
237
+ 2. **transactionUtils.ts** (536 lines)
238
+ - Transaction utilities and helpers
239
+ - Receipt itemization logic (smart collapse for 5+ items)
240
+ - Big ticket preservation (items >10% of total)
241
+ - Tax allocation across line items
242
+ - Date validation, amount validation
243
+
244
+ 3. **transactionTools.ts** (2,274 lines)
245
+ - Tool registration factory (`registerTransactionTools`)
246
+ - Handler implementations for all transaction operations
247
+ - Tools: `create_transaction`, `update_transaction`, `delete_transaction`, `create_transactions`, `create_receipt_split_transaction`, `list_transactions`, `get_transaction`, `export_transactions`, `update_transactions`
248
+
249
+ ### Why Refactored
250
+
251
+ - **Maintainability**: 3,263 lines in one file was unwieldy
252
+ - **Separation of Concerns**: Schemas, utilities, and handlers are distinct responsibilities
253
+ - **Testability**: Easier to unit test schemas and utilities separately
254
+
255
+ ## Receipt Itemization (v0.18.2+)
256
+
257
+ The `create_receipt_split_transaction` tool uses smart itemization logic:
258
+
259
+ ### Features
260
+
261
+ 1. **Smart Collapse**: Collapses 5+ small items into "Other items" memo entry
262
+ 2. **Big Ticket Preservation**: Items >10% of total are always preserved as separate splits
263
+ 3. **Tax Allocation**: Distributes tax proportionally across line items
264
+ 4. **Memo Format**: Each split gets memo like "Item Name ($12.34)" for traceability
265
+
266
+ ### Example
267
+
268
+ ```typescript
269
+ // 8-item receipt with $100 total, $10 tax
270
+ // Result: 4 big items ($15+ each) + 1 "Other items (4 items, $20.00)" + tax split
271
+ ```
272
+
273
+ **Why Important**: Keeps transaction list clean while preserving important line items.
274
+
275
+ **What Breaks**: Manual memo formatting → inconsistent, hard to parse.
276
+
277
+ ## Common Development Tasks
278
+
279
+ ### Adding a New Tool
280
+
281
+ 1. **Choose domain file** (e.g., `budgetTools.ts` for budget operations)
282
+
283
+ 2. **Create Zod schema** with strict validation:
284
+ ```typescript
285
+ const MyToolSchema = z
286
+ .object({
287
+ budget_id: z.string().optional(),
288
+ my_field: z.string(),
289
+ })
290
+ .strict(); // CRITICAL
291
+ ```
292
+
293
+ 3. **Implement handler function**:
294
+ ```typescript
295
+ async function handleMyTool(
296
+ input: z.infer<typeof MyToolSchema>,
297
+ context: ToolContext
298
+ ): Promise<MyResult> {
299
+ const budgetId = BudgetResolver.resolveBudgetId(
300
+ input.budget_id,
301
+ context.getDefaultBudgetId()
302
+ );
303
+ if (typeof budgetId !== 'string') return budgetId;
304
+
305
+ // ... implementation ...
306
+
307
+ return result;
308
+ }
309
+ ```
310
+
311
+ 4. **Register in factory function**:
312
+ ```typescript
313
+ export function registerMyDomainTools(
314
+ registry: ToolRegistry,
315
+ context: ToolContext
316
+ ): void {
317
+ registry.register({
318
+ name: 'my_tool',
319
+ description: 'My tool description',
320
+ inputSchema: MyToolSchema,
321
+ handler: adapt(handleMyTool, context),
322
+ metadata: {
323
+ annotations: {
324
+ ...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
325
+ title: 'YNAB: My Tool',
326
+ },
327
+ },
328
+ });
329
+ }
330
+ ```
331
+
332
+ 5. **Add unit tests** in `__tests__/myDomainTools.test.ts`
333
+
334
+ 6. **Add integration tests** in `__tests__/myDomainTools.integration.test.ts`
335
+
336
+ ### Modifying Existing Tool
337
+
338
+ 1. **Read the current schema** to understand inputs
339
+ 2. **Update schema** if adding/changing fields:
340
+ ```typescript
341
+ const UpdatedSchema = ExistingSchema.extend({
342
+ new_field: z.string().optional(),
343
+ });
344
+ ```
345
+ 3. **Update handler** with new logic
346
+ 4. **Update tests** to cover new behavior
347
+ 5. **Invalidate caches** if it's a write operation
348
+
349
+ ### Adding Progress Notifications
350
+
351
+ 1. **Update handler signature**:
352
+ ```typescript
353
+ async function handleMyTool(
354
+ input: MyInput,
355
+ sendProgress?: ProgressCallback
356
+ ): Promise<MyOutput>
357
+ ```
358
+
359
+ 2. **Use `adaptWrite` adapter** (supports progress):
360
+ ```typescript
361
+ handler: adaptWrite(handleMyTool, context);
362
+ ```
363
+
364
+ 3. **Emit progress updates**:
365
+ ```typescript
366
+ await sendProgress?.({
367
+ progress: currentStep,
368
+ total: totalSteps,
369
+ message: 'Processing...',
370
+ });
371
+ ```
372
+
373
+ ### Adding Output Schema
374
+
375
+ 1. **Create schema** in `schemas/outputs/`:
376
+ ```typescript
377
+ export const MyOutputSchema = z.object({
378
+ id: z.string(),
379
+ name: z.string(),
380
+ // ...
381
+ });
382
+ ```
383
+
384
+ 2. **Use in handler**:
385
+ ```typescript
386
+ const result = await fetchData();
387
+ return MyOutputSchema.parse(result); // Validates output
388
+ ```
389
+
390
+ ## Testing Approach
391
+
392
+ ### Unit Tests
393
+
394
+ - **Location**: `src/tools/__tests__/*.test.ts`
395
+ - **Mock**: YNAB API, ToolContext, all external dependencies
396
+ - **Coverage**: 80% minimum
397
+ - **Focus**: Handler logic, error handling, edge cases
398
+
399
+ ### Integration Tests
400
+
401
+ - **Location**: `src/tools/__tests__/*.integration.test.ts`
402
+ - **Mock**: YNAB API (use realistic fixtures)
403
+ - **Real**: ToolContext, cacheManager, errorHandler
404
+ - **Focus**: End-to-end tool execution, cache behavior
405
+
406
+ ### Example Unit Test
407
+
408
+ ```typescript
409
+ describe('handleCreateTransaction', () => {
410
+ it('should convert dollars to milliunits', async () => {
411
+ const context = createMockContext();
412
+ const input = {
413
+ account_id: 'acc123',
414
+ amount: 25.5, // Dollars
415
+ date: '2025-01-31',
416
+ };
417
+
418
+ await handleCreateTransaction(input, context);
419
+
420
+ expect(context.ynabAPI.createTransaction).toHaveBeenCalledWith(
421
+ expect.objectContaining({
422
+ amount: 25500, // Milliunits!
423
+ })
424
+ );
425
+ });
426
+ });
427
+ ```
428
+
429
+ ## What Will Break If Violated
430
+
431
+ ### 1. Missing Milliunits Conversion
432
+
433
+ **Problem**: Passing dollar amounts directly to YNAB API.
434
+
435
+ **Impact**: Amounts are 1000x wrong (e.g., $25.50 → $0.02550 or $25,500.00).
436
+
437
+ **Fix**: Always use `amountToMilliunits()` before API calls:
438
+
439
+ ```typescript
440
+ // BAD
441
+ await ynabAPI.createTransaction({
442
+ amount: 25.5, // Wrong!
443
+ });
444
+
445
+ // GOOD
446
+ await ynabAPI.createTransaction({
447
+ amount: amountToMilliunits(25.5), // 25500 milliunits
448
+ });
449
+ ```
450
+
451
+ ### 2. Schema Without `.strict()`
452
+
453
+ **Problem**: Input schemas missing `.strict()` modifier.
454
+
455
+ **Impact**: Security vulnerability (unknown fields accepted), potential injection attacks.
456
+
457
+ **Fix**: Always use `.strict()` on input schemas:
458
+
459
+ ```typescript
460
+ // BAD
461
+ const MySchema = z.object({
462
+ field: z.string(),
463
+ }); // Allows unknown fields!
464
+
465
+ // GOOD
466
+ const MySchema = z
467
+ .object({
468
+ field: z.string(),
469
+ })
470
+ .strict(); // Rejects unknown fields
471
+ ```
472
+
473
+ ### 3. Missing Cache Invalidation
474
+
475
+ **Problem**: Write operations without cache invalidation.
476
+
477
+ **Impact**: Users see stale data for 2-10 minutes (until TTL expires).
478
+
479
+ **Fix**: Invalidate related caches after writes:
480
+
481
+ ```typescript
482
+ await updateTransaction(id, updates);
483
+
484
+ // Invalidate all related caches
485
+ context.cacheManager.delete(`transaction:${id}`);
486
+ context.cacheManager.delete(`transactions:${budgetId}`);
487
+ context.cacheManager.delete(`account:${accountId}`);
488
+ ```
489
+
490
+ ### 4. Missing `.js` Extensions in Imports
491
+
492
+ **Problem**: Imports without `.js` extension.
493
+
494
+ **Impact**: Build failures, runtime errors (ES modules require explicit extensions).
495
+
496
+ **Fix**: Always use `.js` extensions:
497
+
498
+ ```typescript
499
+ // BAD
500
+ import { adapt } from './adapters';
501
+
502
+ // GOOD
503
+ import { adapt } from './adapters.js';
504
+ ```
505
+
506
+ ### 5. Not Using Adapters
507
+
508
+ **Problem**: Registering handlers directly without adapters.
509
+
510
+ **Impact**: No dependency injection, missing errorHandler, no progress support, inconsistent error handling.
511
+
512
+ **Fix**: Always use adapter helpers:
513
+
514
+ ```typescript
515
+ // BAD
516
+ handler: async (input) => handleMyTool(input);
517
+
518
+ // GOOD
519
+ handler: adapt(handleMyTool, context);
520
+ ```
521
+
522
+ ### 6. Direct YNAB API Calls
523
+
524
+ **Problem**: Bypassing ToolContext and calling YNAB API directly.
525
+
526
+ **Impact**: No caching, no rate limiting, no error handling, test failures.
527
+
528
+ **Fix**: Always use `context.ynabAPI`:
529
+
530
+ ```typescript
531
+ // BAD
532
+ const api = new ynab.API(token);
533
+ const budgets = await api.budgets.getBudgets();
534
+
535
+ // GOOD
536
+ const budgets = await context.ynabAPI.budgets.getBudgets();
537
+ ```
538
+
539
+ ## Tool Categories & Annotations
540
+
541
+ All tools use MCP annotations from `toolCategories.ts`:
542
+
543
+ ### Annotation Presets
544
+
545
+ - **READ_ONLY_EXTERNAL** - Read-only YNAB API calls (idempotent)
546
+ - **WRITE_EXTERNAL_CREATE** - Create operations (non-idempotent)
547
+ - **WRITE_EXTERNAL_UPDATE** - Update operations (idempotent)
548
+ - **WRITE_EXTERNAL_DELETE** - Delete operations (destructive, idempotent)
549
+ - **UTILITY_LOCAL** - Local operations (no external API)
550
+
551
+ ### Usage
552
+
553
+ ```typescript
554
+ metadata: {
555
+ annotations: {
556
+ ...ToolAnnotationPresets.WRITE_EXTERNAL_UPDATE,
557
+ title: 'YNAB: Update Transaction',
558
+ },
559
+ }
560
+ ```
561
+
562
+ ## Integration Points
563
+
564
+ ### With Server (`src/server/`)
565
+
566
+ - **ToolRegistry**: All tools register via `registry.register()`
567
+ - **ToolContext**: Injected by adapters, provides ynabAPI, cacheManager, etc.
568
+ - **Error Handling**: Uses `errorHandler` from ToolContext
569
+
570
+ ### With Types (`src/types/`)
571
+
572
+ - **ToolContext**: Central DI object with all shared dependencies
573
+ - **Handler Signatures**: Handler, DeltaHandler, WriteHandler, NoInputHandler
574
+ - **Reconciliation Types**: ReconcileInput, ReconcileResult, etc.
575
+
576
+ ### With Utils (`src/utils/`)
577
+
578
+ - **Money Conversion**: `amountToMilliunits()`, `milliunitsToAmount()`
579
+ - **Date Utilities**: `formatDate()`, `isValidDate()`
580
+ - **Validation**: `validateAmount()`, `validateDate()`
581
+
582
+ ## Performance Considerations
583
+
584
+ 1. **Use Delta Requests**: For large datasets (transactions), use `adaptWithDelta`
585
+ 2. **Cache Aggressively**: Read-only tools benefit from long TTLs
586
+ 3. **Batch Operations**: Use bulk APIs (`create_transactions`, `update_transactions`) for multiple operations
587
+ 4. **Progress Notifications**: Operations >5 seconds should emit progress
588
+ 5. **Lazy Loading**: Don't fetch unnecessary related data
589
+
590
+ ## Security Considerations
591
+
592
+ 1. **Strict Schemas**: Always use `.strict()` on input schemas
593
+ 2. **Input Validation**: Validate all inputs via Zod before processing
594
+ 3. **Budget ID Validation**: Always resolve and validate budget IDs
595
+ 4. **Amount Validation**: Validate amounts are reasonable (not negative for debits, etc.)
596
+ 5. **No Secret Leakage**: Error responses never include API tokens or sensitive data
597
+
598
+ ## Related Documentation
599
+
600
+ - [Root CLAUDE.md](../../CLAUDE.md) - Project overview and architecture
601
+ - [Server CLAUDE.md](../server/CLAUDE.md) - Server components and MCP orchestration
602
+ - [Reconciliation CLAUDE.md](reconciliation/CLAUDE.md) - Reconciliation system deep-dive
603
+ - [Schemas CLAUDE.md](schemas/CLAUDE.md) - Schema definitions and validation
604
+ - [API Documentation](../../docs/reference/API.md) - Complete API reference