@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.
- package/.chunkhound.json +11 -0
- package/.code/agents/0427d95e-edca-431f-a214-5e53264e29c4/error.txt +8 -0
- package/.code/agents/0d675174-d1e1-41c3-9975-4c2e275819a9/error.txt +3 -0
- package/.code/agents/0d8c5afd-4787-422b-abf8-2e5943fc7e67/error.txt +3 -0
- package/.code/agents/0ec34a70-ed5d-4b9e-bee4-bb0e4cccbc4b/error.txt +1 -0
- package/.code/agents/0ef51a21-1ab1-49d7-9561-0eaa43875ebc/error.txt +12 -0
- package/.code/agents/15db95d7-abad-4b4d-9c3b-8446089cb61d/error.txt +1 -0
- package/.code/agents/19ab9acb-f675-4ff0-902a-09a5476f8149/error.txt +1 -0
- package/.code/agents/1ef7e12d-f6ff-4897-8a9b-152d523d898e/error.txt +5 -0
- package/.code/agents/2465/exec-call_lroN9KKzJVWC7t5423DK1nT9.txt +1453 -0
- package/.code/agents/28edb6fe-95a9-41a0-ae69-aa0100d26c0c/error.txt +8 -0
- package/.code/agents/2ae40cf5-b4bf-42e2-92bf-7ea350a7755e/error.txt +9 -0
- package/.code/agents/2bfc4e1f-ac4b-45a5-b6df-bf89d4dbb54c/error.txt +1 -0
- package/.code/agents/2e2e1134-eff0-49be-ba25-8e2c3468a564/error.txt +5 -0
- package/.code/agents/3/exec-call_203OC4TNVkLxW7z2HCVEQ1cM.txt +81 -0
- package/.code/agents/3/exec-call_SS5T0XSiXB4LSNzUKTl75wkh.txt +610 -0
- package/.code/agents/3322c003-ce5e-48e3-a342-f5049c5bf9a2/error.txt +1 -0
- package/.code/agents/391e9b08-1ebc-468c-9bcd-6d0cc3193b37/error.txt +1 -0
- package/.code/agents/3ab0aa84-b7bb-4054-afa3-40b8fd7d3be0/error.txt +1 -0
- package/.code/agents/3bed368d-50fe-477e-aee3-a6707eaa1ab9/error.txt +3 -0
- package/.code/agents/3e40b925-db12-442f-8d7a-a25fc69a6672/error.txt +8 -0
- package/.code/agents/414d5776-cf58-41f3-9328-a6daed503a50/error.txt +5 -0
- package/.code/agents/42687751-4565-4610-b240-67835b17d861/error.txt +1 -0
- package/.code/agents/46b98876-1a39-43c9-9e2f-507ca6d47335/error.txt +9 -0
- package/.code/agents/4a7d9491-b26f-43dd-850d-2ecdc49b5d1b/error.txt +1 -0
- package/.code/agents/4e60f00a-1b3e-447f-87f3-7faf9deddec3/error.txt +13 -0
- package/.code/agents/5138fc1c-4d49-4b74-a7da-ccdb3a8e44e7/error.txt +14 -0
- package/.code/agents/521cff39-a7a3-42e5-a557-134f0f7daaa0/error.txt +5 -0
- package/.code/agents/53302dc5-3857-4413-9a47-9e0f64a51dc4/error.txt +5 -0
- package/.code/agents/567c7c2e-6a6f-4761-a08d-d36deeb2e0ac/error.txt +5 -0
- package/.code/agents/57b00845-80dc-47c9-953c-3028d16275d6/error.txt +3 -0
- package/.code/agents/593d9005-c2a5-48fd-8813-ece0d3f2de96/error.txt +1 -0
- package/.code/agents/5a112e66-0e1a-42f9-877c-53af56ea3551/error.txt +1 -0
- package/.code/agents/5b05e8ed-7788-4738-b7ee-9faa8180f992/error.txt +5 -0
- package/.code/agents/5f888d6f-d7ca-4ac8-be23-9ea1bf753951/error.txt +5 -0
- package/.code/agents/607db3ab-e4b0-435b-b497-93e9aa525549/error.txt +8 -0
- package/.code/agents/67dcb2a2-900f-4c78-b3fc-80b5213e0ddf/error.txt +8 -0
- package/.code/agents/69ad848c-4e98-49b3-b16c-0094ac2d1759/error.txt +5 -0
- package/.code/agents/6c9cfc5f-0d0b-445c-b121-9f60082c4f70/error.txt +1 -0
- package/.code/agents/6f6f8f77-4ab0-4f6e-9f30-40e8be0bd8f5/error.txt +1 -0
- package/.code/agents/72a7cde4-fa8a-4024-9038-27faa550539b/error.txt +1 -0
- package/.code/agents/7b48335c-8247-43aa-9949-5f820ba8e199/error.txt +1 -0
- package/.code/agents/80944249-bea9-4ac5-87de-a666c4df306e/error.txt +1 -0
- package/.code/agents/826099df-1b66-4186-a915-7eb59f9db19d/error.txt +5 -0
- package/.code/agents/8291d158-18a8-4a92-b799-4e9a4d9cce88/error.txt +1 -0
- package/.code/agents/82fb71a3-20fb-4341-804a-a2fc900f95bc/error.txt +1 -0
- package/.code/agents/855790ea-54ee-43e4-8209-a66994e37590/error.txt +1 -0
- package/.code/agents/88ce3a2e-04f2-42be-9062-bf97aa798da0/error.txt +3 -0
- package/.code/agents/9a17e398-b6ed-4218-bb55-bc64a8d38ce8/error.txt +8 -0
- package/.code/agents/9a4f4bfc-a2a6-4f40-a896-9335b41a7ed1/error.txt +1 -0
- package/.code/agents/9b633e55-ef84-47d6-94bb-fd3dd172ad97/error.txt +1 -0
- package/.code/agents/9b81f3ab-c72b-4a81-9a8f-28a49ddba84a/error.txt +8 -0
- package/.code/agents/a35daf29-b2d1-4aef-9b42-dad63a76bd47/error.txt +3 -0
- package/.code/agents/a81990cc-69ee-44d2-b907-17403c9bc5d7/error.txt +5 -0
- package/.code/agents/ab56260a-4a83-4ad4-9410-f88a23d6520a/error.txt +1 -0
- package/.code/agents/ad722c31-2d1d-45f7-bae2-3f02ca455b60/error.txt +1 -0
- package/.code/agents/b62e8690-3324-4b97-9309-731bee79416b/error.txt +5 -0
- package/.code/agents/baf60a3a-752b-4ad8-99d6-df32423ed2eb/error.txt +1 -0
- package/.code/agents/be049042-7dcb-4ac8-9beb-c8f1aea67742/error.txt +14 -0
- package/.code/agents/bed1dcb4-bfce-4a9f-8594-0f994962aafd/error.txt +1 -0
- package/.code/agents/c324a6cf-e935-4ede-9529-b3ebc18e8d6b/error.txt +5 -0
- package/.code/agents/c37c06ff-dfe3-43f2-9bbc-3ec73ec8f41d/error.txt +5 -0
- package/.code/agents/c8cd6671-433a-456b-9f88-e51cb2df6bfc/error.txt +11 -0
- package/.code/agents/ca2ccb67-2f24-428e-b27d-9365beadd140/error.txt +1 -0
- package/.code/agents/cf08c0c8-e7f0-423e-93ba-547e8e818340/error.txt +8 -0
- package/.code/agents/d579c74f-874b-40a4-9d56-ced1eb6a701d/error.txt +1 -0
- package/.code/agents/df412c98-7378-4deb-8e1e-76c416931181/error.txt +3 -0
- package/.code/agents/e5134eb3-2af4-45b0-8998-051cb4afdb45/error.txt +3 -0
- package/.code/agents/e6308471-aa45-4e9e-9496-2e9404164d97/error.txt +8 -0
- package/.code/agents/e7bd8bc7-23fb-4f46-98dc-b0dcf11b75a1/error.txt +1 -0
- package/.code/agents/e92bec35-378d-4fe1-8ac0-6e1bb3c86911/error.txt +5 -0
- package/.code/agents/ed918fbf-2dc4-4aa2-bfc5-04b65d9471ea/error.txt +1 -0
- package/.code/agents/ef1d756f-b272-48fc-8729-f05c494674f7/error.txt +1 -0
- package/.code/agents/ef359853-0249-4e41-a804-c0fc459fe456/error.txt +1 -0
- package/.code/agents/effc7b4a-4b90-40a0-8c86-a7a99d2d5fd2/error.txt +1 -0
- package/.code/agents/fa15f8d5-8359-4a8b-83a3-2f2056b3ff40/error.txt +3 -0
- package/.code/agents/fbef4193-eadf-4c8a-83ff-4878a6310f25/error.txt +8 -0
- package/.code/agents/fd0a4b4a-fda4-4964-a6d6-2b8a2da387c6/error.txt +1 -0
- package/.dxtignore +57 -0
- package/.env.example +44 -0
- package/.gemini/settings.json +8 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +41 -0
- package/.github/ISSUE_TEMPLATE/config.yml +5 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
- package/.github/ISSUE_TEMPLATE/release_checklist.md +31 -0
- package/.github/pull_request_template.md +41 -0
- package/.github/workflows/ci-tests.yml +41 -0
- package/.github/workflows/claude-code-review.yml +57 -0
- package/.github/workflows/claude.yml +50 -0
- package/.github/workflows/full-integration.yml +22 -0
- package/.github/workflows/pr-description-check.yml +88 -0
- package/.github/workflows/publish.yml +33 -0
- package/.github/workflows/release.yml +89 -0
- package/.mcpbignore +58 -0
- package/.prettierignore +10 -0
- package/.prettierrc.json +10 -0
- package/ADOS-2-Module-1-Complete-Manual.md +757 -0
- package/AGENTS.md +36 -0
- package/CHANGELOG.md +187 -0
- package/CLAUDE.md +414 -0
- package/CODEREVIEW_RESPONSE.md +128 -0
- package/LICENSE +17 -0
- package/NUL +1 -0
- package/README.md +222 -0
- package/SCHEMA_IMPROVEMENT_SUMMARY.md +120 -0
- package/TESTING_NOTES.md +217 -0
- package/WARP.md +245 -0
- package/accountactivity-merged.csv +149 -0
- package/bin/ynab-mcp-server.cjs +4 -0
- package/bin/ynab-mcp-server.js +8 -0
- package/bundle-analysis.html +13110 -0
- package/dist/bundle/index.cjs +124 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +85 -0
- package/dist/server/YNABMCPServer.d.ts +264 -0
- package/dist/server/YNABMCPServer.js +845 -0
- package/dist/server/budgetResolver.d.ts +15 -0
- package/dist/server/budgetResolver.js +99 -0
- package/dist/server/cacheManager.d.ts +74 -0
- package/dist/server/cacheManager.js +306 -0
- package/dist/server/config.d.ts +3 -0
- package/dist/server/config.js +19 -0
- package/dist/server/deltaCache.d.ts +61 -0
- package/dist/server/deltaCache.js +206 -0
- package/dist/server/deltaCache.merge.d.ts +9 -0
- package/dist/server/deltaCache.merge.js +111 -0
- package/dist/server/diagnostics.d.ts +90 -0
- package/dist/server/diagnostics.js +163 -0
- package/dist/server/errorHandler.d.ts +69 -0
- package/dist/server/errorHandler.js +524 -0
- package/dist/server/prompts.d.ts +31 -0
- package/dist/server/prompts.js +205 -0
- package/dist/server/rateLimiter.d.ts +27 -0
- package/dist/server/rateLimiter.js +82 -0
- package/dist/server/requestLogger.d.ts +62 -0
- package/dist/server/requestLogger.js +190 -0
- package/dist/server/resources.d.ts +39 -0
- package/dist/server/resources.js +85 -0
- package/dist/server/responseFormatter.d.ts +14 -0
- package/dist/server/responseFormatter.js +42 -0
- package/dist/server/securityMiddleware.d.ts +87 -0
- package/dist/server/securityMiddleware.js +117 -0
- package/dist/server/serverKnowledgeStore.d.ts +11 -0
- package/dist/server/serverKnowledgeStore.js +42 -0
- package/dist/server/toolRegistry.d.ts +85 -0
- package/dist/server/toolRegistry.js +272 -0
- package/dist/tools/__tests__/deltaTestUtils.d.ts +18 -0
- package/dist/tools/__tests__/deltaTestUtils.js +26 -0
- package/dist/tools/accountTools.d.ts +37 -0
- package/dist/tools/accountTools.js +175 -0
- package/dist/tools/budgetTools.d.ts +10 -0
- package/dist/tools/budgetTools.js +68 -0
- package/dist/tools/categoryTools.d.ts +27 -0
- package/dist/tools/categoryTools.js +232 -0
- package/dist/tools/compareTransactions/formatter.d.ts +71 -0
- package/dist/tools/compareTransactions/formatter.js +97 -0
- package/dist/tools/compareTransactions/index.d.ts +30 -0
- package/dist/tools/compareTransactions/index.js +160 -0
- package/dist/tools/compareTransactions/matcher.d.ts +12 -0
- package/dist/tools/compareTransactions/matcher.js +140 -0
- package/dist/tools/compareTransactions/parser.d.ts +14 -0
- package/dist/tools/compareTransactions/parser.js +430 -0
- package/dist/tools/compareTransactions/types.d.ts +27 -0
- package/dist/tools/compareTransactions/types.js +1 -0
- package/dist/tools/compareTransactions.d.ts +1 -0
- package/dist/tools/compareTransactions.js +1 -0
- package/dist/tools/deltaFetcher.d.ts +22 -0
- package/dist/tools/deltaFetcher.js +137 -0
- package/dist/tools/deltaSupport.d.ts +20 -0
- package/dist/tools/deltaSupport.js +176 -0
- package/dist/tools/exportTransactions.d.ts +17 -0
- package/dist/tools/exportTransactions.js +191 -0
- package/dist/tools/monthTools.d.ts +16 -0
- package/dist/tools/monthTools.js +107 -0
- package/dist/tools/payeeTools.d.ts +17 -0
- package/dist/tools/payeeTools.js +82 -0
- package/dist/tools/reconcileAdapter.d.ts +25 -0
- package/dist/tools/reconcileAdapter.js +167 -0
- package/dist/tools/reconciliation/analyzer.d.ts +3 -0
- package/dist/tools/reconciliation/analyzer.js +567 -0
- package/dist/tools/reconciliation/executor.d.ts +94 -0
- package/dist/tools/reconciliation/executor.js +611 -0
- package/dist/tools/reconciliation/index.d.ts +54 -0
- package/dist/tools/reconciliation/index.js +249 -0
- package/dist/tools/reconciliation/matcher.d.ts +3 -0
- package/dist/tools/reconciliation/matcher.js +160 -0
- package/dist/tools/reconciliation/payeeNormalizer.d.ts +6 -0
- package/dist/tools/reconciliation/payeeNormalizer.js +77 -0
- package/dist/tools/reconciliation/recommendationEngine.d.ts +2 -0
- package/dist/tools/reconciliation/recommendationEngine.js +273 -0
- package/dist/tools/reconciliation/reportFormatter.d.ts +13 -0
- package/dist/tools/reconciliation/reportFormatter.js +214 -0
- package/dist/tools/reconciliation/types.d.ts +172 -0
- package/dist/tools/reconciliation/types.js +7 -0
- package/dist/tools/schemas/outputs/accountOutputs.d.ts +58 -0
- package/dist/tools/schemas/outputs/accountOutputs.js +24 -0
- package/dist/tools/schemas/outputs/budgetOutputs.d.ts +48 -0
- package/dist/tools/schemas/outputs/budgetOutputs.js +15 -0
- package/dist/tools/schemas/outputs/categoryOutputs.d.ts +93 -0
- package/dist/tools/schemas/outputs/categoryOutputs.js +37 -0
- package/dist/tools/schemas/outputs/comparisonOutputs.d.ts +269 -0
- package/dist/tools/schemas/outputs/comparisonOutputs.js +181 -0
- package/dist/tools/schemas/outputs/index.d.ts +14 -0
- package/dist/tools/schemas/outputs/index.js +14 -0
- package/dist/tools/schemas/outputs/monthOutputs.d.ts +122 -0
- package/dist/tools/schemas/outputs/monthOutputs.js +51 -0
- package/dist/tools/schemas/outputs/payeeOutputs.d.ts +34 -0
- package/dist/tools/schemas/outputs/payeeOutputs.js +16 -0
- package/dist/tools/schemas/outputs/reconciliationOutputs.d.ts +1275 -0
- package/dist/tools/schemas/outputs/reconciliationOutputs.js +377 -0
- package/dist/tools/schemas/outputs/transactionMutationOutputs.d.ts +717 -0
- package/dist/tools/schemas/outputs/transactionMutationOutputs.js +260 -0
- package/dist/tools/schemas/outputs/transactionOutputs.d.ts +98 -0
- package/dist/tools/schemas/outputs/transactionOutputs.js +49 -0
- package/dist/tools/schemas/outputs/utilityOutputs.d.ts +219 -0
- package/dist/tools/schemas/outputs/utilityOutputs.js +120 -0
- package/dist/tools/schemas/shared/commonOutputs.d.ts +24 -0
- package/dist/tools/schemas/shared/commonOutputs.js +27 -0
- package/dist/tools/toolCategories.d.ts +32 -0
- package/dist/tools/toolCategories.js +32 -0
- package/dist/tools/transactionTools.d.ts +315 -0
- package/dist/tools/transactionTools.js +1722 -0
- package/dist/tools/utilityTools.d.ts +10 -0
- package/dist/tools/utilityTools.js +56 -0
- package/dist/types/index.d.ts +20 -0
- package/dist/types/index.js +16 -0
- package/dist/types/toolAnnotations.d.ts +7 -0
- package/dist/types/toolAnnotations.js +1 -0
- package/dist/utils/amountUtils.d.ts +3 -0
- package/dist/utils/amountUtils.js +10 -0
- package/dist/utils/dateUtils.d.ts +9 -0
- package/dist/utils/dateUtils.js +43 -0
- package/dist/utils/money.d.ts +21 -0
- package/dist/utils/money.js +51 -0
- package/docs/README.md +72 -0
- package/docs/assets/examples/reconciliation-with-recommendations.json +68 -0
- package/docs/assets/schemas/reconciliation-v2.json +338 -0
- package/docs/getting-started/CONFIGURATION.md +175 -0
- package/docs/getting-started/INSTALLATION.md +333 -0
- package/docs/getting-started/QUICKSTART.md +282 -0
- package/docs/guides/ARCHITECTURE.md +650 -0
- package/docs/guides/DEPLOYMENT.md +189 -0
- package/docs/guides/INTEGRATION_TESTING.md +730 -0
- package/docs/guides/TESTING.md +591 -0
- package/docs/reconciliation-flow.md +83 -0
- package/docs/reference/API.md +1450 -0
- package/docs/reference/EXAMPLES.md +946 -0
- package/docs/reference/TOOLS.md +348 -0
- package/docs/reference/TROUBLESHOOTING.md +481 -0
- package/esbuild.config.mjs +68 -0
- package/eslint.config.js +49 -0
- package/fix-types.sh +17 -0
- package/meta.json +12550 -0
- package/package.json +105 -0
- package/package.json.tmp +105 -0
- package/scripts/analyze-bundle.mjs +41 -0
- package/scripts/create-pr-description.js +203 -0
- package/scripts/generate-mcpb.ps1 +96 -0
- package/scripts/run-domain-integration-tests.js +33 -0
- package/scripts/run-generate-mcpb.js +29 -0
- package/scripts/run-throttled-integration-tests.js +116 -0
- package/scripts/test-delta-params.mjs +140 -0
- package/scripts/test-recommendations.ts +53 -0
- package/scripts/tmpTransaction.ts +48 -0
- package/scripts/validate-env.js +122 -0
- package/scripts/verify-build.js +105 -0
- package/scripts/watch-and-restart.ps1 +50 -0
- package/src/__tests__/comprehensive.integration.test.ts +1196 -0
- package/src/__tests__/delta.performance.test.ts +80 -0
- package/src/__tests__/performance.test.ts +725 -0
- package/src/__tests__/setup.ts +449 -0
- package/src/__tests__/testRunner.ts +444 -0
- package/src/__tests__/testUtils.ts +563 -0
- package/src/__tests__/workflows.e2e.test.ts +1675 -0
- package/src/index.ts +124 -0
- package/src/server/.gitkeep +1 -0
- package/src/server/YNABMCPServer.ts +1188 -0
- package/src/server/__tests__/YNABMCPServer.integration.test.ts +903 -0
- package/src/server/__tests__/YNABMCPServer.test.ts +894 -0
- package/src/server/__tests__/budgetResolver.test.ts +425 -0
- package/src/server/__tests__/cacheManager.test.ts +880 -0
- package/src/server/__tests__/config.test.ts +166 -0
- package/src/server/__tests__/deltaCache.merge.test.ts +724 -0
- package/src/server/__tests__/deltaCache.swr.test.ts +168 -0
- package/src/server/__tests__/deltaCache.test.ts +774 -0
- package/src/server/__tests__/diagnostics.test.ts +823 -0
- package/src/server/__tests__/errorHandler.integration.test.ts +466 -0
- package/src/server/__tests__/errorHandler.test.ts +416 -0
- package/src/server/__tests__/prompts.test.ts +354 -0
- package/src/server/__tests__/rateLimiter.test.ts +314 -0
- package/src/server/__tests__/requestLogger.test.ts +408 -0
- package/src/server/__tests__/resources.test.ts +299 -0
- package/src/server/__tests__/security.integration.test.ts +426 -0
- package/src/server/__tests__/securityMiddleware.test.ts +449 -0
- package/src/server/__tests__/server-startup.integration.test.ts +477 -0
- package/src/server/__tests__/serverKnowledgeStore.test.ts +174 -0
- package/src/server/__tests__/toolRegistry.test.ts +855 -0
- package/src/server/budgetResolver.ts +235 -0
- package/src/server/cacheManager.ts +503 -0
- package/src/server/config.ts +41 -0
- package/src/server/deltaCache.merge.ts +149 -0
- package/src/server/deltaCache.ts +341 -0
- package/src/server/diagnostics.ts +338 -0
- package/src/server/errorHandler.ts +756 -0
- package/src/server/prompts.ts +291 -0
- package/src/server/rateLimiter.ts +156 -0
- package/src/server/requestLogger.ts +344 -0
- package/src/server/resources.ts +168 -0
- package/src/server/responseFormatter.ts +51 -0
- package/src/server/securityMiddleware.ts +236 -0
- package/src/server/serverKnowledgeStore.ts +91 -0
- package/src/server/toolRegistry.ts +489 -0
- package/src/tools/.gitkeep +1 -0
- package/src/tools/__tests__/accountTools.delta.integration.test.ts +128 -0
- package/src/tools/__tests__/accountTools.integration.test.ts +117 -0
- package/src/tools/__tests__/accountTools.test.ts +653 -0
- package/src/tools/__tests__/budgetTools.delta.integration.test.ts +90 -0
- package/src/tools/__tests__/budgetTools.integration.test.ts +134 -0
- package/src/tools/__tests__/budgetTools.test.ts +423 -0
- package/src/tools/__tests__/categoryTools.delta.integration.test.ts +80 -0
- package/src/tools/__tests__/categoryTools.integration.test.ts +295 -0
- package/src/tools/__tests__/categoryTools.test.ts +622 -0
- package/src/tools/__tests__/compareTransactions/formatter.test.ts +486 -0
- package/src/tools/__tests__/compareTransactions/index.test.ts +383 -0
- package/src/tools/__tests__/compareTransactions/matcher.test.ts +410 -0
- package/src/tools/__tests__/compareTransactions/parser.test.ts +764 -0
- package/src/tools/__tests__/compareTransactions.test.ts +342 -0
- package/src/tools/__tests__/compareTransactions.window.test.ts +147 -0
- package/src/tools/__tests__/deltaFetcher.scheduled.integration.test.ts +76 -0
- package/src/tools/__tests__/deltaFetcher.test.ts +270 -0
- package/src/tools/__tests__/deltaSupport.test.ts +188 -0
- package/src/tools/__tests__/deltaTestUtils.ts +46 -0
- package/src/tools/__tests__/exportTransactions.test.ts +213 -0
- package/src/tools/__tests__/monthTools.delta.integration.test.ts +80 -0
- package/src/tools/__tests__/monthTools.integration.test.ts +174 -0
- package/src/tools/__tests__/monthTools.test.ts +523 -0
- package/src/tools/__tests__/payeeTools.delta.integration.test.ts +80 -0
- package/src/tools/__tests__/payeeTools.integration.test.ts +150 -0
- package/src/tools/__tests__/payeeTools.test.ts +445 -0
- package/src/tools/__tests__/transactionTools.integration.test.ts +762 -0
- package/src/tools/__tests__/transactionTools.test.ts +3521 -0
- package/src/tools/__tests__/utilityTools.integration.test.ts +128 -0
- package/src/tools/__tests__/utilityTools.test.ts +205 -0
- package/src/tools/accountTools.ts +283 -0
- package/src/tools/budgetTools.ts +112 -0
- package/src/tools/categoryTools.ts +366 -0
- package/src/tools/compareTransactions/formatter.ts +163 -0
- package/src/tools/compareTransactions/index.ts +228 -0
- package/src/tools/compareTransactions/matcher.ts +240 -0
- package/src/tools/compareTransactions/parser.ts +557 -0
- package/src/tools/compareTransactions/types.ts +60 -0
- package/src/tools/compareTransactions.ts +3 -0
- package/src/tools/deltaFetcher.ts +278 -0
- package/src/tools/deltaSupport.ts +293 -0
- package/src/tools/exportTransactions.ts +273 -0
- package/src/tools/monthTools.ts +164 -0
- package/src/tools/payeeTools.ts +140 -0
- package/src/tools/reconcileAdapter.ts +312 -0
- package/src/tools/reconciliation/__tests__/adapter.causes.test.ts +122 -0
- package/src/tools/reconciliation/__tests__/adapter.test.ts +234 -0
- package/src/tools/reconciliation/__tests__/analyzer.test.ts +406 -0
- package/src/tools/reconciliation/__tests__/executor.integration.test.ts +366 -0
- package/src/tools/reconciliation/__tests__/executor.test.ts +779 -0
- package/src/tools/reconciliation/__tests__/matcher.test.ts +650 -0
- package/src/tools/reconciliation/__tests__/payeeNormalizer.test.ts +278 -0
- package/src/tools/reconciliation/__tests__/recommendationEngine.integration.test.ts +658 -0
- package/src/tools/reconciliation/__tests__/recommendationEngine.test.ts +1000 -0
- package/src/tools/reconciliation/__tests__/reconciliation.delta.integration.test.ts +151 -0
- package/src/tools/reconciliation/__tests__/reportFormatter.test.ts +573 -0
- package/src/tools/reconciliation/__tests__/scenarios/adapterCurrency.scenario.test.ts +78 -0
- package/src/tools/reconciliation/__tests__/scenarios/extremes.scenario.test.ts +47 -0
- package/src/tools/reconciliation/__tests__/scenarios/repeatAmount.scenario.test.ts +61 -0
- package/src/tools/reconciliation/__tests__/schemaUrl.test.ts +49 -0
- package/src/tools/reconciliation/analyzer.ts +824 -0
- package/src/tools/reconciliation/executor.ts +880 -0
- package/src/tools/reconciliation/index.ts +400 -0
- package/src/tools/reconciliation/matcher.ts +269 -0
- package/src/tools/reconciliation/payeeNormalizer.ts +167 -0
- package/src/tools/reconciliation/recommendationEngine.ts +506 -0
- package/src/tools/reconciliation/reportFormatter.ts +363 -0
- package/src/tools/reconciliation/types.ts +314 -0
- package/src/tools/schemas/outputs/__tests__/accountOutputs.test.ts +424 -0
- package/src/tools/schemas/outputs/__tests__/budgetOutputs.test.ts +310 -0
- package/src/tools/schemas/outputs/__tests__/categoryOutputs.test.ts +448 -0
- package/src/tools/schemas/outputs/__tests__/comparisonOutputs.test.ts +519 -0
- package/src/tools/schemas/outputs/__tests__/dateValidation.test.ts +155 -0
- package/src/tools/schemas/outputs/__tests__/discrepancyDirection.test.ts +288 -0
- package/src/tools/schemas/outputs/__tests__/monthOutputs.test.ts +478 -0
- package/src/tools/schemas/outputs/__tests__/payeeOutputs.test.ts +370 -0
- package/src/tools/schemas/outputs/__tests__/reconciliationOutputs.test.ts +401 -0
- package/src/tools/schemas/outputs/__tests__/transactionMutationSchemas.test.ts +213 -0
- package/src/tools/schemas/outputs/__tests__/transactionOutputs.test.ts +474 -0
- package/src/tools/schemas/outputs/__tests__/utilityOutputs.test.ts +333 -0
- package/src/tools/schemas/outputs/accountOutputs.ts +137 -0
- package/src/tools/schemas/outputs/budgetOutputs.ts +86 -0
- package/src/tools/schemas/outputs/categoryOutputs.ts +194 -0
- package/src/tools/schemas/outputs/comparisonOutputs.ts +600 -0
- package/src/tools/schemas/outputs/index.ts +270 -0
- package/src/tools/schemas/outputs/monthOutputs.ts +243 -0
- package/src/tools/schemas/outputs/payeeOutputs.ts +105 -0
- package/src/tools/schemas/outputs/reconciliationOutputs.ts +796 -0
- package/src/tools/schemas/outputs/transactionMutationOutputs.ts +758 -0
- package/src/tools/schemas/outputs/transactionOutputs.ts +243 -0
- package/src/tools/schemas/outputs/utilityOutputs.ts +411 -0
- package/src/tools/schemas/shared/commonOutputs.ts +140 -0
- package/src/tools/toolCategories.ts +140 -0
- package/src/tools/transactionTools.ts +2509 -0
- package/src/tools/utilityTools.ts +90 -0
- package/src/types/.gitkeep +1 -0
- package/src/types/__tests__/index.test.ts +52 -0
- package/src/types/index.ts +67 -0
- package/src/types/integration-tests.d.ts +35 -0
- package/src/types/toolAnnotations.ts +44 -0
- package/src/utils/__tests__/dateUtils.test.ts +170 -0
- package/src/utils/__tests__/money.test.ts +189 -0
- package/src/utils/amountUtils.ts +32 -0
- package/src/utils/dateUtils.ts +108 -0
- package/src/utils/money.ts +123 -0
- package/test-csv-sample.csv +28 -0
- package/test-exports/sample_bank_statement.csv +7 -0
- package/test-exports/ynab_account_e9ddc2a6_minimal_1items_2025-11-19_09-04-53.json +23 -0
- package/test-exports/ynab_account_e9ddc2a6_minimal_1items_2025-11-19_10-37-42.json +23 -0
- package/test-exports/ynab_account_e9ddc2a6_minimal_4items_2025-11-19_09-02-09.json +44 -0
- package/test-exports/ynab_account_e9ddc2a6_minimal_6items_2025-11-19_10-37-52.json +58 -0
- package/test-exports/ynab_since_2025-11-01_account_4c18e9f0_minimal_14items_2025-11-16_10-07-10.json +115 -0
- package/test-reconcile-autodetect.js +40 -0
- package/test-reconcile-tool.js +152 -0
- package/test-reconcile-with-csv.cjs +89 -0
- package/test-statement.csv +8 -0
- package/test_debug.js +47 -0
- package/test_simple.mjs +16 -0
- package/tsconfig.json +31 -0
- package/tsconfig.prod.json +18 -0
- package/vitest-reporters/split-json-reporter.ts +211 -0
- package/vitest.config.ts +96 -0
|
@@ -0,0 +1,650 @@
|
|
|
1
|
+
# YNAB MCP Server Architecture
|
|
2
|
+
|
|
3
|
+
This guide explains the v0.8.x modular architecture, core components, and architectural patterns.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [v0.8.x Modular Architecture](#v08x-modular-architecture)
|
|
8
|
+
- [Core Components](#core-components)
|
|
9
|
+
- [Dependency Injection Pattern](#dependency-injection-pattern)
|
|
10
|
+
- [Developing Tools with v0.8.x](#developing-tools-with-v08x)
|
|
11
|
+
- [Cache Management](#cache-management)
|
|
12
|
+
- [Service Module Patterns](#service-module-patterns)
|
|
13
|
+
- [Migration from v0.7.x](#migration-from-v07x)
|
|
14
|
+
|
|
15
|
+
## v0.8.x Modular Architecture
|
|
16
|
+
|
|
17
|
+
The v0.8.x series introduces a completely refactored architecture that improves maintainability, testability, and performance while maintaining 100% backward compatibility.
|
|
18
|
+
|
|
19
|
+
### Architecture Overview
|
|
20
|
+
|
|
21
|
+
The v0.8.x architecture consists of several key components working together:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
25
|
+
│ YNABMCPServer │
|
|
26
|
+
│ (Main Orchestrator) │
|
|
27
|
+
├─────────────────────────────────────────────────────────────┤
|
|
28
|
+
│ ┌──────────────┐ ┌───────────────┐ ┌─────────────────┐ │
|
|
29
|
+
│ │ Tool Registry│ │ Cache Manager │ │ Budget Resolver │ │
|
|
30
|
+
│ │ │ │ │ │ │ │
|
|
31
|
+
│ └──────────────┘ └───────────────┘ └─────────────────┘ │
|
|
32
|
+
│ ┌──────────────┐ ┌───────────────┐ ┌─────────────────┐ │
|
|
33
|
+
│ │Config Module │ │Resource Mgr │ │ Prompt Manager │ │
|
|
34
|
+
│ │ │ │ │ │ │ │
|
|
35
|
+
│ └──────────────┘ └───────────────┘ └─────────────────┘ │
|
|
36
|
+
│ ┌──────────────┐ ┌───────────────┐ ┌─────────────────┐ │
|
|
37
|
+
│ │Error Handler │ │Security Mdlwr │ │Diagnostic Mgr │ │
|
|
38
|
+
│ │ │ │ │ │ │ │
|
|
39
|
+
│ └──────────────┘ └───────────────┘ └─────────────────┘ │
|
|
40
|
+
└─────────────────────────────────────────────────────────────┘
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Core Components
|
|
44
|
+
|
|
45
|
+
### Tool Registry
|
|
46
|
+
Centralized management of all MCP tools with consistent validation, security, and error handling.
|
|
47
|
+
|
|
48
|
+
**Key Benefits:**
|
|
49
|
+
- Uniform tool registration and validation
|
|
50
|
+
- Consistent error messages across all tools
|
|
51
|
+
- Centralized security checks
|
|
52
|
+
- Automatic JSON schema generation
|
|
53
|
+
|
|
54
|
+
**Example Tool Definition:**
|
|
55
|
+
```typescript
|
|
56
|
+
registry.register({
|
|
57
|
+
name: 'my_custom_tool',
|
|
58
|
+
description: 'A custom tool for specific operations',
|
|
59
|
+
inputSchema: MyToolSchema,
|
|
60
|
+
handler: adapt(handleMyTool),
|
|
61
|
+
defaultArgumentResolver: resolveBudgetId(),
|
|
62
|
+
security: { requiresValidation: true }
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Enhanced Cache Manager
|
|
67
|
+
Advanced caching system with observability, LRU eviction, and performance optimization.
|
|
68
|
+
|
|
69
|
+
**Key Features:**
|
|
70
|
+
- Hit/miss tracking with detailed metrics
|
|
71
|
+
- LRU eviction with configurable limits
|
|
72
|
+
- Stale-while-revalidate for improved performance
|
|
73
|
+
- Concurrent fetch deduplication
|
|
74
|
+
- Cache warming for faster initial loads
|
|
75
|
+
|
|
76
|
+
### Budget Resolver
|
|
77
|
+
Standardized budget ID resolution with consistent error handling across all tools.
|
|
78
|
+
|
|
79
|
+
**Benefits:**
|
|
80
|
+
- Uniform budget validation
|
|
81
|
+
- Clear, actionable error messages
|
|
82
|
+
- Automatic default budget injection
|
|
83
|
+
- Consistent user experience
|
|
84
|
+
|
|
85
|
+
### Service Modules
|
|
86
|
+
Focused modules handling specific server concerns:
|
|
87
|
+
|
|
88
|
+
- **Config Module**: Environment validation and configuration management
|
|
89
|
+
- **Resource Manager**: MCP resource definitions and handlers
|
|
90
|
+
- **Prompt Manager**: MCP prompt definitions and handlers
|
|
91
|
+
- **Diagnostic Manager**: System diagnostics and health monitoring
|
|
92
|
+
|
|
93
|
+
## Dependency Injection Pattern
|
|
94
|
+
|
|
95
|
+
The v0.8.x releases adopt explicit dependency injection for better testability and maintainability:
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
// v0.8.x pattern - explicit dependencies
|
|
99
|
+
class MyService {
|
|
100
|
+
constructor(
|
|
101
|
+
private cacheManager: CacheManager,
|
|
102
|
+
private errorHandler: ErrorHandler,
|
|
103
|
+
private budgetResolver: BudgetResolver
|
|
104
|
+
) {}
|
|
105
|
+
|
|
106
|
+
async performOperation(budgetId: string) {
|
|
107
|
+
const resolved = this.budgetResolver.resolveBudgetId(budgetId, defaultBudgetId);
|
|
108
|
+
if (typeof resolved !== 'string') {
|
|
109
|
+
return resolved; // Error response
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return this.cacheManager.wrap(`operation_${resolved}`, {
|
|
113
|
+
ttl: CACHE_TTLS.MEDIUM,
|
|
114
|
+
loader: () => this.executeOperation(resolved)
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Service instantiation with dependencies
|
|
120
|
+
const myService = new MyService(cacheManager, errorHandler, budgetResolver);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Developing Tools with v0.8.x
|
|
124
|
+
|
|
125
|
+
### Tool Development Patterns
|
|
126
|
+
|
|
127
|
+
Creating new tools in v0.8.x follows the Tool Registry pattern for consistency and maintainability.
|
|
128
|
+
|
|
129
|
+
#### 1. Define Tool Schema
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { z } from 'zod';
|
|
133
|
+
|
|
134
|
+
export const MyToolSchema = z.object({
|
|
135
|
+
budget_id: z.string().optional(),
|
|
136
|
+
custom_parameter: z.string(),
|
|
137
|
+
optional_parameter: z.number().optional().default(100)
|
|
138
|
+
}).describe('Schema for my custom tool');
|
|
139
|
+
|
|
140
|
+
export type MyToolRequest = z.infer<typeof MyToolSchema>;
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### 2. Implement Tool Handler
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { adapt } from '../server/toolRegistry.js';
|
|
147
|
+
import { BudgetResolver } from '../server/budgetResolver.js';
|
|
148
|
+
import { cacheManager, CACHE_TTLS } from '../server/cacheManager.js';
|
|
149
|
+
|
|
150
|
+
export async function handleMyTool(
|
|
151
|
+
params: MyToolRequest
|
|
152
|
+
): Promise<any> {
|
|
153
|
+
// Budget resolution is handled automatically by defaultArgumentResolver
|
|
154
|
+
const { budget_id, custom_parameter, optional_parameter } = params;
|
|
155
|
+
|
|
156
|
+
// Use enhanced caching
|
|
157
|
+
return cacheManager.wrap(`my_tool_${budget_id}_${custom_parameter}`, {
|
|
158
|
+
ttl: CACHE_TTLS.SHORT,
|
|
159
|
+
staleWhileRevalidate: 60000,
|
|
160
|
+
loader: async () => {
|
|
161
|
+
// Implement your tool logic here
|
|
162
|
+
const result = await performMyOperation(budget_id, custom_parameter);
|
|
163
|
+
return {
|
|
164
|
+
success: true,
|
|
165
|
+
data: {
|
|
166
|
+
custom_result: result,
|
|
167
|
+
parameter_used: custom_parameter,
|
|
168
|
+
optional_value: optional_parameter
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
#### 3. Register Tool with Registry
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
// In YNABMCPServer.ts or a tool registration module
|
|
180
|
+
import { resolveBudgetId } from './budgetResolver.js';
|
|
181
|
+
|
|
182
|
+
registry.register({
|
|
183
|
+
name: 'my_custom_tool',
|
|
184
|
+
description: 'Performs custom operation with enhanced caching and error handling',
|
|
185
|
+
inputSchema: MyToolSchema,
|
|
186
|
+
handler: adapt(handleMyTool),
|
|
187
|
+
defaultArgumentResolver: resolveBudgetId(),
|
|
188
|
+
cacheConfig: {
|
|
189
|
+
enabled: true,
|
|
190
|
+
ttl: CACHE_TTLS.SHORT
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Using Default Argument Resolution
|
|
196
|
+
|
|
197
|
+
The Tool Registry provides automatic budget ID resolution:
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
// Budget ID is automatically resolved when not provided
|
|
201
|
+
export const resolveBudgetId = (): DefaultArgumentResolver =>
|
|
202
|
+
async (args, context) => {
|
|
203
|
+
if (!args.budget_id) {
|
|
204
|
+
const defaultBudget = context.getDefaultBudget();
|
|
205
|
+
if (!defaultBudget) {
|
|
206
|
+
return {
|
|
207
|
+
isError: true,
|
|
208
|
+
content: [{
|
|
209
|
+
type: 'text',
|
|
210
|
+
text: JSON.stringify({
|
|
211
|
+
success: false,
|
|
212
|
+
error: {
|
|
213
|
+
code: 'VALIDATION_ERROR',
|
|
214
|
+
message: 'No default budget set. Use set_default_budget first or provide budget_id parameter.'
|
|
215
|
+
}
|
|
216
|
+
})
|
|
217
|
+
}]
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
args.budget_id = defaultBudget;
|
|
221
|
+
}
|
|
222
|
+
return null; // No error, continue with resolved args
|
|
223
|
+
};
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Error Handling Best Practices
|
|
227
|
+
|
|
228
|
+
Use the centralized error handling system for consistent responses:
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
import { ErrorHandler } from '../server/errorHandler.js';
|
|
232
|
+
|
|
233
|
+
export async function handleMyTool(params: MyToolRequest): Promise<any> {
|
|
234
|
+
try {
|
|
235
|
+
// Tool implementation
|
|
236
|
+
const result = await performOperation(params);
|
|
237
|
+
return result;
|
|
238
|
+
} catch (error) {
|
|
239
|
+
// Use centralized error handling
|
|
240
|
+
return ErrorHandler.createErrorResponse(
|
|
241
|
+
'OPERATION_FAILED',
|
|
242
|
+
`Custom tool operation failed: ${error.message}`,
|
|
243
|
+
{ operation: 'my_custom_tool', params }
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Cache Management
|
|
250
|
+
|
|
251
|
+
### Understanding the Enhanced Cache System
|
|
252
|
+
|
|
253
|
+
The v0.8.x line introduces a sophisticated caching system designed for performance and observability.
|
|
254
|
+
|
|
255
|
+
#### Cache Configuration
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
// Environment variables for cache tuning
|
|
259
|
+
YNAB_MCP_CACHE_MAX_ENTRIES=1000 // Maximum cache entries
|
|
260
|
+
YNAB_MCP_CACHE_DEFAULT_TTL_MS=1800000 // Default TTL (30 minutes)
|
|
261
|
+
YNAB_MCP_CACHE_STALE_MS=120000 // Stale-while-revalidate window
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
#### Using Cache.wrap() Method
|
|
265
|
+
|
|
266
|
+
The primary interface for caching is the `wrap()` method:
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
import { cacheManager, CACHE_TTLS } from '../server/cacheManager.js';
|
|
270
|
+
|
|
271
|
+
// Basic usage
|
|
272
|
+
const result = await cacheManager.wrap('my_cache_key', {
|
|
273
|
+
ttl: CACHE_TTLS.ACCOUNTS,
|
|
274
|
+
loader: async () => {
|
|
275
|
+
// Expensive operation (API call, computation, etc.)
|
|
276
|
+
return await ynabAPI.accounts.getAccounts(budgetId);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// Advanced usage with stale-while-revalidate
|
|
281
|
+
const result = await cacheManager.wrap('complex_operation', {
|
|
282
|
+
ttl: CACHE_TTLS.LONG,
|
|
283
|
+
staleWhileRevalidate: 300000, // 5 minutes
|
|
284
|
+
loader: async () => {
|
|
285
|
+
return await performComplexAnalysis(budgetId);
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
#### Cache Strategy Guidelines
|
|
291
|
+
|
|
292
|
+
**Long TTL (1 hour+):** Budget data, categories, accounts
|
|
293
|
+
```typescript
|
|
294
|
+
// Budget data changes infrequently
|
|
295
|
+
const budgets = await cacheManager.wrap(`budgets_${userId}`, {
|
|
296
|
+
ttl: CACHE_TTLS.BUDGETS, // 1 hour
|
|
297
|
+
loader: () => ynabAPI.budgets.getBudgets()
|
|
298
|
+
});
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Medium TTL (30 minutes):** Account balances, category balances
|
|
302
|
+
```typescript
|
|
303
|
+
// Account data changes moderately
|
|
304
|
+
const accounts = await cacheManager.wrap(`accounts_${budgetId}`, {
|
|
305
|
+
ttl: CACHE_TTLS.ACCOUNTS, // 30 minutes
|
|
306
|
+
staleWhileRevalidate: 120000, // 2 minutes
|
|
307
|
+
loader: () => ynabAPI.accounts.getAccounts(budgetId)
|
|
308
|
+
});
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
**Short TTL (5-15 minutes):** Recent transactions, monthly data
|
|
312
|
+
```typescript
|
|
313
|
+
// Recent transactions change frequently
|
|
314
|
+
const recentTransactions = await cacheManager.wrap(`recent_txns_${budgetId}`, {
|
|
315
|
+
ttl: CACHE_TTLS.SHORT, // 5 minutes
|
|
316
|
+
loader: () => ynabAPI.transactions.getTransactions(budgetId, { since_date })
|
|
317
|
+
});
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**No Caching:** User-specific filtered transactions, write operations
|
|
321
|
+
```typescript
|
|
322
|
+
// Don't cache filtered or user-specific data
|
|
323
|
+
const filteredTransactions = await ynabAPI.transactions.getTransactions(budgetId, {
|
|
324
|
+
account_id: accountId,
|
|
325
|
+
category_id: categoryId,
|
|
326
|
+
since_date: userSpecificDate
|
|
327
|
+
});
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
#### Cache Invalidation Patterns
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
// Invalidate related caches after write operations
|
|
334
|
+
export async function handleCreateAccount(params: CreateAccountRequest) {
|
|
335
|
+
const result = await ynabAPI.accounts.createAccount(params);
|
|
336
|
+
|
|
337
|
+
// Invalidate related caches
|
|
338
|
+
cacheManager.delete(`accounts_${params.budget_id}`);
|
|
339
|
+
cacheManager.delete(`budget_${params.budget_id}`);
|
|
340
|
+
|
|
341
|
+
return result;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Pattern-based invalidation
|
|
345
|
+
export function invalidateAccountCaches(budgetId: string) {
|
|
346
|
+
const keysToInvalidate = [
|
|
347
|
+
`accounts_${budgetId}`,
|
|
348
|
+
`budget_${budgetId}`
|
|
349
|
+
];
|
|
350
|
+
|
|
351
|
+
keysToInvalidate.forEach(key => cacheManager.delete(key));
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
#### Cache Observability
|
|
356
|
+
|
|
357
|
+
Monitor cache performance with built-in metrics:
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
// Get cache statistics
|
|
361
|
+
const stats = cacheManager.getStats();
|
|
362
|
+
console.log('Cache Performance:', {
|
|
363
|
+
hitRate: stats.hit_rate,
|
|
364
|
+
totalHits: stats.total_hits,
|
|
365
|
+
totalMisses: stats.total_misses,
|
|
366
|
+
totalEntries: stats.total_entries,
|
|
367
|
+
evictions: stats.evictions
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
// Example output:
|
|
371
|
+
// Cache Performance: {
|
|
372
|
+
// hitRate: 0.75, // 75% hit rate
|
|
373
|
+
// totalHits: 150,
|
|
374
|
+
// totalMisses: 50,
|
|
375
|
+
// totalEntries: 45,
|
|
376
|
+
// evictions: 5
|
|
377
|
+
// }
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Cache Warming Strategies
|
|
381
|
+
|
|
382
|
+
Implement proactive cache warming for better user experience:
|
|
383
|
+
|
|
384
|
+
```typescript
|
|
385
|
+
// Cache warming after budget selection
|
|
386
|
+
export async function warmBudgetCache(budgetId: string) {
|
|
387
|
+
// Fire and forget - don't block user operations
|
|
388
|
+
const warmingPromises = [
|
|
389
|
+
cacheManager.wrap(`accounts_${budgetId}`, {
|
|
390
|
+
ttl: CACHE_TTLS.ACCOUNTS,
|
|
391
|
+
loader: () => ynabAPI.accounts.getAccounts(budgetId)
|
|
392
|
+
}),
|
|
393
|
+
cacheManager.wrap(`categories_${budgetId}`, {
|
|
394
|
+
ttl: CACHE_TTLS.CATEGORIES,
|
|
395
|
+
loader: () => ynabAPI.categories.getCategories(budgetId)
|
|
396
|
+
}),
|
|
397
|
+
cacheManager.wrap(`payees_${budgetId}`, {
|
|
398
|
+
ttl: CACHE_TTLS.PAYEES,
|
|
399
|
+
loader: () => ynabAPI.payees.getPayees(budgetId)
|
|
400
|
+
})
|
|
401
|
+
];
|
|
402
|
+
|
|
403
|
+
// Don't await - let these run in background
|
|
404
|
+
Promise.all(warmingPromises).catch(error => {
|
|
405
|
+
console.warn('Cache warming failed:', error.message);
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Trigger cache warming
|
|
410
|
+
export async function handleSetDefaultBudget(params: SetDefaultBudgetRequest) {
|
|
411
|
+
const result = await setDefaultBudget(params.budget_id);
|
|
412
|
+
|
|
413
|
+
// Warm cache for better subsequent performance
|
|
414
|
+
if (result.success) {
|
|
415
|
+
warmBudgetCache(params.budget_id);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
return result;
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
## Service Module Patterns
|
|
423
|
+
|
|
424
|
+
### Working with Service Modules
|
|
425
|
+
|
|
426
|
+
The v0.8.x releases decompose server functionality into focused service modules.
|
|
427
|
+
|
|
428
|
+
#### Resource Manager
|
|
429
|
+
|
|
430
|
+
Handle MCP resources consistently:
|
|
431
|
+
|
|
432
|
+
```typescript
|
|
433
|
+
// Custom resource definition
|
|
434
|
+
class MyResourceManager extends ResourceManager {
|
|
435
|
+
getResources() {
|
|
436
|
+
return [
|
|
437
|
+
...super.getResources(),
|
|
438
|
+
{
|
|
439
|
+
uri: 'my-app://custom-resource',
|
|
440
|
+
name: 'Custom Resource',
|
|
441
|
+
description: 'Application-specific resource',
|
|
442
|
+
mimeType: 'application/json'
|
|
443
|
+
}
|
|
444
|
+
];
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
async readResource(uri: string) {
|
|
448
|
+
if (uri === 'my-app://custom-resource') {
|
|
449
|
+
return {
|
|
450
|
+
contents: [{
|
|
451
|
+
type: 'text',
|
|
452
|
+
text: JSON.stringify({
|
|
453
|
+
custom_data: 'value',
|
|
454
|
+
timestamp: new Date().toISOString()
|
|
455
|
+
})
|
|
456
|
+
}]
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
return super.readResource(uri);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
#### Prompt Manager
|
|
465
|
+
|
|
466
|
+
Create dynamic prompts with context:
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
// Custom prompt with dynamic context
|
|
470
|
+
class MyPromptManager extends PromptManager {
|
|
471
|
+
getPrompts() {
|
|
472
|
+
return [
|
|
473
|
+
...super.getPrompts(),
|
|
474
|
+
{
|
|
475
|
+
name: 'analyze_spending',
|
|
476
|
+
description: 'Analyze spending patterns with budget context'
|
|
477
|
+
}
|
|
478
|
+
];
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
async getPrompt(name: string, args: any) {
|
|
482
|
+
if (name === 'analyze_spending') {
|
|
483
|
+
const budgetContext = await this.getBudgetContext(args.budget_id);
|
|
484
|
+
return {
|
|
485
|
+
messages: [{
|
|
486
|
+
role: 'user',
|
|
487
|
+
content: {
|
|
488
|
+
type: 'text',
|
|
489
|
+
text: `Analyze spending patterns for budget: ${budgetContext.name}.
|
|
490
|
+
Current month: ${budgetContext.current_month}.
|
|
491
|
+
Focus on categories with significant changes.`
|
|
492
|
+
}
|
|
493
|
+
}]
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
return super.getPrompt(name, args);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
#### Diagnostic Manager
|
|
502
|
+
|
|
503
|
+
Extend diagnostics for custom monitoring:
|
|
504
|
+
|
|
505
|
+
```typescript
|
|
506
|
+
class MyDiagnosticManager extends DiagnosticManager {
|
|
507
|
+
async getSystemDiagnostics() {
|
|
508
|
+
const baseDiagnostics = await super.getSystemDiagnostics();
|
|
509
|
+
|
|
510
|
+
return {
|
|
511
|
+
...baseDiagnostics,
|
|
512
|
+
custom_metrics: {
|
|
513
|
+
active_integrations: this.getActiveIntegrations(),
|
|
514
|
+
last_sync_time: this.getLastSyncTime(),
|
|
515
|
+
error_rate: this.calculateErrorRate()
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
private getActiveIntegrations() {
|
|
521
|
+
// Custom integration monitoring
|
|
522
|
+
return {
|
|
523
|
+
external_apis: ['ynab', 'my_custom_api'],
|
|
524
|
+
webhooks: this.activeWebhooks.length,
|
|
525
|
+
background_jobs: this.backgroundJobs.size
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
## Migration from v0.7.x
|
|
532
|
+
|
|
533
|
+
### No Breaking Changes for Users
|
|
534
|
+
|
|
535
|
+
**Important:** All v0.7.x tool calls, parameters, and responses work identically in v0.8.x. This section is for developers working with the internal architecture.
|
|
536
|
+
|
|
537
|
+
### Internal API Changes
|
|
538
|
+
|
|
539
|
+
#### Error Handling Migration
|
|
540
|
+
|
|
541
|
+
**v0.7.x Pattern:**
|
|
542
|
+
```typescript
|
|
543
|
+
// Direct error throwing
|
|
544
|
+
if (!budgetId) {
|
|
545
|
+
throw new Error('No budget ID provided');
|
|
546
|
+
}
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
**v0.8.x Pattern:**
|
|
550
|
+
```typescript
|
|
551
|
+
// Centralized error handling with consistent format
|
|
552
|
+
const result = BudgetResolver.resolveBudgetId(providedId, defaultId);
|
|
553
|
+
if (typeof result !== 'string') {
|
|
554
|
+
return result; // Returns properly formatted CallToolResult
|
|
555
|
+
}
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
#### Caching Migration
|
|
559
|
+
|
|
560
|
+
**v0.7.x Pattern:**
|
|
561
|
+
```typescript
|
|
562
|
+
// Manual cache management
|
|
563
|
+
const cached = cacheManager.get(key);
|
|
564
|
+
if (cached && !isExpired(cached)) {
|
|
565
|
+
return cached.data;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
const result = await apiCall();
|
|
569
|
+
cacheManager.set(key, result, ttl);
|
|
570
|
+
return result;
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
**v0.8.x Pattern:**
|
|
574
|
+
```typescript
|
|
575
|
+
// Enhanced cache wrapper with observability
|
|
576
|
+
return cacheManager.wrap(key, {
|
|
577
|
+
ttl: CACHE_TTLS.ACCOUNTS,
|
|
578
|
+
staleWhileRevalidate: 120000,
|
|
579
|
+
loader: () => apiCall()
|
|
580
|
+
});
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
#### Tool Registration Migration
|
|
584
|
+
|
|
585
|
+
**v0.7.x Pattern:**
|
|
586
|
+
```typescript
|
|
587
|
+
// Direct switch statement in handleCallTool
|
|
588
|
+
case 'my_tool':
|
|
589
|
+
return withSecurityWrapper(async () => {
|
|
590
|
+
const validated = MyToolSchema.parse(params);
|
|
591
|
+
return await handleMyTool(validated);
|
|
592
|
+
});
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
**v0.8.x Pattern:**
|
|
596
|
+
```typescript
|
|
597
|
+
// Registry-based registration
|
|
598
|
+
registry.register({
|
|
599
|
+
name: 'my_tool',
|
|
600
|
+
description: 'Tool description',
|
|
601
|
+
inputSchema: MyToolSchema,
|
|
602
|
+
handler: adapt(handleMyTool),
|
|
603
|
+
defaultArgumentResolver: resolveBudgetId()
|
|
604
|
+
});
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
### Testing Pattern Updates
|
|
608
|
+
|
|
609
|
+
**Enhanced Dependency Injection for Testing:**
|
|
610
|
+
|
|
611
|
+
```typescript
|
|
612
|
+
// v0.8.x - Mock individual services
|
|
613
|
+
const mockCacheManager = {
|
|
614
|
+
wrap: vi.fn().mockImplementation((key, options) => options.loader()),
|
|
615
|
+
getStats: vi.fn().mockReturnValue({ hit_rate: 0.5 })
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
const mockErrorHandler = {
|
|
619
|
+
createErrorResponse: vi.fn().mockReturnValue({ success: false })
|
|
620
|
+
};
|
|
621
|
+
|
|
622
|
+
// Test with mocked dependencies
|
|
623
|
+
const service = new MyService(mockCacheManager, mockErrorHandler);
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### Import Path Updates
|
|
627
|
+
|
|
628
|
+
Most imports remain the same due to barrel exports:
|
|
629
|
+
|
|
630
|
+
```typescript
|
|
631
|
+
// Still works (barrel export)
|
|
632
|
+
import { handleMyTool } from '../tools/myTool.js';
|
|
633
|
+
|
|
634
|
+
// New modular imports available
|
|
635
|
+
import { parseCSV } from '../tools/compareTransactions/parser.js';
|
|
636
|
+
import { findMatches } from '../tools/compareTransactions/matcher.js';
|
|
637
|
+
import { formatResults } from '../tools/compareTransactions/formatter.js';
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
### Performance Improvements to Expect
|
|
641
|
+
|
|
642
|
+
- **Cache Hit Rate**: 60-80% for repeated operations
|
|
643
|
+
- **Initial Load Time**: Faster due to cache warming
|
|
644
|
+
- **Memory Usage**: More efficient with LRU eviction
|
|
645
|
+
- **Error Response Time**: Faster with pre-formatted responses
|
|
646
|
+
|
|
647
|
+
---
|
|
648
|
+
|
|
649
|
+
For practical development patterns and examples, see [`DEVELOPMENT.md`](DEVELOPMENT.md).
|
|
650
|
+
For troubleshooting guidance, see [`../reference/TROUBLESHOOTING.md`](../reference/TROUBLESHOOTING.md).
|