@dizzlkheinz/ynab-mcpb 0.12.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 (435) hide show
  1. package/.chunkhound.json +11 -0
  2. package/.code/agents/0427d95e-edca-431f-a214-5e53264e29c4/error.txt +8 -0
  3. package/.code/agents/0d675174-d1e1-41c3-9975-4c2e275819a9/error.txt +3 -0
  4. package/.code/agents/0d8c5afd-4787-422b-abf8-2e5943fc7e67/error.txt +3 -0
  5. package/.code/agents/0ec34a70-ed5d-4b9e-bee4-bb0e4cccbc4b/error.txt +1 -0
  6. package/.code/agents/0ef51a21-1ab1-49d7-9561-0eaa43875ebc/error.txt +12 -0
  7. package/.code/agents/15db95d7-abad-4b4d-9c3b-8446089cb61d/error.txt +1 -0
  8. package/.code/agents/19ab9acb-f675-4ff0-902a-09a5476f8149/error.txt +1 -0
  9. package/.code/agents/1ef7e12d-f6ff-4897-8a9b-152d523d898e/error.txt +5 -0
  10. package/.code/agents/2465/exec-call_lroN9KKzJVWC7t5423DK1nT9.txt +1453 -0
  11. package/.code/agents/28edb6fe-95a9-41a0-ae69-aa0100d26c0c/error.txt +8 -0
  12. package/.code/agents/2ae40cf5-b4bf-42e2-92bf-7ea350a7755e/error.txt +9 -0
  13. package/.code/agents/2bfc4e1f-ac4b-45a5-b6df-bf89d4dbb54c/error.txt +1 -0
  14. package/.code/agents/2e2e1134-eff0-49be-ba25-8e2c3468a564/error.txt +5 -0
  15. package/.code/agents/3/exec-call_203OC4TNVkLxW7z2HCVEQ1cM.txt +81 -0
  16. package/.code/agents/3/exec-call_SS5T0XSiXB4LSNzUKTl75wkh.txt +610 -0
  17. package/.code/agents/3322c003-ce5e-48e3-a342-f5049c5bf9a2/error.txt +1 -0
  18. package/.code/agents/391e9b08-1ebc-468c-9bcd-6d0cc3193b37/error.txt +1 -0
  19. package/.code/agents/3ab0aa84-b7bb-4054-afa3-40b8fd7d3be0/error.txt +1 -0
  20. package/.code/agents/3bed368d-50fe-477e-aee3-a6707eaa1ab9/error.txt +3 -0
  21. package/.code/agents/3e40b925-db12-442f-8d7a-a25fc69a6672/error.txt +8 -0
  22. package/.code/agents/414d5776-cf58-41f3-9328-a6daed503a50/error.txt +5 -0
  23. package/.code/agents/42687751-4565-4610-b240-67835b17d861/error.txt +1 -0
  24. package/.code/agents/46b98876-1a39-43c9-9e2f-507ca6d47335/error.txt +9 -0
  25. package/.code/agents/4a7d9491-b26f-43dd-850d-2ecdc49b5d1b/error.txt +1 -0
  26. package/.code/agents/4e60f00a-1b3e-447f-87f3-7faf9deddec3/error.txt +13 -0
  27. package/.code/agents/5138fc1c-4d49-4b74-a7da-ccdb3a8e44e7/error.txt +14 -0
  28. package/.code/agents/521cff39-a7a3-42e5-a557-134f0f7daaa0/error.txt +5 -0
  29. package/.code/agents/53302dc5-3857-4413-9a47-9e0f64a51dc4/error.txt +5 -0
  30. package/.code/agents/567c7c2e-6a6f-4761-a08d-d36deeb2e0ac/error.txt +5 -0
  31. package/.code/agents/57b00845-80dc-47c9-953c-3028d16275d6/error.txt +3 -0
  32. package/.code/agents/593d9005-c2a5-48fd-8813-ece0d3f2de96/error.txt +1 -0
  33. package/.code/agents/5a112e66-0e1a-42f9-877c-53af56ea3551/error.txt +1 -0
  34. package/.code/agents/5b05e8ed-7788-4738-b7ee-9faa8180f992/error.txt +5 -0
  35. package/.code/agents/5f888d6f-d7ca-4ac8-be23-9ea1bf753951/error.txt +5 -0
  36. package/.code/agents/607db3ab-e4b0-435b-b497-93e9aa525549/error.txt +8 -0
  37. package/.code/agents/67dcb2a2-900f-4c78-b3fc-80b5213e0ddf/error.txt +8 -0
  38. package/.code/agents/69ad848c-4e98-49b3-b16c-0094ac2d1759/error.txt +5 -0
  39. package/.code/agents/6c9cfc5f-0d0b-445c-b121-9f60082c4f70/error.txt +1 -0
  40. package/.code/agents/6f6f8f77-4ab0-4f6e-9f30-40e8be0bd8f5/error.txt +1 -0
  41. package/.code/agents/72a7cde4-fa8a-4024-9038-27faa550539b/error.txt +1 -0
  42. package/.code/agents/7b48335c-8247-43aa-9949-5f820ba8e199/error.txt +1 -0
  43. package/.code/agents/80944249-bea9-4ac5-87de-a666c4df306e/error.txt +1 -0
  44. package/.code/agents/826099df-1b66-4186-a915-7eb59f9db19d/error.txt +5 -0
  45. package/.code/agents/8291d158-18a8-4a92-b799-4e9a4d9cce88/error.txt +1 -0
  46. package/.code/agents/82fb71a3-20fb-4341-804a-a2fc900f95bc/error.txt +1 -0
  47. package/.code/agents/855790ea-54ee-43e4-8209-a66994e37590/error.txt +1 -0
  48. package/.code/agents/88ce3a2e-04f2-42be-9062-bf97aa798da0/error.txt +3 -0
  49. package/.code/agents/9a17e398-b6ed-4218-bb55-bc64a8d38ce8/error.txt +8 -0
  50. package/.code/agents/9a4f4bfc-a2a6-4f40-a896-9335b41a7ed1/error.txt +1 -0
  51. package/.code/agents/9b633e55-ef84-47d6-94bb-fd3dd172ad97/error.txt +1 -0
  52. package/.code/agents/9b81f3ab-c72b-4a81-9a8f-28a49ddba84a/error.txt +8 -0
  53. package/.code/agents/a35daf29-b2d1-4aef-9b42-dad63a76bd47/error.txt +3 -0
  54. package/.code/agents/a81990cc-69ee-44d2-b907-17403c9bc5d7/error.txt +5 -0
  55. package/.code/agents/ab56260a-4a83-4ad4-9410-f88a23d6520a/error.txt +1 -0
  56. package/.code/agents/ad722c31-2d1d-45f7-bae2-3f02ca455b60/error.txt +1 -0
  57. package/.code/agents/b62e8690-3324-4b97-9309-731bee79416b/error.txt +5 -0
  58. package/.code/agents/baf60a3a-752b-4ad8-99d6-df32423ed2eb/error.txt +1 -0
  59. package/.code/agents/be049042-7dcb-4ac8-9beb-c8f1aea67742/error.txt +14 -0
  60. package/.code/agents/bed1dcb4-bfce-4a9f-8594-0f994962aafd/error.txt +1 -0
  61. package/.code/agents/c324a6cf-e935-4ede-9529-b3ebc18e8d6b/error.txt +5 -0
  62. package/.code/agents/c37c06ff-dfe3-43f2-9bbc-3ec73ec8f41d/error.txt +5 -0
  63. package/.code/agents/c8cd6671-433a-456b-9f88-e51cb2df6bfc/error.txt +11 -0
  64. package/.code/agents/ca2ccb67-2f24-428e-b27d-9365beadd140/error.txt +1 -0
  65. package/.code/agents/cf08c0c8-e7f0-423e-93ba-547e8e818340/error.txt +8 -0
  66. package/.code/agents/d579c74f-874b-40a4-9d56-ced1eb6a701d/error.txt +1 -0
  67. package/.code/agents/df412c98-7378-4deb-8e1e-76c416931181/error.txt +3 -0
  68. package/.code/agents/e5134eb3-2af4-45b0-8998-051cb4afdb45/error.txt +3 -0
  69. package/.code/agents/e6308471-aa45-4e9e-9496-2e9404164d97/error.txt +8 -0
  70. package/.code/agents/e7bd8bc7-23fb-4f46-98dc-b0dcf11b75a1/error.txt +1 -0
  71. package/.code/agents/e92bec35-378d-4fe1-8ac0-6e1bb3c86911/error.txt +5 -0
  72. package/.code/agents/ed918fbf-2dc4-4aa2-bfc5-04b65d9471ea/error.txt +1 -0
  73. package/.code/agents/ef1d756f-b272-48fc-8729-f05c494674f7/error.txt +1 -0
  74. package/.code/agents/ef359853-0249-4e41-a804-c0fc459fe456/error.txt +1 -0
  75. package/.code/agents/effc7b4a-4b90-40a0-8c86-a7a99d2d5fd2/error.txt +1 -0
  76. package/.code/agents/fa15f8d5-8359-4a8b-83a3-2f2056b3ff40/error.txt +3 -0
  77. package/.code/agents/fbef4193-eadf-4c8a-83ff-4878a6310f25/error.txt +8 -0
  78. package/.code/agents/fd0a4b4a-fda4-4964-a6d6-2b8a2da387c6/error.txt +1 -0
  79. package/.dxtignore +57 -0
  80. package/.env.example +44 -0
  81. package/.gemini/settings.json +8 -0
  82. package/.github/ISSUE_TEMPLATE/bug_report.md +41 -0
  83. package/.github/ISSUE_TEMPLATE/config.yml +5 -0
  84. package/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
  85. package/.github/ISSUE_TEMPLATE/release_checklist.md +31 -0
  86. package/.github/pull_request_template.md +41 -0
  87. package/.github/workflows/ci-tests.yml +41 -0
  88. package/.github/workflows/claude-code-review.yml +57 -0
  89. package/.github/workflows/claude.yml +50 -0
  90. package/.github/workflows/full-integration.yml +22 -0
  91. package/.github/workflows/pr-description-check.yml +88 -0
  92. package/.github/workflows/publish.yml +33 -0
  93. package/.github/workflows/release.yml +89 -0
  94. package/.mcpbignore +58 -0
  95. package/.prettierignore +10 -0
  96. package/.prettierrc.json +10 -0
  97. package/ADOS-2-Module-1-Complete-Manual.md +757 -0
  98. package/AGENTS.md +36 -0
  99. package/CHANGELOG.md +187 -0
  100. package/CLAUDE.md +414 -0
  101. package/CODEREVIEW_RESPONSE.md +128 -0
  102. package/LICENSE +17 -0
  103. package/NUL +1 -0
  104. package/README.md +222 -0
  105. package/SCHEMA_IMPROVEMENT_SUMMARY.md +120 -0
  106. package/TESTING_NOTES.md +217 -0
  107. package/WARP.md +245 -0
  108. package/accountactivity-merged.csv +149 -0
  109. package/bin/ynab-mcp-server.cjs +4 -0
  110. package/bin/ynab-mcp-server.js +8 -0
  111. package/bundle-analysis.html +13110 -0
  112. package/dist/bundle/index.cjs +124 -0
  113. package/dist/index.d.ts +2 -0
  114. package/dist/index.js +85 -0
  115. package/dist/server/YNABMCPServer.d.ts +264 -0
  116. package/dist/server/YNABMCPServer.js +845 -0
  117. package/dist/server/budgetResolver.d.ts +15 -0
  118. package/dist/server/budgetResolver.js +99 -0
  119. package/dist/server/cacheManager.d.ts +74 -0
  120. package/dist/server/cacheManager.js +306 -0
  121. package/dist/server/config.d.ts +3 -0
  122. package/dist/server/config.js +19 -0
  123. package/dist/server/deltaCache.d.ts +61 -0
  124. package/dist/server/deltaCache.js +206 -0
  125. package/dist/server/deltaCache.merge.d.ts +9 -0
  126. package/dist/server/deltaCache.merge.js +111 -0
  127. package/dist/server/diagnostics.d.ts +90 -0
  128. package/dist/server/diagnostics.js +163 -0
  129. package/dist/server/errorHandler.d.ts +69 -0
  130. package/dist/server/errorHandler.js +524 -0
  131. package/dist/server/prompts.d.ts +31 -0
  132. package/dist/server/prompts.js +205 -0
  133. package/dist/server/rateLimiter.d.ts +27 -0
  134. package/dist/server/rateLimiter.js +82 -0
  135. package/dist/server/requestLogger.d.ts +62 -0
  136. package/dist/server/requestLogger.js +190 -0
  137. package/dist/server/resources.d.ts +39 -0
  138. package/dist/server/resources.js +85 -0
  139. package/dist/server/responseFormatter.d.ts +14 -0
  140. package/dist/server/responseFormatter.js +42 -0
  141. package/dist/server/securityMiddleware.d.ts +87 -0
  142. package/dist/server/securityMiddleware.js +117 -0
  143. package/dist/server/serverKnowledgeStore.d.ts +11 -0
  144. package/dist/server/serverKnowledgeStore.js +42 -0
  145. package/dist/server/toolRegistry.d.ts +85 -0
  146. package/dist/server/toolRegistry.js +272 -0
  147. package/dist/tools/__tests__/deltaTestUtils.d.ts +18 -0
  148. package/dist/tools/__tests__/deltaTestUtils.js +26 -0
  149. package/dist/tools/accountTools.d.ts +37 -0
  150. package/dist/tools/accountTools.js +175 -0
  151. package/dist/tools/budgetTools.d.ts +10 -0
  152. package/dist/tools/budgetTools.js +68 -0
  153. package/dist/tools/categoryTools.d.ts +27 -0
  154. package/dist/tools/categoryTools.js +232 -0
  155. package/dist/tools/compareTransactions/formatter.d.ts +71 -0
  156. package/dist/tools/compareTransactions/formatter.js +97 -0
  157. package/dist/tools/compareTransactions/index.d.ts +30 -0
  158. package/dist/tools/compareTransactions/index.js +160 -0
  159. package/dist/tools/compareTransactions/matcher.d.ts +12 -0
  160. package/dist/tools/compareTransactions/matcher.js +140 -0
  161. package/dist/tools/compareTransactions/parser.d.ts +14 -0
  162. package/dist/tools/compareTransactions/parser.js +430 -0
  163. package/dist/tools/compareTransactions/types.d.ts +27 -0
  164. package/dist/tools/compareTransactions/types.js +1 -0
  165. package/dist/tools/compareTransactions.d.ts +1 -0
  166. package/dist/tools/compareTransactions.js +1 -0
  167. package/dist/tools/deltaFetcher.d.ts +22 -0
  168. package/dist/tools/deltaFetcher.js +137 -0
  169. package/dist/tools/deltaSupport.d.ts +20 -0
  170. package/dist/tools/deltaSupport.js +176 -0
  171. package/dist/tools/exportTransactions.d.ts +17 -0
  172. package/dist/tools/exportTransactions.js +191 -0
  173. package/dist/tools/monthTools.d.ts +16 -0
  174. package/dist/tools/monthTools.js +107 -0
  175. package/dist/tools/payeeTools.d.ts +17 -0
  176. package/dist/tools/payeeTools.js +82 -0
  177. package/dist/tools/reconcileAdapter.d.ts +25 -0
  178. package/dist/tools/reconcileAdapter.js +167 -0
  179. package/dist/tools/reconciliation/analyzer.d.ts +3 -0
  180. package/dist/tools/reconciliation/analyzer.js +567 -0
  181. package/dist/tools/reconciliation/executor.d.ts +94 -0
  182. package/dist/tools/reconciliation/executor.js +611 -0
  183. package/dist/tools/reconciliation/index.d.ts +54 -0
  184. package/dist/tools/reconciliation/index.js +249 -0
  185. package/dist/tools/reconciliation/matcher.d.ts +3 -0
  186. package/dist/tools/reconciliation/matcher.js +160 -0
  187. package/dist/tools/reconciliation/payeeNormalizer.d.ts +6 -0
  188. package/dist/tools/reconciliation/payeeNormalizer.js +77 -0
  189. package/dist/tools/reconciliation/recommendationEngine.d.ts +2 -0
  190. package/dist/tools/reconciliation/recommendationEngine.js +273 -0
  191. package/dist/tools/reconciliation/reportFormatter.d.ts +13 -0
  192. package/dist/tools/reconciliation/reportFormatter.js +214 -0
  193. package/dist/tools/reconciliation/types.d.ts +172 -0
  194. package/dist/tools/reconciliation/types.js +7 -0
  195. package/dist/tools/schemas/outputs/accountOutputs.d.ts +58 -0
  196. package/dist/tools/schemas/outputs/accountOutputs.js +24 -0
  197. package/dist/tools/schemas/outputs/budgetOutputs.d.ts +48 -0
  198. package/dist/tools/schemas/outputs/budgetOutputs.js +15 -0
  199. package/dist/tools/schemas/outputs/categoryOutputs.d.ts +93 -0
  200. package/dist/tools/schemas/outputs/categoryOutputs.js +37 -0
  201. package/dist/tools/schemas/outputs/comparisonOutputs.d.ts +269 -0
  202. package/dist/tools/schemas/outputs/comparisonOutputs.js +181 -0
  203. package/dist/tools/schemas/outputs/index.d.ts +14 -0
  204. package/dist/tools/schemas/outputs/index.js +14 -0
  205. package/dist/tools/schemas/outputs/monthOutputs.d.ts +122 -0
  206. package/dist/tools/schemas/outputs/monthOutputs.js +51 -0
  207. package/dist/tools/schemas/outputs/payeeOutputs.d.ts +34 -0
  208. package/dist/tools/schemas/outputs/payeeOutputs.js +16 -0
  209. package/dist/tools/schemas/outputs/reconciliationOutputs.d.ts +1275 -0
  210. package/dist/tools/schemas/outputs/reconciliationOutputs.js +377 -0
  211. package/dist/tools/schemas/outputs/transactionMutationOutputs.d.ts +717 -0
  212. package/dist/tools/schemas/outputs/transactionMutationOutputs.js +260 -0
  213. package/dist/tools/schemas/outputs/transactionOutputs.d.ts +98 -0
  214. package/dist/tools/schemas/outputs/transactionOutputs.js +49 -0
  215. package/dist/tools/schemas/outputs/utilityOutputs.d.ts +219 -0
  216. package/dist/tools/schemas/outputs/utilityOutputs.js +120 -0
  217. package/dist/tools/schemas/shared/commonOutputs.d.ts +24 -0
  218. package/dist/tools/schemas/shared/commonOutputs.js +27 -0
  219. package/dist/tools/toolCategories.d.ts +32 -0
  220. package/dist/tools/toolCategories.js +32 -0
  221. package/dist/tools/transactionTools.d.ts +315 -0
  222. package/dist/tools/transactionTools.js +1722 -0
  223. package/dist/tools/utilityTools.d.ts +10 -0
  224. package/dist/tools/utilityTools.js +56 -0
  225. package/dist/types/index.d.ts +20 -0
  226. package/dist/types/index.js +16 -0
  227. package/dist/types/toolAnnotations.d.ts +7 -0
  228. package/dist/types/toolAnnotations.js +1 -0
  229. package/dist/utils/amountUtils.d.ts +3 -0
  230. package/dist/utils/amountUtils.js +10 -0
  231. package/dist/utils/dateUtils.d.ts +9 -0
  232. package/dist/utils/dateUtils.js +43 -0
  233. package/dist/utils/money.d.ts +21 -0
  234. package/dist/utils/money.js +51 -0
  235. package/docs/README.md +72 -0
  236. package/docs/assets/examples/reconciliation-with-recommendations.json +68 -0
  237. package/docs/assets/schemas/reconciliation-v2.json +338 -0
  238. package/docs/getting-started/CONFIGURATION.md +175 -0
  239. package/docs/getting-started/INSTALLATION.md +333 -0
  240. package/docs/getting-started/QUICKSTART.md +282 -0
  241. package/docs/guides/ARCHITECTURE.md +650 -0
  242. package/docs/guides/DEPLOYMENT.md +189 -0
  243. package/docs/guides/INTEGRATION_TESTING.md +730 -0
  244. package/docs/guides/TESTING.md +591 -0
  245. package/docs/reconciliation-flow.md +83 -0
  246. package/docs/reference/API.md +1450 -0
  247. package/docs/reference/EXAMPLES.md +946 -0
  248. package/docs/reference/TOOLS.md +348 -0
  249. package/docs/reference/TROUBLESHOOTING.md +481 -0
  250. package/esbuild.config.mjs +68 -0
  251. package/eslint.config.js +49 -0
  252. package/fix-types.sh +17 -0
  253. package/meta.json +12550 -0
  254. package/package.json +105 -0
  255. package/package.json.tmp +105 -0
  256. package/scripts/analyze-bundle.mjs +41 -0
  257. package/scripts/create-pr-description.js +203 -0
  258. package/scripts/generate-mcpb.ps1 +96 -0
  259. package/scripts/run-domain-integration-tests.js +33 -0
  260. package/scripts/run-generate-mcpb.js +29 -0
  261. package/scripts/run-throttled-integration-tests.js +116 -0
  262. package/scripts/test-delta-params.mjs +140 -0
  263. package/scripts/test-recommendations.ts +53 -0
  264. package/scripts/tmpTransaction.ts +48 -0
  265. package/scripts/validate-env.js +122 -0
  266. package/scripts/verify-build.js +105 -0
  267. package/scripts/watch-and-restart.ps1 +50 -0
  268. package/src/__tests__/comprehensive.integration.test.ts +1196 -0
  269. package/src/__tests__/delta.performance.test.ts +80 -0
  270. package/src/__tests__/performance.test.ts +725 -0
  271. package/src/__tests__/setup.ts +449 -0
  272. package/src/__tests__/testRunner.ts +444 -0
  273. package/src/__tests__/testUtils.ts +563 -0
  274. package/src/__tests__/workflows.e2e.test.ts +1675 -0
  275. package/src/index.ts +124 -0
  276. package/src/server/.gitkeep +1 -0
  277. package/src/server/YNABMCPServer.ts +1188 -0
  278. package/src/server/__tests__/YNABMCPServer.integration.test.ts +903 -0
  279. package/src/server/__tests__/YNABMCPServer.test.ts +894 -0
  280. package/src/server/__tests__/budgetResolver.test.ts +425 -0
  281. package/src/server/__tests__/cacheManager.test.ts +880 -0
  282. package/src/server/__tests__/config.test.ts +166 -0
  283. package/src/server/__tests__/deltaCache.merge.test.ts +724 -0
  284. package/src/server/__tests__/deltaCache.swr.test.ts +168 -0
  285. package/src/server/__tests__/deltaCache.test.ts +774 -0
  286. package/src/server/__tests__/diagnostics.test.ts +823 -0
  287. package/src/server/__tests__/errorHandler.integration.test.ts +466 -0
  288. package/src/server/__tests__/errorHandler.test.ts +416 -0
  289. package/src/server/__tests__/prompts.test.ts +354 -0
  290. package/src/server/__tests__/rateLimiter.test.ts +314 -0
  291. package/src/server/__tests__/requestLogger.test.ts +408 -0
  292. package/src/server/__tests__/resources.test.ts +299 -0
  293. package/src/server/__tests__/security.integration.test.ts +426 -0
  294. package/src/server/__tests__/securityMiddleware.test.ts +449 -0
  295. package/src/server/__tests__/server-startup.integration.test.ts +477 -0
  296. package/src/server/__tests__/serverKnowledgeStore.test.ts +174 -0
  297. package/src/server/__tests__/toolRegistry.test.ts +855 -0
  298. package/src/server/budgetResolver.ts +235 -0
  299. package/src/server/cacheManager.ts +503 -0
  300. package/src/server/config.ts +41 -0
  301. package/src/server/deltaCache.merge.ts +149 -0
  302. package/src/server/deltaCache.ts +341 -0
  303. package/src/server/diagnostics.ts +338 -0
  304. package/src/server/errorHandler.ts +756 -0
  305. package/src/server/prompts.ts +291 -0
  306. package/src/server/rateLimiter.ts +156 -0
  307. package/src/server/requestLogger.ts +344 -0
  308. package/src/server/resources.ts +168 -0
  309. package/src/server/responseFormatter.ts +51 -0
  310. package/src/server/securityMiddleware.ts +236 -0
  311. package/src/server/serverKnowledgeStore.ts +91 -0
  312. package/src/server/toolRegistry.ts +489 -0
  313. package/src/tools/.gitkeep +1 -0
  314. package/src/tools/__tests__/accountTools.delta.integration.test.ts +128 -0
  315. package/src/tools/__tests__/accountTools.integration.test.ts +117 -0
  316. package/src/tools/__tests__/accountTools.test.ts +653 -0
  317. package/src/tools/__tests__/budgetTools.delta.integration.test.ts +90 -0
  318. package/src/tools/__tests__/budgetTools.integration.test.ts +134 -0
  319. package/src/tools/__tests__/budgetTools.test.ts +423 -0
  320. package/src/tools/__tests__/categoryTools.delta.integration.test.ts +80 -0
  321. package/src/tools/__tests__/categoryTools.integration.test.ts +295 -0
  322. package/src/tools/__tests__/categoryTools.test.ts +622 -0
  323. package/src/tools/__tests__/compareTransactions/formatter.test.ts +486 -0
  324. package/src/tools/__tests__/compareTransactions/index.test.ts +383 -0
  325. package/src/tools/__tests__/compareTransactions/matcher.test.ts +410 -0
  326. package/src/tools/__tests__/compareTransactions/parser.test.ts +764 -0
  327. package/src/tools/__tests__/compareTransactions.test.ts +342 -0
  328. package/src/tools/__tests__/compareTransactions.window.test.ts +147 -0
  329. package/src/tools/__tests__/deltaFetcher.scheduled.integration.test.ts +76 -0
  330. package/src/tools/__tests__/deltaFetcher.test.ts +270 -0
  331. package/src/tools/__tests__/deltaSupport.test.ts +188 -0
  332. package/src/tools/__tests__/deltaTestUtils.ts +46 -0
  333. package/src/tools/__tests__/exportTransactions.test.ts +213 -0
  334. package/src/tools/__tests__/monthTools.delta.integration.test.ts +80 -0
  335. package/src/tools/__tests__/monthTools.integration.test.ts +174 -0
  336. package/src/tools/__tests__/monthTools.test.ts +523 -0
  337. package/src/tools/__tests__/payeeTools.delta.integration.test.ts +80 -0
  338. package/src/tools/__tests__/payeeTools.integration.test.ts +150 -0
  339. package/src/tools/__tests__/payeeTools.test.ts +445 -0
  340. package/src/tools/__tests__/transactionTools.integration.test.ts +762 -0
  341. package/src/tools/__tests__/transactionTools.test.ts +3521 -0
  342. package/src/tools/__tests__/utilityTools.integration.test.ts +128 -0
  343. package/src/tools/__tests__/utilityTools.test.ts +205 -0
  344. package/src/tools/accountTools.ts +283 -0
  345. package/src/tools/budgetTools.ts +112 -0
  346. package/src/tools/categoryTools.ts +366 -0
  347. package/src/tools/compareTransactions/formatter.ts +163 -0
  348. package/src/tools/compareTransactions/index.ts +228 -0
  349. package/src/tools/compareTransactions/matcher.ts +240 -0
  350. package/src/tools/compareTransactions/parser.ts +557 -0
  351. package/src/tools/compareTransactions/types.ts +60 -0
  352. package/src/tools/compareTransactions.ts +3 -0
  353. package/src/tools/deltaFetcher.ts +278 -0
  354. package/src/tools/deltaSupport.ts +293 -0
  355. package/src/tools/exportTransactions.ts +273 -0
  356. package/src/tools/monthTools.ts +164 -0
  357. package/src/tools/payeeTools.ts +140 -0
  358. package/src/tools/reconcileAdapter.ts +312 -0
  359. package/src/tools/reconciliation/__tests__/adapter.causes.test.ts +122 -0
  360. package/src/tools/reconciliation/__tests__/adapter.test.ts +234 -0
  361. package/src/tools/reconciliation/__tests__/analyzer.test.ts +406 -0
  362. package/src/tools/reconciliation/__tests__/executor.integration.test.ts +366 -0
  363. package/src/tools/reconciliation/__tests__/executor.test.ts +779 -0
  364. package/src/tools/reconciliation/__tests__/matcher.test.ts +650 -0
  365. package/src/tools/reconciliation/__tests__/payeeNormalizer.test.ts +278 -0
  366. package/src/tools/reconciliation/__tests__/recommendationEngine.integration.test.ts +658 -0
  367. package/src/tools/reconciliation/__tests__/recommendationEngine.test.ts +1000 -0
  368. package/src/tools/reconciliation/__tests__/reconciliation.delta.integration.test.ts +151 -0
  369. package/src/tools/reconciliation/__tests__/reportFormatter.test.ts +573 -0
  370. package/src/tools/reconciliation/__tests__/scenarios/adapterCurrency.scenario.test.ts +78 -0
  371. package/src/tools/reconciliation/__tests__/scenarios/extremes.scenario.test.ts +47 -0
  372. package/src/tools/reconciliation/__tests__/scenarios/repeatAmount.scenario.test.ts +61 -0
  373. package/src/tools/reconciliation/__tests__/schemaUrl.test.ts +49 -0
  374. package/src/tools/reconciliation/analyzer.ts +824 -0
  375. package/src/tools/reconciliation/executor.ts +880 -0
  376. package/src/tools/reconciliation/index.ts +400 -0
  377. package/src/tools/reconciliation/matcher.ts +269 -0
  378. package/src/tools/reconciliation/payeeNormalizer.ts +167 -0
  379. package/src/tools/reconciliation/recommendationEngine.ts +506 -0
  380. package/src/tools/reconciliation/reportFormatter.ts +363 -0
  381. package/src/tools/reconciliation/types.ts +314 -0
  382. package/src/tools/schemas/outputs/__tests__/accountOutputs.test.ts +424 -0
  383. package/src/tools/schemas/outputs/__tests__/budgetOutputs.test.ts +310 -0
  384. package/src/tools/schemas/outputs/__tests__/categoryOutputs.test.ts +448 -0
  385. package/src/tools/schemas/outputs/__tests__/comparisonOutputs.test.ts +519 -0
  386. package/src/tools/schemas/outputs/__tests__/dateValidation.test.ts +155 -0
  387. package/src/tools/schemas/outputs/__tests__/discrepancyDirection.test.ts +288 -0
  388. package/src/tools/schemas/outputs/__tests__/monthOutputs.test.ts +478 -0
  389. package/src/tools/schemas/outputs/__tests__/payeeOutputs.test.ts +370 -0
  390. package/src/tools/schemas/outputs/__tests__/reconciliationOutputs.test.ts +401 -0
  391. package/src/tools/schemas/outputs/__tests__/transactionMutationSchemas.test.ts +213 -0
  392. package/src/tools/schemas/outputs/__tests__/transactionOutputs.test.ts +474 -0
  393. package/src/tools/schemas/outputs/__tests__/utilityOutputs.test.ts +333 -0
  394. package/src/tools/schemas/outputs/accountOutputs.ts +137 -0
  395. package/src/tools/schemas/outputs/budgetOutputs.ts +86 -0
  396. package/src/tools/schemas/outputs/categoryOutputs.ts +194 -0
  397. package/src/tools/schemas/outputs/comparisonOutputs.ts +600 -0
  398. package/src/tools/schemas/outputs/index.ts +270 -0
  399. package/src/tools/schemas/outputs/monthOutputs.ts +243 -0
  400. package/src/tools/schemas/outputs/payeeOutputs.ts +105 -0
  401. package/src/tools/schemas/outputs/reconciliationOutputs.ts +796 -0
  402. package/src/tools/schemas/outputs/transactionMutationOutputs.ts +758 -0
  403. package/src/tools/schemas/outputs/transactionOutputs.ts +243 -0
  404. package/src/tools/schemas/outputs/utilityOutputs.ts +411 -0
  405. package/src/tools/schemas/shared/commonOutputs.ts +140 -0
  406. package/src/tools/toolCategories.ts +140 -0
  407. package/src/tools/transactionTools.ts +2509 -0
  408. package/src/tools/utilityTools.ts +90 -0
  409. package/src/types/.gitkeep +1 -0
  410. package/src/types/__tests__/index.test.ts +52 -0
  411. package/src/types/index.ts +67 -0
  412. package/src/types/integration-tests.d.ts +35 -0
  413. package/src/types/toolAnnotations.ts +44 -0
  414. package/src/utils/__tests__/dateUtils.test.ts +170 -0
  415. package/src/utils/__tests__/money.test.ts +189 -0
  416. package/src/utils/amountUtils.ts +32 -0
  417. package/src/utils/dateUtils.ts +108 -0
  418. package/src/utils/money.ts +123 -0
  419. package/test-csv-sample.csv +28 -0
  420. package/test-exports/sample_bank_statement.csv +7 -0
  421. package/test-exports/ynab_account_e9ddc2a6_minimal_1items_2025-11-19_09-04-53.json +23 -0
  422. package/test-exports/ynab_account_e9ddc2a6_minimal_1items_2025-11-19_10-37-42.json +23 -0
  423. package/test-exports/ynab_account_e9ddc2a6_minimal_4items_2025-11-19_09-02-09.json +44 -0
  424. package/test-exports/ynab_account_e9ddc2a6_minimal_6items_2025-11-19_10-37-52.json +58 -0
  425. package/test-exports/ynab_since_2025-11-01_account_4c18e9f0_minimal_14items_2025-11-16_10-07-10.json +115 -0
  426. package/test-reconcile-autodetect.js +40 -0
  427. package/test-reconcile-tool.js +152 -0
  428. package/test-reconcile-with-csv.cjs +89 -0
  429. package/test-statement.csv +8 -0
  430. package/test_debug.js +47 -0
  431. package/test_simple.mjs +16 -0
  432. package/tsconfig.json +31 -0
  433. package/tsconfig.prod.json +18 -0
  434. package/vitest-reporters/split-json-reporter.ts +211 -0
  435. package/vitest.config.ts +96 -0
