@dizzlkheinz/ynab-mcpb 0.18.4 → 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 (343) hide show
  1. package/CLAUDE.md +87 -8
  2. package/bin/ynab-mcp-server.cjs +2 -2
  3. package/bin/ynab-mcp-server.js +3 -3
  4. package/biome.json +39 -0
  5. package/dist/bundle/index.cjs +67 -67
  6. package/dist/index.d.ts +1 -1
  7. package/dist/index.js +27 -27
  8. package/dist/server/YNABMCPServer.d.ts +3 -4
  9. package/dist/server/YNABMCPServer.js +111 -116
  10. package/dist/server/budgetResolver.d.ts +6 -5
  11. package/dist/server/budgetResolver.js +46 -36
  12. package/dist/server/cacheKeys.js +6 -6
  13. package/dist/server/cacheManager.js +14 -11
  14. package/dist/server/completions.d.ts +2 -2
  15. package/dist/server/completions.js +20 -15
  16. package/dist/server/config.d.ts +10 -5
  17. package/dist/server/config.js +24 -7
  18. package/dist/server/deltaCache.d.ts +2 -2
  19. package/dist/server/deltaCache.js +22 -16
  20. package/dist/server/deltaCache.merge.d.ts +2 -2
  21. package/dist/server/diagnostics.d.ts +4 -4
  22. package/dist/server/diagnostics.js +38 -32
  23. package/dist/server/errorHandler.d.ts +5 -12
  24. package/dist/server/errorHandler.js +219 -217
  25. package/dist/server/prompts.d.ts +2 -2
  26. package/dist/server/prompts.js +45 -45
  27. package/dist/server/rateLimiter.js +4 -4
  28. package/dist/server/requestLogger.d.ts +1 -1
  29. package/dist/server/requestLogger.js +40 -35
  30. package/dist/server/resources.d.ts +3 -3
  31. package/dist/server/resources.js +55 -52
  32. package/dist/server/responseFormatter.js +6 -6
  33. package/dist/server/securityMiddleware.d.ts +2 -2
  34. package/dist/server/securityMiddleware.js +22 -20
  35. package/dist/server/serverKnowledgeStore.js +1 -1
  36. package/dist/server/toolRegistry.d.ts +3 -3
  37. package/dist/server/toolRegistry.js +47 -40
  38. package/dist/tools/__tests__/deltaTestUtils.d.ts +3 -3
  39. package/dist/tools/__tests__/deltaTestUtils.js +2 -2
  40. package/dist/tools/accountTools.d.ts +9 -8
  41. package/dist/tools/accountTools.js +47 -47
  42. package/dist/tools/adapters.d.ts +13 -8
  43. package/dist/tools/adapters.js +21 -11
  44. package/dist/tools/budgetTools.d.ts +8 -7
  45. package/dist/tools/budgetTools.js +22 -22
  46. package/dist/tools/categoryTools.d.ts +9 -8
  47. package/dist/tools/categoryTools.js +68 -59
  48. package/dist/tools/compareTransactions/formatter.d.ts +3 -3
  49. package/dist/tools/compareTransactions/formatter.js +9 -9
  50. package/dist/tools/compareTransactions/index.d.ts +6 -6
  51. package/dist/tools/compareTransactions/index.js +58 -43
  52. package/dist/tools/compareTransactions/matcher.d.ts +1 -1
  53. package/dist/tools/compareTransactions/matcher.js +28 -15
  54. package/dist/tools/compareTransactions/parser.d.ts +2 -2
  55. package/dist/tools/compareTransactions/parser.js +144 -138
  56. package/dist/tools/compareTransactions/types.d.ts +4 -4
  57. package/dist/tools/compareTransactions.d.ts +1 -1
  58. package/dist/tools/compareTransactions.js +1 -1
  59. package/dist/tools/deltaFetcher.d.ts +2 -2
  60. package/dist/tools/deltaFetcher.js +16 -15
  61. package/dist/tools/deltaSupport.d.ts +4 -4
  62. package/dist/tools/deltaSupport.js +35 -41
  63. package/dist/tools/exportTransactions.d.ts +5 -4
  64. package/dist/tools/exportTransactions.js +61 -59
  65. package/dist/tools/monthTools.d.ts +7 -6
  66. package/dist/tools/monthTools.js +31 -29
  67. package/dist/tools/payeeTools.d.ts +7 -6
  68. package/dist/tools/payeeTools.js +28 -28
  69. package/dist/tools/reconcileAdapter.d.ts +2 -2
  70. package/dist/tools/reconcileAdapter.js +19 -12
  71. package/dist/tools/reconciliation/analyzer.d.ts +4 -4
  72. package/dist/tools/reconciliation/analyzer.js +73 -59
  73. package/dist/tools/reconciliation/csvParser.d.ts +3 -3
  74. package/dist/tools/reconciliation/csvParser.js +128 -104
  75. package/dist/tools/reconciliation/executor.d.ts +4 -4
  76. package/dist/tools/reconciliation/executor.js +148 -109
  77. package/dist/tools/reconciliation/index.d.ts +10 -10
  78. package/dist/tools/reconciliation/index.js +96 -83
  79. package/dist/tools/reconciliation/matcher.d.ts +3 -3
  80. package/dist/tools/reconciliation/matcher.js +17 -16
  81. package/dist/tools/reconciliation/payeeNormalizer.js +19 -8
  82. package/dist/tools/reconciliation/recommendationEngine.d.ts +1 -1
  83. package/dist/tools/reconciliation/recommendationEngine.js +40 -40
  84. package/dist/tools/reconciliation/reportFormatter.d.ts +2 -2
  85. package/dist/tools/reconciliation/reportFormatter.js +59 -58
  86. package/dist/tools/reconciliation/signDetector.d.ts +1 -1
  87. package/dist/tools/reconciliation/types.d.ts +16 -16
  88. package/dist/tools/reconciliation/ynabAdapter.d.ts +2 -2
  89. package/dist/tools/schemas/common.d.ts +1 -1
  90. package/dist/tools/schemas/common.js +1 -1
  91. package/dist/tools/schemas/outputs/accountOutputs.d.ts +1 -1
  92. package/dist/tools/schemas/outputs/accountOutputs.js +24 -18
  93. package/dist/tools/schemas/outputs/budgetOutputs.d.ts +1 -1
  94. package/dist/tools/schemas/outputs/budgetOutputs.js +14 -11
  95. package/dist/tools/schemas/outputs/categoryOutputs.d.ts +1 -1
  96. package/dist/tools/schemas/outputs/categoryOutputs.js +49 -29
  97. package/dist/tools/schemas/outputs/comparisonOutputs.d.ts +1 -1
  98. package/dist/tools/schemas/outputs/comparisonOutputs.js +12 -12
  99. package/dist/tools/schemas/outputs/index.d.ts +14 -14
  100. package/dist/tools/schemas/outputs/index.js +14 -14
  101. package/dist/tools/schemas/outputs/monthOutputs.d.ts +1 -1
  102. package/dist/tools/schemas/outputs/monthOutputs.js +56 -41
  103. package/dist/tools/schemas/outputs/payeeOutputs.d.ts +1 -1
  104. package/dist/tools/schemas/outputs/payeeOutputs.js +10 -10
  105. package/dist/tools/schemas/outputs/reconciliationOutputs.d.ts +2 -2
  106. package/dist/tools/schemas/outputs/reconciliationOutputs.js +45 -45
  107. package/dist/tools/schemas/outputs/transactionMutationOutputs.d.ts +1 -1
  108. package/dist/tools/schemas/outputs/transactionMutationOutputs.js +28 -22
  109. package/dist/tools/schemas/outputs/transactionOutputs.d.ts +1 -1
  110. package/dist/tools/schemas/outputs/transactionOutputs.js +43 -35
  111. package/dist/tools/schemas/outputs/utilityOutputs.d.ts +1 -1
  112. package/dist/tools/schemas/outputs/utilityOutputs.js +5 -3
  113. package/dist/tools/schemas/shared/commonOutputs.d.ts +1 -1
  114. package/dist/tools/schemas/shared/commonOutputs.js +15 -9
  115. package/dist/tools/transactionReadTools.d.ts +11 -0
  116. package/dist/tools/transactionReadTools.js +202 -0
  117. package/dist/tools/transactionSchemas.d.ts +7 -7
  118. package/dist/tools/transactionSchemas.js +77 -57
  119. package/dist/tools/transactionTools.d.ts +6 -24
  120. package/dist/tools/transactionTools.js +7 -1499
  121. package/dist/tools/transactionUtils.d.ts +6 -6
  122. package/dist/tools/transactionUtils.js +78 -63
  123. package/dist/tools/transactionWriteTools.d.ts +20 -0
  124. package/dist/tools/transactionWriteTools.js +1342 -0
  125. package/dist/tools/utilityTools.d.ts +5 -4
  126. package/dist/tools/utilityTools.js +11 -11
  127. package/dist/types/index.d.ts +7 -7
  128. package/dist/types/index.js +6 -6
  129. package/dist/types/reconciliation.d.ts +1 -1
  130. package/dist/types/toolRegistration.d.ts +14 -12
  131. package/dist/utils/amountUtils.js +1 -1
  132. package/dist/utils/dateUtils.js +4 -4
  133. package/dist/utils/errors.d.ts +3 -3
  134. package/dist/utils/errors.js +4 -4
  135. package/dist/utils/money.d.ts +2 -2
  136. package/dist/utils/money.js +8 -8
  137. package/dist/utils/validationError.d.ts +1 -1
  138. package/dist/utils/validationError.js +1 -1
  139. package/docs/assets/examples/reconciliation-with-recommendations.json +66 -66
  140. package/docs/assets/schemas/reconciliation-v2.json +360 -336
  141. package/esbuild.config.mjs +53 -50
  142. package/meta.json +12548 -12548
  143. package/package.json +98 -111
  144. package/scripts/analyze-bundle.mjs +33 -30
  145. package/scripts/create-pr-description.js +169 -120
  146. package/scripts/run-all-tests.js +178 -169
  147. package/scripts/run-domain-integration-tests.js +28 -18
  148. package/scripts/run-generate-mcpb.js +19 -17
  149. package/scripts/run-throttled-integration-tests.js +92 -83
  150. package/scripts/test-delta-params.mjs +149 -120
  151. package/scripts/test-recommendations.ts +36 -32
  152. package/scripts/tmpTransaction.ts +80 -43
  153. package/scripts/validate-env.js +98 -91
  154. package/scripts/verify-build.js +78 -76
  155. package/src/__tests__/comprehensive.integration.test.ts +1281 -1154
  156. package/src/__tests__/performance.test.ts +723 -671
  157. package/src/__tests__/setup.ts +442 -395
  158. package/src/__tests__/smoke.e2e.test.ts +41 -39
  159. package/src/__tests__/testRunner.ts +314 -295
  160. package/src/__tests__/testUtils.ts +456 -364
  161. package/src/__tests__/tools/reconciliation/csvParser.integration.test.ts +109 -107
  162. package/src/__tests__/tools/reconciliation/real-world.integration.test.ts +41 -41
  163. package/src/index.ts +68 -59
  164. package/src/server/CLAUDE.md +480 -0
  165. package/src/server/YNABMCPServer.ts +821 -794
  166. package/src/server/__tests__/YNABMCPServer.integration.test.ts +929 -893
  167. package/src/server/__tests__/YNABMCPServer.test.ts +903 -899
  168. package/src/server/__tests__/budgetResolver.test.ts +466 -423
  169. package/src/server/__tests__/cacheManager.test.ts +891 -874
  170. package/src/server/__tests__/completions.integration.test.ts +115 -106
  171. package/src/server/__tests__/completions.test.ts +334 -313
  172. package/src/server/__tests__/config.test.ts +98 -86
  173. package/src/server/__tests__/deltaCache.merge.test.ts +774 -703
  174. package/src/server/__tests__/deltaCache.swr.test.ts +198 -153
  175. package/src/server/__tests__/deltaCache.test.ts +946 -759
  176. package/src/server/__tests__/diagnostics.test.ts +825 -792
  177. package/src/server/__tests__/errorHandler.integration.test.ts +512 -462
  178. package/src/server/__tests__/errorHandler.test.ts +402 -397
  179. package/src/server/__tests__/prompts.test.ts +424 -347
  180. package/src/server/__tests__/rateLimiter.test.ts +313 -309
  181. package/src/server/__tests__/requestLogger.test.ts +443 -403
  182. package/src/server/__tests__/resources.template.test.ts +196 -185
  183. package/src/server/__tests__/resources.test.ts +294 -288
  184. package/src/server/__tests__/security.integration.test.ts +487 -421
  185. package/src/server/__tests__/securityMiddleware.test.ts +519 -444
  186. package/src/server/__tests__/server-startup.integration.test.ts +509 -490
  187. package/src/server/__tests__/serverKnowledgeStore.test.ts +174 -173
  188. package/src/server/__tests__/toolRegistration.test.ts +239 -210
  189. package/src/server/__tests__/toolRegistry.test.ts +907 -845
  190. package/src/server/budgetResolver.ts +221 -181
  191. package/src/server/cacheKeys.ts +6 -6
  192. package/src/server/cacheManager.ts +498 -484
  193. package/src/server/completions.ts +267 -243
  194. package/src/server/config.ts +35 -14
  195. package/src/server/deltaCache.merge.ts +146 -128
  196. package/src/server/deltaCache.ts +352 -309
  197. package/src/server/diagnostics.ts +257 -242
  198. package/src/server/errorHandler.ts +747 -744
  199. package/src/server/prompts.ts +181 -176
  200. package/src/server/rateLimiter.ts +131 -129
  201. package/src/server/requestLogger.ts +350 -322
  202. package/src/server/resources.ts +442 -374
  203. package/src/server/responseFormatter.ts +41 -37
  204. package/src/server/securityMiddleware.ts +223 -205
  205. package/src/server/serverKnowledgeStore.ts +67 -67
  206. package/src/server/toolRegistry.ts +508 -474
  207. package/src/tools/CLAUDE.md +604 -0
  208. package/src/tools/__tests__/accountTools.delta.integration.test.ts +128 -111
  209. package/src/tools/__tests__/accountTools.integration.test.ts +129 -111
  210. package/src/tools/__tests__/accountTools.test.ts +685 -638
  211. package/src/tools/__tests__/adapters.test.ts +142 -108
  212. package/src/tools/__tests__/budgetTools.delta.integration.test.ts +73 -73
  213. package/src/tools/__tests__/budgetTools.integration.test.ts +132 -124
  214. package/src/tools/__tests__/budgetTools.test.ts +442 -413
  215. package/src/tools/__tests__/categoryTools.delta.integration.test.ts +76 -68
  216. package/src/tools/__tests__/categoryTools.integration.test.ts +314 -288
  217. package/src/tools/__tests__/categoryTools.test.ts +656 -625
  218. package/src/tools/__tests__/compareTransactions/formatter.test.ts +535 -462
  219. package/src/tools/__tests__/compareTransactions/index.test.ts +378 -358
  220. package/src/tools/__tests__/compareTransactions/matcher.test.ts +497 -398
  221. package/src/tools/__tests__/compareTransactions/parser.test.ts +765 -747
  222. package/src/tools/__tests__/compareTransactions.test.ts +352 -332
  223. package/src/tools/__tests__/compareTransactions.window.test.ts +150 -146
  224. package/src/tools/__tests__/deltaFetcher.scheduled.integration.test.ts +69 -65
  225. package/src/tools/__tests__/deltaFetcher.test.ts +325 -265
  226. package/src/tools/__tests__/deltaSupport.test.ts +211 -184
  227. package/src/tools/__tests__/deltaTestUtils.ts +37 -33
  228. package/src/tools/__tests__/exportTransactions.test.ts +205 -200
  229. package/src/tools/__tests__/monthTools.delta.integration.test.ts +68 -68
  230. package/src/tools/__tests__/monthTools.integration.test.ts +178 -166
  231. package/src/tools/__tests__/monthTools.test.ts +561 -512
  232. package/src/tools/__tests__/payeeTools.delta.integration.test.ts +68 -68
  233. package/src/tools/__tests__/payeeTools.integration.test.ts +158 -142
  234. package/src/tools/__tests__/payeeTools.test.ts +486 -434
  235. package/src/tools/__tests__/transactionSchemas.test.ts +1202 -1186
  236. package/src/tools/__tests__/transactionTools.integration.test.ts +875 -825
  237. package/src/tools/__tests__/transactionTools.test.ts +4923 -4366
  238. package/src/tools/__tests__/transactionUtils.test.ts +1004 -977
  239. package/src/tools/__tests__/utilityTools.integration.test.ts +32 -32
  240. package/src/tools/__tests__/utilityTools.test.ts +68 -58
  241. package/src/tools/accountTools.ts +293 -271
  242. package/src/tools/adapters.ts +120 -63
  243. package/src/tools/budgetTools.ts +121 -116
  244. package/src/tools/categoryTools.ts +379 -339
  245. package/src/tools/compareTransactions/formatter.ts +131 -119
  246. package/src/tools/compareTransactions/index.ts +249 -214
  247. package/src/tools/compareTransactions/matcher.ts +259 -209
  248. package/src/tools/compareTransactions/parser.ts +517 -487
  249. package/src/tools/compareTransactions/types.ts +38 -38
  250. package/src/tools/compareTransactions.ts +1 -1
  251. package/src/tools/deltaFetcher.ts +281 -260
  252. package/src/tools/deltaSupport.ts +264 -259
  253. package/src/tools/exportTransactions.ts +230 -218
  254. package/src/tools/monthTools.ts +180 -165
  255. package/src/tools/payeeTools.ts +152 -140
  256. package/src/tools/reconcileAdapter.ts +297 -252
  257. package/src/tools/reconciliation/CLAUDE.md +506 -0
  258. package/src/tools/reconciliation/__tests__/adapter.causes.test.ts +133 -124
  259. package/src/tools/reconciliation/__tests__/adapter.test.ts +249 -230
  260. package/src/tools/reconciliation/__tests__/analyzer.test.ts +408 -400
  261. package/src/tools/reconciliation/__tests__/csvParser.test.ts +71 -69
  262. package/src/tools/reconciliation/__tests__/executor.integration.test.ts +348 -323
  263. package/src/tools/reconciliation/__tests__/executor.progress.test.ts +503 -457
  264. package/src/tools/reconciliation/__tests__/executor.test.ts +898 -831
  265. package/src/tools/reconciliation/__tests__/matcher.test.ts +667 -663
  266. package/src/tools/reconciliation/__tests__/payeeNormalizer.test.ts +296 -276
  267. package/src/tools/reconciliation/__tests__/recommendationEngine.integration.test.ts +692 -624
  268. package/src/tools/reconciliation/__tests__/recommendationEngine.test.ts +1008 -989
  269. package/src/tools/reconciliation/__tests__/reconciliation.delta.integration.test.ts +187 -146
  270. package/src/tools/reconciliation/__tests__/reportFormatter.test.ts +583 -533
  271. package/src/tools/reconciliation/__tests__/scenarios/adapterCurrency.scenario.test.ts +75 -74
  272. package/src/tools/reconciliation/__tests__/scenarios/extremes.scenario.test.ts +70 -62
  273. package/src/tools/reconciliation/__tests__/scenarios/repeatAmount.scenario.test.ts +102 -88
  274. package/src/tools/reconciliation/__tests__/schemaUrl.test.ts +56 -55
  275. package/src/tools/reconciliation/__tests__/signDetector.test.ts +209 -206
  276. package/src/tools/reconciliation/__tests__/ynabAdapter.test.ts +66 -60
  277. package/src/tools/reconciliation/analyzer.ts +564 -504
  278. package/src/tools/reconciliation/csvParser.ts +656 -609
  279. package/src/tools/reconciliation/executor.ts +1290 -1128
  280. package/src/tools/reconciliation/index.ts +580 -528
  281. package/src/tools/reconciliation/matcher.ts +256 -240
  282. package/src/tools/reconciliation/payeeNormalizer.ts +92 -78
  283. package/src/tools/reconciliation/recommendationEngine.ts +357 -345
  284. package/src/tools/reconciliation/reportFormatter.ts +343 -307
  285. package/src/tools/reconciliation/signDetector.ts +89 -83
  286. package/src/tools/reconciliation/types.ts +164 -159
  287. package/src/tools/reconciliation/ynabAdapter.ts +17 -15
  288. package/src/tools/schemas/CLAUDE.md +546 -0
  289. package/src/tools/schemas/common.ts +1 -1
  290. package/src/tools/schemas/outputs/__tests__/accountOutputs.test.ts +410 -409
  291. package/src/tools/schemas/outputs/__tests__/budgetOutputs.test.ts +305 -299
  292. package/src/tools/schemas/outputs/__tests__/categoryOutputs.test.ts +431 -430
  293. package/src/tools/schemas/outputs/__tests__/comparisonOutputs.test.ts +510 -495
  294. package/src/tools/schemas/outputs/__tests__/dateValidation.test.ts +179 -153
  295. package/src/tools/schemas/outputs/__tests__/discrepancyDirection.test.ts +293 -254
  296. package/src/tools/schemas/outputs/__tests__/monthOutputs.test.ts +457 -457
  297. package/src/tools/schemas/outputs/__tests__/payeeOutputs.test.ts +362 -356
  298. package/src/tools/schemas/outputs/__tests__/reconciliationOutputs.test.ts +402 -399
  299. package/src/tools/schemas/outputs/__tests__/transactionMutationSchemas.test.ts +225 -211
  300. package/src/tools/schemas/outputs/__tests__/transactionOutputs.test.ts +457 -454
  301. package/src/tools/schemas/outputs/__tests__/utilityOutputs.test.ts +316 -315
  302. package/src/tools/schemas/outputs/accountOutputs.ts +40 -34
  303. package/src/tools/schemas/outputs/budgetOutputs.ts +24 -19
  304. package/src/tools/schemas/outputs/categoryOutputs.ts +76 -56
  305. package/src/tools/schemas/outputs/comparisonOutputs.ts +192 -169
  306. package/src/tools/schemas/outputs/index.ts +163 -163
  307. package/src/tools/schemas/outputs/monthOutputs.ts +95 -80
  308. package/src/tools/schemas/outputs/payeeOutputs.ts +18 -18
  309. package/src/tools/schemas/outputs/reconciliationOutputs.ts +386 -373
  310. package/src/tools/schemas/outputs/transactionMutationOutputs.ts +259 -231
  311. package/src/tools/schemas/outputs/transactionOutputs.ts +81 -71
  312. package/src/tools/schemas/outputs/utilityOutputs.ts +90 -84
  313. package/src/tools/schemas/shared/commonOutputs.ts +27 -19
  314. package/src/tools/toolCategories.ts +114 -114
  315. package/src/tools/transactionReadTools.ts +327 -0
  316. package/src/tools/transactionSchemas.ts +322 -291
  317. package/src/tools/transactionTools.ts +84 -2246
  318. package/src/tools/transactionUtils.ts +507 -422
  319. package/src/tools/transactionWriteTools.ts +2110 -0
  320. package/src/tools/utilityTools.ts +46 -41
  321. package/src/types/CLAUDE.md +477 -0
  322. package/src/types/__tests__/index.test.ts +51 -51
  323. package/src/types/index.ts +43 -39
  324. package/src/types/integration-tests.d.ts +26 -26
  325. package/src/types/reconciliation.ts +29 -29
  326. package/src/types/toolAnnotations.ts +30 -30
  327. package/src/types/toolRegistration.ts +43 -32
  328. package/src/utils/CLAUDE.md +508 -0
  329. package/src/utils/__tests__/dateUtils.test.ts +174 -168
  330. package/src/utils/__tests__/money.test.ts +193 -187
  331. package/src/utils/amountUtils.ts +5 -5
  332. package/src/utils/baseError.ts +5 -5
  333. package/src/utils/dateUtils.ts +29 -26
  334. package/src/utils/errors.ts +14 -14
  335. package/src/utils/money.ts +66 -52
  336. package/src/utils/validationError.ts +1 -1
  337. package/tsconfig.json +29 -29
  338. package/tsconfig.prod.json +16 -16
  339. package/vitest-reporters/split-json-reporter.ts +247 -204
  340. package/vitest.config.ts +99 -95
  341. package/.prettierignore +0 -10
  342. package/.prettierrc.json +0 -10
  343. package/eslint.config.js +0 -49
