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