package/package.json ADDED
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "@dizzlkheinz/ynab-mcpb",
3
+ "version": "0.12.1",
4
+ "description": "Model Context Protocol server for YNAB (You Need A Budget) integration",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "ynab-mcp-server": "bin/ynab-mcp-server.cjs"
9
+ },
10
+ "scripts": {
11
+ "prebuild": "npm run clean",
12
+ "build": "npm run build:prod",
13
+ "postbuild": "node scripts/run-generate-mcpb.js",
14
+ "build:dev": "npm run clean && tsc && npm run bundle",
15
+ "build:no-lint": "npm run clean && tsc && npm run bundle:prod",
16
+ "build:prod": "npm run lint:fix && npm run prebuild && tsc --project tsconfig.prod.json && npm run bundle:prod && npm run verify-build",
17
+ "clean": "rimraf dist",
18
+ "dev": "tsc --watch",
19
+ "start": "node -r dotenv/config dist/index.js",
20
+ "start:prod": "NODE_ENV=production node dist/index.js",
21
+ "start:mcp": "node dist/index.js",
22
+ "validate-env": "node scripts/validate-env.js",
23
+ "verify-build": "node scripts/verify-build.js",
24
+ "lint": "npm run lint:eslint && npm run format:check",
25
+ "lint:eslint": "eslint src --ext .ts",
26
+ "lint:fix": "eslint src --ext .ts --fix && prettier --write .",
27
+ "format": "prettier --write .",
28
+ "format:check": "prettier --check .",
29
+ "type-check": "tsc --noEmit",
30
+ "test": "vitest run --project unit && npm run filter-test-results",
31
+ "test:watch": "vitest",
32
+ "test:unit": "vitest run --project unit",
33
+ "test:integration": "npm run test:integration:core",
34
+ "test:integration:core": "vitest run --project integration:core",
35
+ "test:integration:domain": "vitest run --project integration:domain",
36
+ "test:integration:full": "node scripts/run-throttled-integration-tests.js",
37
+ "test:integration:budgets": "node scripts/run-domain-integration-tests.js budgets",
38
+ "test:integration:accounts": "node scripts/run-domain-integration-tests.js accounts",
39
+ "test:integration:transactions": "node scripts/run-domain-integration-tests.js transactions",
40
+ "test:integration:categories": "node scripts/run-domain-integration-tests.js categories",
41
+ "test:integration:payees": "node scripts/run-domain-integration-tests.js payees",
42
+ "test:integration:months": "node scripts/run-domain-integration-tests.js months",
43
+ "test:integration:delta": "node scripts/run-domain-integration-tests.js delta",
44
+ "test:integration:reconciliation": "node scripts/run-domain-integration-tests.js reconciliation",
45
+ "test:e2e": "vitest run --project e2e",
46
+ "test:coverage": "vitest run --coverage --project unit",
47
+ "test:performance": "vitest run src/__tests__/performance.test.ts",
48
+ "test:comprehensive": "tsx src/__tests__/testRunner.ts",
49
+ "test:all": "npm run test:unit && npm run test:integration:core && npm run test:e2e && npm run test:performance",
50
+ "filter-test-results": "node -e \"const fs = require('fs'); try { const results = JSON.parse(fs.readFileSync('test-results.json', 'utf-8')); if (!results.quickStats || !results.quickStats.success) { console.warn('Tests failed. See test-results/failed-tests.json for details.'); } } catch (e) { console.warn('Could not read test results:', e.message); }\"",
51
+ "generate:mcpb": "node scripts/run-generate-mcpb.js",
52
+ "bundle": "node esbuild.config.mjs",
53
+ "bundle:prod": "node esbuild.config.mjs --production",
54
+ "package:mcpb": "npm run build:prod && npm run generate:mcpb",
55
+ "pr:description": "node scripts/create-pr-description.js",
56
+ "pr:create": "npm run pr:description && gh pr create --body-file .pr-description.md",
57
+ "prepare": "npm run build:prod",
58
+ "prepublishOnly": "npm run test:unit && npm run build:prod"
59
+ },
60
+ "keywords": [
61
+ "mcp",
62
+ "ynab",
63
+ "budget",
64
+ "finance"
65
+ ],
66
+ "author": "",
67
+ "license": "AGPL-3.0",
68
+ "dependencies": {
69
+ "@modelcontextprotocol/sdk": "^1.22.0",
70
+ "csv-parse": "^6.1.0",
71
+ "d3-array": "^3.2.4",
72
+ "date-fns": "^4.1.0",
73
+ "dotenv": "^17.2.1",
74
+ "ynab": "^2.9.0",
75
+ "zod": "^4.1.11"
76
+ },
77
+ "devDependencies": {
78
+ "@eslint/js": "^9.35.0",
79
+ "@types/d3-array": "^3.2.1",
80
+ "@types/node": "^24.5.2",
81
+ "@vitest/coverage-v8": "^3.2.4",
82
+ "@vitest/ui": "^3.2.4",
83
+ "esbuild": "^0.25.10",
84
+ "eslint": "^9.35.0",
85
+ "eslint-config-prettier": "^10.1.8",
86
+ "prettier": "^3.3.3",
87
+ "rimraf": "^6.0.1",
88
+ "tsx": "^4.20.6",
89
+ "typescript": "^5.9.2",
90
+ "typescript-eslint": "^8.42.0",
91
+ "vitest": "^3.2.4"
92
+ },
93
+ "directories": {
94
+ "doc": "docs"
95
+ },
96
+ "repository": {
97
+ "type": "git",
98
+ "url": "git+https://github.com/dizzlkheinz/ynab-mcpb.git"
99
+ },
100
+ "types": "./dist/index.d.ts",
101
+ "bugs": {
102
+ "url": "https://github.com/dizzlkheinz/ynab-mcpb/issues"
103
+ },
104
+ "homepage": "https://github.com/dizzlkheinz/ynab-mcpb#readme"
105
+ }
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "@dizzlkheinz/ynab-mcp-server",
3
+ "version": "0.12.0",
4
+ "description": "Model Context Protocol server for YNAB (You Need A Budget) integration",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "ynab-mcp-server": "bin/ynab-mcp-server.cjs"
9
+ },
10
+ "scripts": {
11
+ "prebuild": "npm run clean",
12
+ "build": "npm run build:prod",
13
+ "postbuild": "node scripts/run-generate-mcpb.js",
14
+ "build:dev": "npm run clean && tsc && npm run bundle",
15
+ "build:no-lint": "npm run clean && tsc && npm run bundle:prod",
16
+ "build:prod": "npm run lint:fix && npm run prebuild && tsc --project tsconfig.prod.json && npm run bundle:prod && npm run verify-build",
17
+ "clean": "rimraf dist",
18
+ "dev": "tsc --watch",
19
+ "start": "node -r dotenv/config dist/index.js",
20
+ "start:prod": "NODE_ENV=production node dist/index.js",
21
+ "start:mcp": "node dist/index.js",
22
+ "validate-env": "node scripts/validate-env.js",
23
+ "verify-build": "node scripts/verify-build.js",
24
+ "lint": "npm run lint:eslint && npm run format:check",
25
+ "lint:eslint": "eslint src --ext .ts",
26
+ "lint:fix": "eslint src --ext .ts --fix && prettier --write .",
27
+ "format": "prettier --write .",
28
+ "format:check": "prettier --check .",
29
+ "type-check": "tsc --noEmit",
30
+ "test": "vitest run --project unit && npm run filter-test-results",
31
+ "test:watch": "vitest",
32
+ "test:unit": "vitest run --project unit",
33
+ "test:integration": "npm run test:integration:core",
34
+ "test:integration:core": "vitest run --project integration:core",
35
+ "test:integration:domain": "vitest run --project integration:domain",
36
+ "test:integration:full": "node scripts/run-throttled-integration-tests.js",
37
+ "test:integration:budgets": "node scripts/run-domain-integration-tests.js budgets",
38
+ "test:integration:accounts": "node scripts/run-domain-integration-tests.js accounts",
39
+ "test:integration:transactions": "node scripts/run-domain-integration-tests.js transactions",
40
+ "test:integration:categories": "node scripts/run-domain-integration-tests.js categories",
41
+ "test:integration:payees": "node scripts/run-domain-integration-tests.js payees",
42
+ "test:integration:months": "node scripts/run-domain-integration-tests.js months",
43
+ "test:integration:delta": "node scripts/run-domain-integration-tests.js delta",
44
+ "test:integration:reconciliation": "node scripts/run-domain-integration-tests.js reconciliation",
45
+ "test:e2e": "vitest run --project e2e",
46
+ "test:coverage": "vitest run --coverage --project unit",
47
+ "test:performance": "vitest run src/__tests__/performance.test.ts",
48
+ "test:comprehensive": "tsx src/__tests__/testRunner.ts",
49
+ "test:all": "npm run test:unit && npm run test:integration:core && npm run test:e2e && npm run test:performance",
50
+ "filter-test-results": "node -e \"const fs = require('fs'); try { const results = JSON.parse(fs.readFileSync('test-results.json', 'utf-8')); results.testResults = results.testResults.filter(r => r.status === 'fail'); fs.writeFileSync('test-results.json', JSON.stringify(results, null, 2)); } catch (e) { console.error('Failed to filter test results:', e); process.exit(1); }\"",
51
+ "generate:mcpb": "node scripts/run-generate-mcpb.js",
52
+ "bundle": "node esbuild.config.mjs",
53
+ "bundle:prod": "node esbuild.config.mjs --production",
54
+ "package:mcpb": "npm run build:prod && npm run generate:mcpb",
55
+ "pr:description": "node scripts/create-pr-description.js",
56
+ "pr:create": "npm run pr:description && gh pr create --body-file .pr-description.md",
57
+ "prepare": "npm run build:prod",
58
+ "prepublishOnly": "npm run test:unit && npm run build:prod"
59
+ },
60
+ "keywords": [
61
+ "mcp",
62
+ "ynab",
63
+ "budget",
64
+ "finance"
65
+ ],
66
+ "author": "",
67
+ "license": "AGPL-3.0",
68
+ "dependencies": {
69
+ "@modelcontextprotocol/sdk": "^1.22.0",
70
+ "csv-parse": "^6.1.0",
71
+ "d3-array": "^3.2.4",
72
+ "date-fns": "^4.1.0",
73
+ "dotenv": "^17.2.1",
74
+ "ynab": "^2.9.0",
75
+ "zod": "^4.1.11"
76
+ },
77
+ "devDependencies": {
78
+ "@eslint/js": "^9.35.0",
79
+ "@types/d3-array": "^3.2.1",
80
+ "@types/node": "^24.5.2",
81
+ "@vitest/coverage-v8": "^3.2.4",
82
+ "@vitest/ui": "^3.2.4",
83
+ "esbuild": "^0.25.10",
84
+ "eslint": "^9.35.0",
85
+ "eslint-config-prettier": "^10.1.8",
86
+ "prettier": "^3.3.3",
87
+ "rimraf": "^6.0.1",
88
+ "tsx": "^4.20.6",
89
+ "typescript": "^5.9.2",
90
+ "typescript-eslint": "^8.42.0",
91
+ "vitest": "^3.2.4"
92
+ },
93
+ "directories": {
94
+ "doc": "docs"
95
+ },
96
+ "repository": {
97
+ "type": "git",
98
+ "url": "git+https://github.com/dizzlkheinz/ynab-mcp-dxt.git"
99
+ },
100
+ "types": "./dist/index.d.ts",
101
+ "bugs": {
102
+ "url": "https://github.com/dizzlkheinz/ynab-mcp-dxt/issues"
103
+ },
104
+ "homepage": "https://github.com/dizzlkheinz/ynab-mcp-dxt#readme"
105
+ }
@@ -0,0 +1,41 @@
1
+ import fs from 'fs';
2
+
3
+ let meta;
4
+ try {
5
+ meta = JSON.parse(fs.readFileSync('meta.json', 'utf-8'));
6
+ } catch (error) {
7
+ console.error('❌ Error reading meta.json:', error.message);
8
+ process.exit(1);
9
+ }
10
+ if (!meta.inputs || typeof meta.inputs !== 'object') {
11
+ console.error('❌ Error: meta.inputs is missing or invalid in meta.json');
12
+ process.exit(1);
13
+ }
14
+
15
+ const inputs = Object.entries(meta.inputs)
16
+ .map(([path, data]) => ({
17
+ path,
18
+ bytes: data.bytes,
19
+ }))
20
+ .sort((a, b) => b.bytes - a.bytes)
21
+ .slice(0, 20);
22
+
23
+ const totalBytes = Object.values(meta.inputs).reduce((sum, item) => sum + item.bytes, 0);
24
+ console.log(`\n📦 Total input size: ${(totalBytes / 1024 / 1024).toFixed(2)} MB`);
25
+ const outputKey = 'dist/bundle/index.cjs';
26
+ if (!meta.outputs || !meta.outputs[outputKey]) {
27
+ console.error(`❌ Error: meta.outputs['${outputKey}'] is missing in meta.json`);
28
+ process.exit(1);
29
+ }
30
+ console.log(`📦 Output size: ${(meta.outputs[outputKey].bytes / 1024 / 1024).toFixed(2)} MB`);
31
+ console.log('\n📊 Top 20 largest inputs in bundle:\n');
32
+ inputs.forEach((item) => {
33
+ const kb = (item.bytes / 1024).toFixed(1).padStart(8);
34
+ console.log(`${kb} KB ${item.path}`);
35
+ }); const kb = (item.bytes / 1024).toFixed(1).padStart(8);
36
+ console.log(`${kb} KB ${item.path}`);
37
+ });
38
+
39
+ const totalBytes = Object.values(meta.inputs).reduce((sum, item) => sum + item.bytes, 0);
40
+ console.log(`\n📦 Total input size: ${(totalBytes / 1024 / 1024).toFixed(2)} MB`);
41
+ console.log(`📦 Output size: ${(meta.outputs['dist/bundle/index.cjs'].bytes / 1024 / 1024).toFixed(2)} MB`);
@@ -0,0 +1,203 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Generates a PR description from template with smart defaults
4
+ * Usage: node scripts/create-pr-description.js [options]
5
+ */
6
+
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ import { fileURLToPath } from 'url';
10
+ import { execSync } from 'child_process';
11
+
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = path.dirname(__filename);
14
+
15
+ // Read the PR template
16
+ const templatePath = path.join(__dirname, '..', '.github', 'pull_request_template.md');
17
+ const template = fs.readFileSync(templatePath, 'utf-8');
18
+
19
+ // Function to detect the repository's default branch
20
+ function getDefaultBranch() {
21
+ try {
22
+ // Try to get the default branch from origin/HEAD
23
+ const defaultBranch = execSync('git symbolic-ref refs/remotes/origin/HEAD', {
24
+ encoding: 'utf-8',
25
+ })
26
+ .trim()
27
+ .replace('refs/remotes/origin/', '');
28
+ return defaultBranch;
29
+ } catch (err) {
30
+ // Fallback: try common branch names
31
+ try {
32
+ execSync('git rev-parse --verify origin/main', { encoding: 'utf-8', stdio: 'ignore' });
33
+ return 'main';
34
+ } catch {
35
+ try {
36
+ execSync('git rev-parse --verify origin/master', { encoding: 'utf-8', stdio: 'ignore' });
37
+ return 'master';
38
+ } catch {
39
+ console.warn('Could not detect default branch, using "main" as fallback');
40
+ return 'main';
41
+ }
42
+ }
43
+ }
44
+ }
45
+
46
+ // Read package.json for version info
47
+ const packageJson = JSON.parse(
48
+ fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8'),
49
+ );
50
+
51
+ // Read CHANGELOG.md if it exists
52
+ let changelogEntries = '';
53
+ try {
54
+ const changelog = fs.readFileSync(path.join(__dirname, '..', 'CHANGELOG.md'), 'utf-8');
55
+ // Extract the latest version entries
56
+ const latestSection = changelog.split('##')[1];
57
+ changelogEntries = latestSection ? `## Latest Changes\n\n${latestSection}` : '';
58
+ } catch (err) {
59
+ // No changelog
60
+ }
61
+
62
+ // Detect the default branch
63
+ const defaultBranch = getDefaultBranch();
64
+
65
+ // Get git info
66
+ let commitMessages = '';
67
+ try {
68
+ const branch = execSync('git branch --show-current', { encoding: 'utf-8' }).trim();
69
+
70
+ // Get commit messages since branching from default branch
71
+ const commits = execSync(`git log ${defaultBranch}..${branch} --pretty=format:"- %s"`, {
72
+ encoding: 'utf-8',
73
+ }).trim();
74
+
75
+ if (commits) {
76
+ commitMessages = `## Commits\n\n${commits}\n\n`;
77
+ }
78
+ } catch (err) {
79
+ console.warn('Could not get git commit info');
80
+ }
81
+
82
+ // Get file change stats
83
+ let changeStats = '';
84
+ try {
85
+ const stats = execSync(`git diff --shortstat ${defaultBranch}...HEAD`, {
86
+ encoding: 'utf-8',
87
+ }).trim();
88
+
89
+ if (stats) {
90
+ changeStats = `**Changes**: ${stats}\n\n`;
91
+ }
92
+ } catch (err) {
93
+ console.warn('Could not get change stats');
94
+ }
95
+
96
+ // Get previous version from default branch
97
+ function getPreviousVersion() {
98
+ try {
99
+ // Try to get package.json from default branch
100
+ const previousPackageJson = execSync(`git show origin/${defaultBranch}:package.json`, {
101
+ encoding: 'utf-8',
102
+ });
103
+ const previousPkg = JSON.parse(previousPackageJson);
104
+ return previousPkg.version;
105
+ } catch (err) {
106
+ // Fallback: try to get the latest git tag
107
+ try {
108
+ const latestTag = execSync('git describe --tags --abbrev=0', {
109
+ encoding: 'utf-8',
110
+ }).trim();
111
+ // Remove 'v' prefix if present
112
+ return latestTag.replace(/^v/, '');
113
+ } catch {
114
+ // Fallback: try to get tags sorted by version
115
+ try {
116
+ const tags = execSync('git tag --sort=-v:refname', {
117
+ encoding: 'utf-8',
118
+ }).trim();
119
+ const latestTag = tags.split('\n')[0];
120
+ if (latestTag) {
121
+ return latestTag.replace(/^v/, '');
122
+ }
123
+ } catch {
124
+ console.warn('Could not determine previous version, using current version as fallback');
125
+ return packageJson.version;
126
+ }
127
+ }
128
+ }
129
+ return packageJson.version;
130
+ }
131
+
132
+ // Smart defaults based on branch name and commits
133
+ function detectChangeType(branchName, commits) {
134
+ const name = branchName.toLowerCase();
135
+ const commitText = commits.toLowerCase();
136
+
137
+ if (name.includes('major') || commitText.includes('breaking') || commitText.includes('major:')) {
138
+ return 'Major';
139
+ } else if (name.includes('minor') || name.includes('feature') || name.includes('feat')) {
140
+ return 'Minor';
141
+ } else if (name.includes('patch') || name.includes('fix') || name.includes('hotfix')) {
142
+ return 'Patch';
143
+ }
144
+
145
+ return 'Unknown';
146
+ }
147
+
148
+ const branch = execSync('git branch --show-current', { encoding: 'utf-8' }).trim();
149
+ const changeType = detectChangeType(branch, commitMessages);
150
+
151
+ // Build the description
152
+ let description = template;
153
+
154
+ // Add summary if we have commits
155
+ if (commitMessages) {
156
+ const summarySection = commitMessages.split('\n').slice(0, 5).join('\n');
157
+ description = description.replace(
158
+ 'Describe the change and its motivation.',
159
+ `Describe the change and its motivation.\n\n${summarySection}`,
160
+ );
161
+ }
162
+
163
+ // Pre-check the type of change if we detected it
164
+ if (changeType === 'Major') {
165
+ description = description.replace('- [ ] Major', '- [x] Major');
166
+ } else if (changeType === 'Minor') {
167
+ description = description.replace('- [ ] Minor', '- [x] Minor');
168
+ } else if (changeType === 'Patch') {
169
+ description = description.replace('- [ ] Patch', '- [x] Patch');
170
+ }
171
+
172
+ // Add version info
173
+ const currentVersion = packageJson.version;
174
+ const previousVersion = getPreviousVersion();
175
+ description = description.replace(
176
+ '`X.Y.Z` → `X.Y.Z`',
177
+ `\`${previousVersion}\` → \`${currentVersion}\``,
178
+ );
179
+
180
+ // Add changelog entries if available
181
+ if (changelogEntries) {
182
+ description += `\n\n---\n\n${changelogEntries}`;
183
+ }
184
+
185
+ // Add change stats if available
186
+ if (changeStats) {
187
+ description += `\n\n${changeStats}`;
188
+ }
189
+
190
+ // Add commit history
191
+ if (commitMessages) {
192
+ description += `\n${commitMessages}`;
193
+ }
194
+
195
+ // Output the description
196
+ console.log(description);
197
+
198
+ // Optionally write to file
199
+ const outputPath = path.join(__dirname, '..', '.pr-description.md');
200
+ fs.writeFileSync(outputPath, description);
201
+ console.error(`\n✅ PR description written to: ${outputPath}`);
202
+ console.error('\nTo create PR with this description:');
203
+ console.error(` gh pr create --body-file .pr-description.md --title "Your PR title"`);
@@ -0,0 +1,96 @@
1
+ # PowerShell script to generate a .mcpb file using the official Anthropic MCPB CLI
2
+
3
+ param(
4
+ [string]$OutputDir = "dist"
5
+ )
6
+
7
+ Write-Host "Generating YNAB MCP Server .mcpb package using official CLI..." -ForegroundColor Green
8
+
9
+ # Configuration
10
+ $PackageJson = Get-Content "package.json" | ConvertFrom-Json
11
+ $PackageName = $PackageJson.name
12
+ $Version = $PackageJson.version
13
+
14
+ # Ensure we have a built version
15
+ if (-not (Test-Path "dist/index.js")) {
16
+ Write-Host "Build not found. Running build first..." -ForegroundColor Red
17
+ npm run build
18
+ if ($LASTEXITCODE -ne 0) {
19
+ Write-Host "Build failed!" -ForegroundColor Red
20
+ exit 1
21
+ }
22
+ }
23
+
24
+ # Check if official MCPB CLI is installed
25
+ try {
26
+ $mcpbVersion = & mcpb --version
27
+ Write-Host "Using MCPB CLI version: $mcpbVersion" -ForegroundColor Green
28
+ } catch {
29
+ Write-Host "MCPB CLI not found. Installing..." -ForegroundColor Yellow
30
+ npm install -g @anthropic-ai/mcpb
31
+ if ($LASTEXITCODE -ne 0) {
32
+ Write-Host "Failed to install MCPB CLI!" -ForegroundColor Red
33
+ exit 1
34
+ }
35
+ }
36
+
37
+ # Ensure manifest.json exists and is valid
38
+ if (-not (Test-Path "manifest.json")) {
39
+ Write-Host "manifest.json not found. Creating one..." -ForegroundColor Yellow
40
+ & mcpb init -y
41
+ if ($LASTEXITCODE -ne 0) {
42
+ Write-Host "Failed to create manifest!" -ForegroundColor Red
43
+ exit 1
44
+ }
45
+ }
46
+
47
+ # Sync version from package.json to manifest.json
48
+ Write-Host "Syncing version from package.json to manifest.json..." -ForegroundColor Yellow
49
+ $ManifestPath = "manifest.json"
50
+ $ManifestContent = Get-Content $ManifestPath -Raw
51
+ $Manifest = $ManifestContent | ConvertFrom-Json
52
+
53
+ if ($Manifest.version -ne $Version) {
54
+ Write-Host "Updating manifest version from $($Manifest.version) to $Version" -ForegroundColor Cyan
55
+ # Use regex to update version while preserving formatting
56
+ $UpdatedContent = $ManifestContent -replace '("version"\s*:\s*)"[^"]*"', "`$1`"$Version`""
57
+ $UpdatedContent | Set-Content $ManifestPath -NoNewline
58
+ }
59
+
60
+ # Validate the manifest
61
+ Write-Host "Validating manifest..." -ForegroundColor Yellow
62
+ & mcpb validate manifest.json
63
+ if ($LASTEXITCODE -ne 0) {
64
+ Write-Host "Manifest validation failed!" -ForegroundColor Red
65
+ exit 1
66
+ }
67
+
68
+ # Pack the MCPB using official CLI
69
+ Write-Host "Packing MCPB file..." -ForegroundColor Yellow
70
+ $DxtFile = "$PackageName-$Version.mcpb"
71
+ $OutputPath = Join-Path $OutputDir $DxtFile
72
+
73
+ & mcpb pack . $OutputPath
74
+ if ($LASTEXITCODE -ne 0) {
75
+ Write-Host "MCPB packing failed!" -ForegroundColor Red
76
+ exit 1
77
+ }
78
+
79
+ # Get file size
80
+ if (Test-Path $OutputPath) {
81
+ $FileSize = (Get-Item $OutputPath).Length
82
+ $FileSizeKB = [math]::Round($FileSize / 1KB, 1)
83
+ $FileSizeMB = [math]::Round($FileSize / 1MB, 1)
84
+
85
+ Write-Host "Created $OutputPath" -ForegroundColor Green
86
+ Write-Host "Size: $FileSizeKB KB ($FileSizeMB MB)" -ForegroundColor Cyan
87
+ } else {
88
+ Write-Host "MCPB file was not created!" -ForegroundColor Red
89
+ exit 1
90
+ }
91
+
92
+ Write-Host ""
93
+ Write-Host "Installation Instructions:" -ForegroundColor Yellow
94
+ Write-Host "1. Drag and drop the .mcpb file into Claude Desktop" -ForegroundColor White
95
+ Write-Host "2. Set YNAB_ACCESS_TOKEN environment variable" -ForegroundColor White
96
+ Write-Host "3. Restart Claude Desktop" -ForegroundColor White
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Runs domain-scoped integration tests with tier filtering.
4
+ */
5
+ import { spawn } from 'node:child_process';
6
+
7
+ const rawArgs = process.argv.slice(2);
8
+ const separatorIndex = rawArgs.indexOf('--');
9
+ const domainArgs = separatorIndex === -1 ? rawArgs : rawArgs.slice(0, separatorIndex);
10
+ const passthroughArgs = separatorIndex === -1 ? [] : rawArgs.slice(separatorIndex + 1);
11
+
12
+ if (domainArgs.length === 0) {
13
+ console.error('Usage: node scripts/run-domain-integration-tests.js <domain> [domain ...]');
14
+ process.exit(1);
15
+ }
16
+
17
+ const domains = domainArgs.join(',');
18
+ const env = {
19
+ ...process.env,
20
+ INTEGRATION_TEST_TIER: 'domain',
21
+ INTEGRATION_TEST_DOMAINS: domains,
22
+ };
23
+
24
+ const vitestArgs = ['vitest', 'run', '--project', 'integration:domain', ...passthroughArgs];
25
+ const runner = process.platform === 'win32' ? 'npx.cmd' : 'npx';
26
+ const child = spawn(runner, vitestArgs, {
27
+ stdio: 'inherit',
28
+ env,
29
+ });
30
+
31
+ child.on('close', (code) => {
32
+ process.exit(code ?? 1);
33
+ });
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from 'node:child_process';
3
+ import process from 'node:process';
4
+
5
+ if (process.env['SKIP_MCPB'] === '1') {
6
+ console.log('Skipping MCPB generation because SKIP_MCPB=1');
7
+ process.exit(0);
8
+ }
9
+
10
+ const commands = [];
11
+ if (process.platform === 'win32') {
12
+ commands.push([
13
+ 'powershell',
14
+ ['-ExecutionPolicy', 'Bypass', '-File', 'scripts/generate-mcpb.ps1'],
15
+ ]);
16
+ commands.push(['pwsh', ['-File', 'scripts/generate-mcpb.ps1']]);
17
+ } else {
18
+ commands.push(['pwsh', ['-File', 'scripts/generate-mcpb.ps1']]);
19
+ }
20
+
21
+ for (const [cmd, args] of commands) {
22
+ const result = spawnSync(cmd, args, { stdio: 'inherit' });
23
+ if (result.status === 0) {
24
+ process.exit(0);
25
+ }
26
+ }
27
+
28
+ console.log('PowerShell is not available on this runner; skipping MCPB generation.');
29
+ process.exit(0);