@@ -0,0 +1,480 @@
1
+ # Server Components - YNAB MCP Server
2
+
3
+ This directory contains the core orchestration layer for the YNAB MCP Server, managing the Model Context Protocol interface, caching, error handling, budget resolution, and all server-side coordination.
4
+
5
+ ## Purpose & Responsibilities
6
+
7
+ The `src/server/` directory implements:
8
+
9
+ 1. **MCP Protocol Orchestration** - Request/response handling, tool registration, resources, prompts, completions
10
+ 2. **Caching Strategy** - Multi-tier caching with LRU eviction, delta requests, and server knowledge tracking
11
+ 3. **Error Handling** - Centralized, consistent error responses across all tools
12
+ 4. **Budget Resolution** - Default budget ID management and resolution
13
+ 5. **Security** - Input validation, rate limiting, security middleware
14
+ 6. **Diagnostics** - Health monitoring, cache statistics, system information
15
+
16
+ ## Key Files & Responsibilities
17
+
18
+ | File | Responsibility | Criticality | Lines |
19
+ |------|---------------|-------------|-------|
20
+ | **YNABMCPServer.ts** | Main orchestration server, MCP lifecycle, tool/resource/prompt handlers | CRITICAL | ~600 |
21
+ | **toolRegistry.ts** | Tool registration, validation, execution, progress notifications | CRITICAL | ~500 |
22
+ | **completions.ts** | MCP completions manager for autocomplete (budget_id, account_id, etc.) | HIGH | ~300 |
23
+ | **cacheManager.ts** | Enhanced caching with LRU, observability, stale-while-revalidate | CRITICAL | ~400 |
24
+ | **deltaCache.ts** | Delta request management, server knowledge tracking, merge operations | HIGH | ~350 |
25
+ | **deltaCache.merge.ts** | Entity merging functions for delta responses (transactions, categories, accounts) | HIGH | ~200 |
26
+ | **serverKnowledgeStore.ts** | Tracks last known server_knowledge values per cache key | MEDIUM | ~100 |
27
+ | **budgetResolver.ts** | Budget ID resolution with default budget support | HIGH | ~150 |
28
+ | **errorHandler.ts** | Centralized error handling, consistent error responses | CRITICAL | ~200 |
29
+ | **config.ts** | Environment validation, server configuration | CRITICAL | ~150 |
30
+ | **resources.ts** | MCP resource definitions and handlers (resource templates) | MEDIUM | ~250 |
31
+ | **prompts.ts** | MCP prompt definitions and handlers | LOW | ~150 |
32
+ | **diagnostics.ts** | System diagnostics, health monitoring, cache statistics | MEDIUM | ~200 |
33
+ | **securityMiddleware.ts** | Security validation, wrapper functions | HIGH | ~150 |
34
+ | **responseFormatter.ts** | JSON response formatting (minification/pretty-print) | LOW | ~100 |
35
+ | **rateLimiter.ts** | Rate limiting for YNAB API compliance | MEDIUM | ~150 |
36
+ | **requestLogger.ts** | Request/response logging middleware | LOW | ~100 |
37
+ | **cacheKeys.ts** | Centralized cache key generation utilities | MEDIUM | ~100 |
38
+
39
+ ## Critical Patterns & Conventions
40
+
41
+ ### 1. Dependency Injection Pattern
42
+
43
+ All server components use explicit dependency injection for testability and modularity:
44
+
45
+ ```typescript
46
+ // In YNABMCPServer.ts
47
+ constructor() {
48
+ this.errorHandler = new ErrorHandler();
49
+ this.cacheManager = new CacheManager(config);
50
+ this.budgetResolver = new BudgetResolver(
51
+ () => this.getDefaultBudgetId(),
52
+ this.errorHandler
53
+ );
54
+ // ... inject into other services
55
+ }
56
+ ```
57
+
58
+ **Why Critical**: Enables unit testing, loose coupling, and clear dependency graphs.
59
+
60
+ **What Breaks**: If you create services without DI, tests become impossible, circular dependencies emerge, and the system becomes tightly coupled.
61
+
62
+ ### 2. MCP Handler Pattern
63
+
64
+ All MCP handlers (tools, resources, prompts, completions) follow a consistent pattern:
65
+
66
+ ```typescript
67
+ // Tool handler
68
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
69
+ return this.toolRegistry.executeTool(
70
+ request.params.name,
71
+ request.params.arguments ?? {}
72
+ );
73
+ });
74
+
75
+ // Resource handler
76
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
77
+ return this.resourcesManager.handleReadResource(request.params.uri);
78
+ });
79
+ ```
80
+
81
+ **Why Critical**: Ensures consistent error handling, logging, and security across all MCP operations.
82
+
83
+ **What Breaks**: Direct implementation without the registry/manager pattern bypasses security, error handling, and caching.
84
+
85
+ ### 3. Cache Wrapper Pattern
86
+
87
+ Use `cacheManager.wrap()` for automatic caching with observability:
88
+
89
+ ```typescript
90
+ return cacheManager.wrap('cache_key', {
91
+ ttl: CACHE_TTLS.ACCOUNTS, // Use predefined TTL constants
92
+ staleWhileRevalidate: 120000, // Optional background refresh
93
+ loader: () => expensiveOperation(),
94
+ });
95
+ ```
96
+
97
+ **Predefined TTL Constants** (in `cacheManager.ts`):
98
+
99
+ - `CACHE_TTLS.BUDGETS` - 10 minutes
100
+ - `CACHE_TTLS.ACCOUNTS` - 5 minutes
101
+ - `CACHE_TTLS.CATEGORIES` - 5 minutes
102
+ - `CACHE_TTLS.PAYEES` - 10 minutes
103
+ - `CACHE_TTLS.TRANSACTIONS` - 2 minutes
104
+ - `CACHE_TTLS.SCHEDULED_TRANSACTIONS` - 5 minutes
105
+ - `CACHE_TTLS.USER_INFO` - 30 minutes
106
+ - `CACHE_TTLS.MONTHS` - 5 minutes
107
+
108
+ **Why Critical**: Reduces YNAB API calls, respects rate limits, improves response times.
109
+
110
+ **What Breaks**: Missing cache invalidation after writes → stale data. Wrong TTLs → excessive API calls or stale data.
111
+
112
+ ### 4. Progress Notification Pattern
113
+
114
+ Long-running operations emit MCP progress notifications:
115
+
116
+ ```typescript
117
+ // In tool handler
118
+ async function handleReconciliation(
119
+ input: ReconcileInput,
120
+ sendProgress?: ProgressCallback
121
+ ): Promise<ReconcileResult> {
122
+ await sendProgress?.({
123
+ progress: 50,
124
+ total: 100,
125
+ message: 'Matching transactions...',
126
+ });
127
+ }
128
+ ```
129
+
130
+ **Why Critical**: Provides user feedback for operations that take >5 seconds.
131
+
132
+ **What Breaks**: Missing optional chaining (`?.`) → TypeError if no progress callback. Missing progress updates → poor UX.
133
+
134
+ ### 5. Error Response Pattern
135
+
136
+ Always use `ErrorHandler.createErrorResponse()` for consistency:
137
+
138
+ ```typescript
139
+ return ErrorHandler.createErrorResponse(
140
+ 'OPERATION_FAILED',
141
+ 'Detailed error message',
142
+ {
143
+ operation: 'tool_name',
144
+ budgetId: input.budget_id,
145
+ }
146
+ );
147
+ ```
148
+
149
+ **Error Codes**:
150
+
151
+ - `MISSING_DEFAULT_BUDGET` - No default budget set
152
+ - `BUDGET_NOT_FOUND` - Budget ID doesn't exist
153
+ - `OPERATION_FAILED` - Generic operation failure
154
+ - `VALIDATION_ERROR` - Input validation failure
155
+ - `RATE_LIMIT_EXCEEDED` - YNAB API rate limit hit
156
+
157
+ **Why Critical**: Consistent error format allows clients to parse and handle errors reliably.
158
+
159
+ **What Breaks**: Throwing raw errors → inconsistent response format, poor error messages, no contextual data.
160
+
161
+ ### 6. Delta Caching Pattern
162
+
163
+ Use `deltaCache.fetchWithDelta()` for efficient updates:
164
+
165
+ ```typescript
166
+ const result = await deltaCache.fetchWithDelta({
167
+ cacheKey: `transactions:${budgetId}`,
168
+ fetchFn: (lastKnowledge) =>
169
+ ynabAPI.getTransactions(budgetId, lastKnowledge),
170
+ mergeFn: DeltaCache.mergeTransactions, // Built-in merge functions
171
+ });
172
+ ```
173
+
174
+ **Built-in Merge Functions**:
175
+
176
+ - `DeltaCache.mergeTransactions` - Merge transaction deltas
177
+ - `DeltaCache.mergeCategories` - Merge category deltas
178
+ - `DeltaCache.mergeAccounts` - Merge account deltas
179
+
180
+ **Why Critical**: Reduces API bandwidth, faster responses, respects YNAB rate limits.
181
+
182
+ **What Breaks**: Missing merge function → cache corruption. Incorrect cache keys → stale data. Not using Date.UTC → timezone bugs.
183
+
184
+ ## Dependencies
185
+
186
+ ### Imports From
187
+
188
+ - `@modelcontextprotocol/sdk` - MCP protocol types and schemas
189
+ - `ynab` - YNAB API client
190
+ - `zod` - Schema validation
191
+ - `../tools/` - Tool implementations
192
+ - `../types/` - Type definitions
193
+ - `../utils/` - Utility functions
194
+
195
+ ### Imported By
196
+
197
+ - `../index.ts` - Entry point
198
+ - `../tools/` - Tool implementations (via ToolContext)
199
+
200
+ ## Common Development Tasks
201
+
202
+ ### Adding a New MCP Capability
203
+
204
+ When adding new MCP features (tools, resources, prompts, completions):
205
+
206
+ 1. **Create handler module** in `src/server/` (e.g., `myFeature.ts`)
207
+ 2. **Implement with DI pattern**:
208
+ ```typescript
209
+ export class MyFeatureManager {
210
+ constructor(
211
+ private cacheManager: CacheManager,
212
+ private errorHandler: ErrorHandler
213
+ ) {}
214
+ }
215
+ ```
216
+ 3. **Register in YNABMCPServer**:
217
+ ```typescript
218
+ this.myFeatureManager = new MyFeatureManager(
219
+ this.cacheManager,
220
+ this.errorHandler
221
+ );
222
+ ```
223
+ 4. **Add MCP handler**:
224
+ ```typescript
225
+ server.setRequestHandler(MyFeatureSchema, async (request) => {
226
+ return this.myFeatureManager.handle(request.params);
227
+ });
228
+ ```
229
+ 5. **Add tests** in `src/server/__tests__/myFeature.test.ts`
230
+
231
+ ### Modifying Cache Behavior
232
+
233
+ To adjust cache TTLs or strategy:
234
+
235
+ 1. **Update TTL constants** in `cacheManager.ts`:
236
+ ```typescript
237
+ export const CACHE_TTLS = {
238
+ MY_RESOURCE: 5 * 60 * 1000, // 5 minutes
239
+ };
240
+ ```
241
+ 2. **Adjust stale-while-revalidate** for background refresh:
242
+ ```typescript
243
+ return cacheManager.wrap('key', {
244
+ ttl: CACHE_TTLS.MY_RESOURCE,
245
+ staleWhileRevalidate: 120000, // 2 min background refresh
246
+ loader: () => fetchData(),
247
+ });
248
+ ```
249
+ 3. **Add cache invalidation** after writes:
250
+ ```typescript
251
+ await updateResource();
252
+ this.cacheManager.delete(`resource:${id}`);
253
+ ```
254
+
255
+ ### Adding Progress Notifications
256
+
257
+ To add progress to a tool:
258
+
259
+ 1. **Update handler signature** to accept `ProgressCallback`:
260
+ ```typescript
261
+ async function handleMyTool(
262
+ input: MyInput,
263
+ sendProgress?: ProgressCallback
264
+ ): Promise<MyOutput>
265
+ ```
266
+ 2. **Emit progress updates**:
267
+ ```typescript
268
+ await sendProgress?.({
269
+ progress: currentStep,
270
+ total: totalSteps,
271
+ message: 'Processing...',
272
+ });
273
+ ```
274
+ 3. **Use optional chaining** (`?.`) to avoid errors when no callback
275
+
276
+ ### Adding MCP Completions
277
+
278
+ To add autocomplete for a new argument:
279
+
280
+ 1. **Update CompletionsManager** in `completions.ts`:
281
+ ```typescript
282
+ private async getMyFieldCompletions(
283
+ budgetId: string
284
+ ): Promise<Completion[]> {
285
+ const items = await this.fetchItems(budgetId);
286
+ return items.map(item => ({
287
+ label: item.name,
288
+ value: item.id,
289
+ }));
290
+ }
291
+ ```
292
+ 2. **Register in handleComplete**:
293
+ ```typescript
294
+ if (argument.name === 'my_field') {
295
+ return this.getMyFieldCompletions(budgetId);
296
+ }
297
+ ```
298
+
299
+ ## Testing Approach
300
+
301
+ ### Unit Tests
302
+
303
+ - **Location**: `src/server/__tests__/*.test.ts`
304
+ - **Mock**: All external dependencies (YNAB API, MCP SDK)
305
+ - **Coverage**: 80% minimum, 90% for critical files (cacheManager, errorHandler, toolRegistry)
306
+ - **Focus**: Business logic, error handling, edge cases
307
+
308
+ ### Integration Tests
309
+
310
+ - **Location**: `src/server/__tests__/*.integration.test.ts`
311
+ - **Mock**: YNAB API (use test fixtures)
312
+ - **Real**: MCP protocol flow, cache interactions
313
+ - **Focus**: End-to-end MCP request/response cycles
314
+
315
+ ### Example Unit Test
316
+
317
+ ```typescript
318
+ describe('CacheManager', () => {
319
+ it('should cache results with TTL', async () => {
320
+ const manager = new CacheManager({ maxEntries: 100 });
321
+ const loader = vi.fn(() => Promise.resolve({ data: 'test' }));
322
+
323
+ const result1 = await manager.wrap('key', { ttl: 5000, loader });
324
+ const result2 = await manager.wrap('key', { ttl: 5000, loader });
325
+
326
+ expect(result1).toEqual(result2);
327
+ expect(loader).toHaveBeenCalledTimes(1); // Cached!
328
+ });
329
+ });
330
+ ```
331
+
332
+ ## What Will Break If Violated
333
+
334
+ ### 1. Cache Invalidation After Writes
335
+
336
+ **Problem**: Write operations (create, update, delete) without cache invalidation.
337
+
338
+ **Impact**: Stale data returned to clients, inconsistent state.
339
+
340
+ **Fix**: Always invalidate related caches after writes:
341
+
342
+ ```typescript
343
+ await updateTransaction(transactionId, updates);
344
+ this.cacheManager.delete(`transaction:${transactionId}`);
345
+ this.cacheManager.delete(`transactions:${budgetId}`);
346
+ ```
347
+
348
+ ### 2. Missing ErrorHandler
349
+
350
+ **Problem**: Throwing raw errors or returning plain objects.
351
+
352
+ **Impact**: Inconsistent error format, poor error messages, no context.
353
+
354
+ **Fix**: Always use `ErrorHandler.createErrorResponse()`:
355
+
356
+ ```typescript
357
+ // BAD
358
+ throw new Error('Budget not found');
359
+
360
+ // GOOD
361
+ return ErrorHandler.createErrorResponse(
362
+ 'BUDGET_NOT_FOUND',
363
+ `Budget ${budgetId} not found`,
364
+ { budgetId }
365
+ );
366
+ ```
367
+
368
+ ### 3. Progress Callback Without Optional Chaining
369
+
370
+ **Problem**: Calling `sendProgress()` without `?.` operator.
371
+
372
+ **Impact**: TypeError when no progress callback provided.
373
+
374
+ **Fix**: Always use optional chaining:
375
+
376
+ ```typescript
377
+ // BAD
378
+ await sendProgress({ progress: 50, total: 100 });
379
+
380
+ // GOOD
381
+ await sendProgress?.({ progress: 50, total: 100 });
382
+ ```
383
+
384
+ ### 4. MCP Response Format Violations
385
+
386
+ **Problem**: Returning custom objects instead of MCP-compliant responses.
387
+
388
+ **Impact**: Protocol violations, client errors, failed requests.
389
+
390
+ **Fix**: Always return MCP-compliant response objects:
391
+
392
+ ```typescript
393
+ // Tool response
394
+ return {
395
+ content: [{ type: 'text', text: JSON.stringify(result) }],
396
+ };
397
+
398
+ // Resource response
399
+ return {
400
+ contents: [{ uri, mimeType: 'application/json', text: data }],
401
+ };
402
+ ```
403
+
404
+ ### 5. Missing Dependency Injection
405
+
406
+ **Problem**: Creating dependencies directly in classes (`new YnabAPI()`).
407
+
408
+ **Impact**: Untestable code, tight coupling, circular dependencies.
409
+
410
+ **Fix**: Always inject dependencies via constructor:
411
+
412
+ ```typescript
413
+ // BAD
414
+ class MyService {
415
+ private api = new YnabAPI();
416
+ }
417
+
418
+ // GOOD
419
+ class MyService {
420
+ constructor(private api: YnabAPI) {}
421
+ }
422
+ ```
423
+
424
+ ### 6. Hardcoded Configuration
425
+
426
+ **Problem**: Hardcoded API tokens, URLs, or configuration values.
427
+
428
+ **Impact**: Security issues, inflexible deployment, test failures.
429
+
430
+ **Fix**: Always use `config.ts` for environment-based configuration:
431
+
432
+ ```typescript
433
+ import { config } from './config.js';
434
+
435
+ const token = config.ynabAccessToken; // From env var
436
+ ```
437
+
438
+ ## Integration Points
439
+
440
+ ### With Tools (`src/tools/`)
441
+
442
+ - **ToolContext**: Injected into all tool factories with shared dependencies
443
+ - **Tool Registration**: Tools register via `toolRegistry.register()`
444
+ - **Cache Access**: Tools use `cacheManager` via ToolContext
445
+ - **Error Handling**: Tools use `errorHandler` via adapters
446
+
447
+ ### With Types (`src/types/`)
448
+
449
+ - **ToolContext**: Central DI object for tool dependencies
450
+ - **Handler Signatures**: Handler, DeltaHandler, WriteHandler, NoInputHandler
451
+ - **Error Classes**: BaseError, ValidationError, custom errors
452
+
453
+ ### With Utils (`src/utils/`)
454
+
455
+ - **Money Conversion**: milliunits ↔ dollars conversion
456
+ - **Date Utilities**: ISO date formatting, validation
457
+ - **Validation**: Amount validation, error formatting
458
+
459
+ ## Performance Considerations
460
+
461
+ 1. **Cache Aggressively**: Use long TTLs for rarely-changing data (budgets, categories)
462
+ 2. **Delta Requests**: Always prefer delta requests for large datasets (transactions)
463
+ 3. **Stale-While-Revalidate**: Use for non-critical data to improve response times
464
+ 4. **Rate Limiting**: Respect YNAB API limits (200 requests/hour)
465
+ 5. **Progress Notifications**: Use for operations >5 seconds to prevent timeouts
466
+
467
+ ## Security Considerations
468
+
469
+ 1. **Input Validation**: All tool inputs validated via Zod schemas
470
+ 2. **Security Middleware**: Wraps all tool handlers for consistent validation
471
+ 3. **Rate Limiting**: Prevents API abuse and YNAB rate limit violations
472
+ 4. **Error Sanitization**: Error responses never leak sensitive data (API tokens)
473
+ 5. **Budget ID Validation**: All budget IDs validated against YNAB API
474
+
475
+ ## Related Documentation
476
+
477
+ - [Root CLAUDE.md](../../CLAUDE.md) - Project overview and architecture
478
+ - [Tools CLAUDE.md](../tools/CLAUDE.md) - Tool implementation patterns
479
+ - [Types CLAUDE.md](../types/CLAUDE.md) - Type definitions and interfaces
480
+ - [Reconciliation Architecture](../../docs/technical/reconciliation-system-architecture.md) - Reconciliation system deep-dive