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