@dizzlkheinz/ynab-mcpb 0.18.4 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +19 -12
- package/dist/tools/reconciliation/analyzer.d.ts +4 -4
- package/dist/tools/reconciliation/analyzer.js +73 -59
- 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 +59 -58
- package/dist/tools/reconciliation/signDetector.d.ts +1 -1
- package/dist/tools/reconciliation/types.d.ts +16 -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 +7 -7
- package/dist/tools/transactionSchemas.js +77 -57
- package/dist/tools/transactionTools.d.ts +6 -24
- package/dist/tools/transactionTools.js +7 -1499
- package/dist/tools/transactionUtils.d.ts +6 -6
- package/dist/tools/transactionUtils.js +78 -63
- 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/esbuild.config.mjs +53 -50
- package/meta.json +12548 -12548
- package/package.json +98 -111
- package/scripts/analyze-bundle.mjs +33 -30
- package/scripts/create-pr-description.js +169 -120
- package/scripts/run-all-tests.js +178 -169
- 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 +1202 -1186
- 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 +1004 -977
- 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 -252
- package/src/tools/reconciliation/CLAUDE.md +506 -0
- package/src/tools/reconciliation/__tests__/adapter.causes.test.ts +133 -124
- package/src/tools/reconciliation/__tests__/adapter.test.ts +249 -230
- package/src/tools/reconciliation/__tests__/analyzer.test.ts +408 -400
- 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 -989
- package/src/tools/reconciliation/__tests__/reconciliation.delta.integration.test.ts +187 -146
- package/src/tools/reconciliation/__tests__/reportFormatter.test.ts +583 -533
- package/src/tools/reconciliation/__tests__/scenarios/adapterCurrency.scenario.test.ts +75 -74
- package/src/tools/reconciliation/__tests__/scenarios/extremes.scenario.test.ts +70 -62
- package/src/tools/reconciliation/__tests__/scenarios/repeatAmount.scenario.test.ts +102 -88
- package/src/tools/reconciliation/__tests__/schemaUrl.test.ts +56 -55
- 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 +564 -504
- 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 +343 -307
- package/src/tools/reconciliation/signDetector.ts +89 -83
- package/src/tools/reconciliation/types.ts +164 -159
- 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 +322 -291
- package/src/tools/transactionTools.ts +84 -2246
- package/src/tools/transactionUtils.ts +507 -422
- 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
|
@@ -1,194 +1,231 @@
|
|
|
1
|
-
import { CallToolResult } from
|
|
2
|
-
import { ErrorHandler } from
|
|
1
|
+
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import { type ErrorHandler, createErrorHandler } from "./errorHandler.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Module-level fallback ErrorHandler for convenience functions and backward compatibility.
|
|
6
|
+
* Uses a simple JSON formatter; callers that have access to the injected formatter
|
|
7
|
+
* should pass their own ErrorHandler instance via the optional parameter.
|
|
8
|
+
*/
|
|
9
|
+
const fallbackErrorHandler = createErrorHandler({
|
|
10
|
+
format: (value: unknown) => JSON.stringify(value, null, 2),
|
|
11
|
+
});
|
|
3
12
|
|
|
4
13
|
/**
|
|
5
14
|
* Centralized budget resolution helper that standardizes budget ID validation
|
|
6
15
|
* and resolution logic across the entire YNAB MCP server
|
|
7
16
|
*/
|
|
17
|
+
// biome-ignore lint/complexity/noStaticOnlyClass: static utility class
|
|
8
18
|
export class BudgetResolver {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
19
|
+
/**
|
|
20
|
+
* UUID format validation regex (accepts UUID versions 1-5)
|
|
21
|
+
*/
|
|
22
|
+
private static readonly UUID_REGEX =
|
|
23
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Special keywords that are allowed as budget IDs
|
|
27
|
+
*/
|
|
28
|
+
private static readonly ALLOWED_KEYWORDS = ["default"] as const;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Resolves a budget ID using provided ID or default, with standardized error handling.
|
|
32
|
+
* Maps keywords ('default') to concrete budget IDs to prevent 404s from YNAB API.
|
|
33
|
+
*
|
|
34
|
+
* Note: While YNAB API natively supports the "default" keyword, this MCP server
|
|
35
|
+
* intentionally intercepts it to use its own locally-stored default budget ID
|
|
36
|
+
* (set via set_default_budget tool). This provides caching, consistency, and
|
|
37
|
+
* allows the MCP server to maintain default budget state independently of YNAB's
|
|
38
|
+
* OAuth default budget setting.
|
|
39
|
+
*
|
|
40
|
+
* @param providedId - The budget ID provided by the user (optional)
|
|
41
|
+
* @param defaultId - The default budget ID to fall back to (optional)
|
|
42
|
+
* @returns The resolved budget ID string or CallToolResult with error
|
|
43
|
+
*/
|
|
44
|
+
static resolveBudgetId(
|
|
45
|
+
providedId?: string,
|
|
46
|
+
defaultId?: string,
|
|
47
|
+
errorHandler?: ErrorHandler,
|
|
48
|
+
): string | CallToolResult {
|
|
49
|
+
// If a budget ID is provided (including empty strings), handle keywords first
|
|
50
|
+
if (providedId !== undefined && providedId !== null) {
|
|
51
|
+
const trimmed = providedId.trim();
|
|
52
|
+
|
|
53
|
+
// Handle special keywords
|
|
54
|
+
if (trimmed === "default") {
|
|
55
|
+
// For "default" keyword, we use the MCP server's stored default budget ID
|
|
56
|
+
// rather than passing "default" to YNAB API (see function JSDoc for rationale)
|
|
57
|
+
if (defaultId) {
|
|
58
|
+
return BudgetResolver.validateBudgetId(defaultId, errorHandler);
|
|
59
|
+
}
|
|
60
|
+
// No default budget set in MCP server, return error
|
|
61
|
+
return BudgetResolver.createMissingBudgetError(errorHandler);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (trimmed === "last-used") {
|
|
65
|
+
// "last-used" keyword is not currently supported
|
|
66
|
+
const eh = errorHandler ?? fallbackErrorHandler;
|
|
67
|
+
return eh.createValidationError(
|
|
68
|
+
"Unsupported keyword",
|
|
69
|
+
'The "last-used" keyword is not supported yet. Please use a specific budget ID or set a default budget.',
|
|
70
|
+
[
|
|
71
|
+
"Use a specific budget ID (UUID format)",
|
|
72
|
+
"Set a default budget using the set_default_budget tool",
|
|
73
|
+
'Use the "default" keyword after setting a default budget',
|
|
74
|
+
"Run the list_budgets tool to see available budget IDs",
|
|
75
|
+
],
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// For non-keyword IDs, validate normally (including empty strings)
|
|
80
|
+
return BudgetResolver.validateBudgetId(providedId, errorHandler);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// If no budget ID provided, try to use the default
|
|
84
|
+
if (defaultId) {
|
|
85
|
+
return BudgetResolver.validateBudgetId(defaultId, errorHandler);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// No budget ID provided and no default set
|
|
89
|
+
return BudgetResolver.createMissingBudgetError(errorHandler);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Validates that a budget ID has the correct format
|
|
94
|
+
*
|
|
95
|
+
* @param budgetId - The budget ID to validate
|
|
96
|
+
* @returns The validated budget ID or CallToolResult with error
|
|
97
|
+
*/
|
|
98
|
+
static validateBudgetId(
|
|
99
|
+
budgetId: string,
|
|
100
|
+
errorHandler?: ErrorHandler,
|
|
101
|
+
): string | CallToolResult {
|
|
102
|
+
if (!budgetId || typeof budgetId !== "string") {
|
|
103
|
+
return BudgetResolver.createInvalidBudgetError(
|
|
104
|
+
"Budget ID must be provided as a non-empty string",
|
|
105
|
+
errorHandler,
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const trimmed = budgetId.trim();
|
|
110
|
+
if (!trimmed) {
|
|
111
|
+
return BudgetResolver.createInvalidBudgetError(
|
|
112
|
+
"Budget ID cannot be empty or whitespace only",
|
|
113
|
+
errorHandler,
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Allow simplified identifiers in test environments
|
|
118
|
+
if (process.env["NODE_ENV"] === "test") {
|
|
119
|
+
const testIdentifierPattern =
|
|
120
|
+
/^(test|budget|account|category|transaction|payee|mock)-[a-z0-9_-]+$/i;
|
|
121
|
+
if (testIdentifierPattern.test(trimmed)) {
|
|
122
|
+
return trimmed;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Validate UUID format
|
|
127
|
+
if (!BudgetResolver.UUID_REGEX.test(trimmed)) {
|
|
128
|
+
return BudgetResolver.createInvalidBudgetError(
|
|
129
|
+
`Invalid budget ID format: '${trimmed}'. Must be a valid UUID format (versions 1-5)`,
|
|
130
|
+
errorHandler,
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return trimmed;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Creates a standardized error response for missing budget scenarios
|
|
139
|
+
*
|
|
140
|
+
* @returns CallToolResult with standardized error response
|
|
141
|
+
*/
|
|
142
|
+
static createMissingBudgetError(errorHandler?: ErrorHandler): CallToolResult {
|
|
143
|
+
const detailMessage = `A budget ID is required for this operation. You can either:
|
|
119
144
|
1. Provide a specific budget_id parameter
|
|
120
145
|
2. Set a default budget using the set_default_budget tool first`;
|
|
121
146
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
147
|
+
const eh = errorHandler ?? fallbackErrorHandler;
|
|
148
|
+
return eh.createValidationError(
|
|
149
|
+
"No budget ID provided and no default budget set",
|
|
150
|
+
detailMessage,
|
|
151
|
+
[
|
|
152
|
+
"Set a default budget first using the set_default_budget tool",
|
|
153
|
+
"Provide a budget_id parameter when invoking the tool",
|
|
154
|
+
],
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Creates a standardized error response for invalid budget ID format
|
|
160
|
+
*
|
|
161
|
+
* @param details - Specific details about the validation failure
|
|
162
|
+
* @returns CallToolResult with standardized error response
|
|
163
|
+
*/
|
|
164
|
+
static createInvalidBudgetError(
|
|
165
|
+
details: string,
|
|
166
|
+
errorHandler?: ErrorHandler,
|
|
167
|
+
): CallToolResult {
|
|
168
|
+
const detailMessage = `${details}
|
|
140
169
|
|
|
141
170
|
Valid formats:
|
|
142
171
|
- UUID format (versions 1-5, e.g., "123e4567-e89b-12d3-a456-426614174000")
|
|
143
|
-
- Special keywords: ${
|
|
172
|
+
- Special keywords: ${BudgetResolver.ALLOWED_KEYWORDS.map((k) => `"${k}"`).join(", ")}
|
|
144
173
|
|
|
145
174
|
You can use the list_budgets tool to see available budget IDs.`;
|
|
146
175
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
176
|
+
const eh = errorHandler ?? fallbackErrorHandler;
|
|
177
|
+
return eh.createValidationError("Invalid budget ID format", detailMessage, [
|
|
178
|
+
"Use a valid UUID format (UUID v1-v5, e.g., 123e4567-e89b-12d3-a456-426614174000; standard UUID v4 format works as well)",
|
|
179
|
+
"Run the list_budgets tool to view available budget IDs",
|
|
180
|
+
'Use the special keyword "default" for convenience',
|
|
181
|
+
]);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Convenience function that throws an error if budget resolution fails
|
|
186
|
+
*
|
|
187
|
+
* @param providedId - The budget ID provided by the user (optional)
|
|
188
|
+
* @param defaultId - The default budget ID to fall back to (optional)
|
|
189
|
+
* @returns The resolved budget ID string
|
|
190
|
+
* @throws Error if resolution fails
|
|
191
|
+
*/
|
|
192
|
+
static resolveBudgetIdOrThrow(
|
|
193
|
+
providedId?: string,
|
|
194
|
+
defaultId?: string,
|
|
195
|
+
): string {
|
|
196
|
+
const result = BudgetResolver.resolveBudgetId(providedId, defaultId);
|
|
197
|
+
if (typeof result === "string") {
|
|
198
|
+
return result;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Extract error message from CallToolResult for throwing
|
|
202
|
+
const errorText =
|
|
203
|
+
result.content?.[0]?.type === "text"
|
|
204
|
+
? result.content[0].text
|
|
205
|
+
: "Budget resolution failed";
|
|
206
|
+
throw new Error(errorText);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Convenience function that validates budget ID and throws an error if validation fails
|
|
211
|
+
*
|
|
212
|
+
* @param budgetId - The budget ID to validate
|
|
213
|
+
* @returns The validated budget ID string
|
|
214
|
+
* @throws Error if validation fails
|
|
215
|
+
*/
|
|
216
|
+
static validateBudgetIdOrThrow(budgetId: string): string {
|
|
217
|
+
const result = BudgetResolver.validateBudgetId(budgetId);
|
|
218
|
+
if (typeof result === "string") {
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Extract error message from CallToolResult for throwing
|
|
223
|
+
const errorText =
|
|
224
|
+
result.content?.[0]?.type === "text"
|
|
225
|
+
? result.content[0].text
|
|
226
|
+
: "Budget validation failed";
|
|
227
|
+
throw new Error(errorText);
|
|
228
|
+
}
|
|
192
229
|
}
|
|
193
230
|
|
|
194
231
|
/**
|
|
@@ -202,8 +239,11 @@ You can use the list_budgets tool to see available budget IDs.`;
|
|
|
202
239
|
* @param defaultId - Default budget ID to use if `providedId` is not present (optional)
|
|
203
240
|
* @returns The resolved budget ID string, or a `CallToolResult` describing a validation error
|
|
204
241
|
*/
|
|
205
|
-
export function resolveBudgetId(
|
|
206
|
-
|
|
242
|
+
export function resolveBudgetId(
|
|
243
|
+
providedId?: string,
|
|
244
|
+
defaultId?: string,
|
|
245
|
+
): string | CallToolResult {
|
|
246
|
+
return BudgetResolver.resolveBudgetId(providedId, defaultId);
|
|
207
247
|
}
|
|
208
248
|
|
|
209
249
|
/**
|
|
@@ -212,7 +252,7 @@ export function resolveBudgetId(providedId?: string, defaultId?: string): string
|
|
|
212
252
|
* @returns The validated budget ID string, or a CallToolResult describing the validation error.
|
|
213
253
|
*/
|
|
214
254
|
export function validateBudgetId(budgetId: string): string | CallToolResult {
|
|
215
|
-
|
|
255
|
+
return BudgetResolver.validateBudgetId(budgetId);
|
|
216
256
|
}
|
|
217
257
|
|
|
218
258
|
/**
|
|
@@ -221,7 +261,7 @@ export function validateBudgetId(budgetId: string): string | CallToolResult {
|
|
|
221
261
|
* @returns A CallToolResult representing a validation error that explains a budget_id is missing and provides guidance to supply a `budget_id` or configure a default budget.
|
|
222
262
|
*/
|
|
223
263
|
export function createMissingBudgetError(): CallToolResult {
|
|
224
|
-
|
|
264
|
+
return BudgetResolver.createMissingBudgetError();
|
|
225
265
|
}
|
|
226
266
|
|
|
227
267
|
/**
|
|
@@ -231,5 +271,5 @@ export function createMissingBudgetError(): CallToolResult {
|
|
|
231
271
|
* @returns CallToolResult with standardized error response
|
|
232
272
|
*/
|
|
233
273
|
export function createInvalidBudgetError(details: string): CallToolResult {
|
|
234
|
-
|
|
274
|
+
return BudgetResolver.createInvalidBudgetError(details);
|
|
235
275
|
}
|
package/src/server/cacheKeys.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export const CacheKeys = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
ACCOUNTS: "accounts",
|
|
3
|
+
BUDGETS: "budgets",
|
|
4
|
+
CATEGORIES: "categories",
|
|
5
|
+
PAYEES: "payees",
|
|
6
|
+
TRANSACTIONS: "transactions",
|
|
7
|
+
MONTHS: "months",
|
|
8
8
|
} as const;
|