@dizzlkheinz/ynab-mcpb 0.16.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,153 +0,0 @@
1
- # YNAB MCP v0.14 Hardening Implementation Plan
2
-
3
- > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
4
-
5
- **Goal:** Ship v0.14 with tighter schema fidelity, cache/knowledge resets, resilient config+token handling, clearer reconciliation errors, and strongly-typed dry-run payloads.
6
-
7
- **Architecture:** Focused, TDD-driven changes inside existing server/tool layers: enforce ToolRegistry metadata/schema parity, route cache clears through DeltaCache, inject per-instance config with robust token validation, add error normalization in reconciliation executor, and replace untyped dry-run request blobs with explicit Zod schemas mirrored by handlers.
8
-
9
- **Tech Stack:** TypeScript 5, Node 18+, MCP SDK, Zod, Vitest (unit/integration/e2e), Prettier/ESLint, docs in `docs/reference`.
10
-
11
- ### Task 1: Enforce tool metadata schema parity
12
-
13
- **Files:**
14
- - Modify: `src/server/toolRegistry.ts`
15
- - Modify: `src/server/__tests__/toolRegistry.test.ts`
16
-
17
- **Step 1: Write failing unit test**
18
- Add a case that registers a tool whose `metadata.inputJsonSchema` differs from the generated schema and expects an error: `metadata input schema must match generated schema for tool "budget-sync"`.
19
-
20
- **Step 2: Run test to see it fail**
21
- `npm run test:unit -- --runInBand src/server/__tests__/toolRegistry.test.ts --testNamePattern "metadata input schema"`
22
-
23
- **Step 3: Implement enforcement**
24
- In `register`, call a new helper (e.g., `ensureMetadataSchemaMatches`) that generates the JSON schema from `inputSchema`; if `metadata.inputJsonSchema` exists and differs, throw; otherwise populate it. Remove redundant schema regeneration in `listTools` when metadata is present.
25
-
26
- **Step 4: Re-run unit test**
27
- `npm run test:unit -- --runInBand src/server/__tests__/toolRegistry.test.ts --testNamePattern "metadata input schema"`
28
-
29
- **Step 5: Commit**
30
- `git add src/server/toolRegistry.ts src/server/__tests__/toolRegistry.test.ts && git commit -m "fix: validate tool metadata schemas at registration"`
31
-
32
- ### Task 2: Make clear_cache reset delta knowledge
33
-
34
- **Files:**
35
- - Modify: `src/server/YNABMCPServer.ts`
36
- - Modify: `src/server/__tests__/YNABMCPServer.integration.test.ts`
37
- - Modify: `docs/reference/TOOLS.md`
38
-
39
- **Step 1: Add failing integration test**
40
- In `YNABMCPServer.integration.test.ts`, assert that after `list_accounts` populates caches, `clear_cache` drives knowledge entries to zero via `diagnostic_info` with `include_delta: true`.
41
-
42
- **Step 2: Run test to confirm failure**
43
- `npm run test:integration:domain -- --testNamePattern "clear cache runs"`
44
-
45
- **Step 3: Implement reset**
46
- In `setupToolRegistry`, change the `clear_cache` handler to call `this.deltaCache.forceFullRefresh()` (not just `cacheManager.clear()`), ensuring both cache and `ServerKnowledgeStore` reset.
47
-
48
- **Step 4: Update docs**
49
- Document in `docs/reference/TOOLS.md` that `clear_cache` now clears cache *and* delta knowledge.
50
-
51
- **Step 5: Re-run integration slice**
52
- `npm run test:integration:domain -- --testNamePattern "clear cache runs"`
53
-
54
- **Step 6: Commit**
55
- `git add src/server/YNABMCPServer.ts src/server/__tests__/YNABMCPServer.integration.test.ts docs/reference/TOOLS.md && git commit -m "feat: reset delta knowledge when cache is cleared"`
56
-
57
- ### Task 3: Reloadable config, per-instance server config, and resilient token validation
58
-
59
- **Files:**
60
- - Modify: `src/server/config.ts`
61
- - Modify: `src/server/YNABMCPServer.ts`
62
- - Modify: `src/server/__tests__/config.test.ts`
63
- - Modify: `src/server/__tests__/YNABMCPServer.test.ts`
64
- - Modify: `src/server/__tests__/server-startup.integration.test.ts`
65
- - Modify: `scripts/run-throttled-integration-tests.js`
66
-
67
- **Step 1: Verify/extend config reload tests**
68
- Ensure `config.test.ts` covers re-parsing on successive `loadConfig()` calls and explicit env overrides. Add a case asserting per-call env changes are observed.
69
-
70
- **Step 2: Add failing per-instance server test**
71
- In `YNABMCPServer.test.ts`, instantiate two servers after mutating `process.env.YNAB_ACCESS_TOKEN` and assert each uses its instantiation-time config (via diagnostic/info accessor).
72
-
73
- **Step 3: Make config injectable per instance**
74
- In `YNABMCPServer.ts`, replace module-level `config` usage with `this.serverConfig = loadConfig()` inside the constructor; route YNAB API creation and tool setup through `this.serverConfig`.
75
-
76
- **Step 4: Harden token validation**
77
- Wrap `validateToken` to catch `SyntaxError` / malformed JSON or HTML responses from YNAB and throw `AuthenticationError` with guidance; keep 401/403 handling; rethrow others.
78
-
79
- **Step 5: Windows-safe throttled runner**
80
- In `scripts/run-throttled-integration-tests.js`, spawn Vitest via a platform-safe path (use `.cmd` on win32, otherwise the binary) and avoid EINVAL issues.
81
-
82
- **Step 6: Run focused tests**
83
- `npm run test:unit -- src/server/__tests__/config.test.ts src/server/__tests__/YNABMCPServer.test.ts`
84
- `npm run test:integration:core -- --testNamePattern "server-startup"`
85
- `node scripts/run-throttled-integration-tests.js --help` (manual sanity on Windows)
86
-
87
- **Step 7: Commit**
88
- `git add src/server/config.ts src/server/YNABMCPServer.ts src/server/__tests__/*.ts scripts/run-throttled-integration-tests.js && git commit -m "feat: reloadable config and robust token validation"`
89
-
90
- ### Task 4: Propagate fatal YNAB errors during reconciliation
91
-
92
- **Files:**
93
- - Modify: `src/tools/reconciliation/executor.ts`
94
- - Modify: `src/tools/reconciliation/__tests__/executor.test.ts`
95
- - Modify: `src/tools/reconciliation/__tests__/executor.integration.test.ts`
96
-
97
- **Step 1: Add failing unit tests for error normalization**
98
- Cover `normalizeYnabError`, `shouldPropagateYnabError`, and status/message shaping for 429/404 plus generic errors.
99
-
100
- **Step 2: Implement normalization helpers**
101
- Add helpers in `executor.ts` to parse YNAB SDK error objects, standard Errors, and strings; decide propagation for 401/403/404/429/500/503; attach status to thrown Error.
102
-
103
- **Step 3: Add failing integration test for bulk rate-limit**
104
- Simulate bulk create rejecting with `id: '429'` and assert `executeReconciliation` rejects with status 429 instead of silent fallback.
105
-
106
- **Step 4: Wire helpers into bulk + sequential paths**
107
- In bulk chunk catch blocks, propagate fatal errors, otherwise log and fall back; in sequential creation, log failure reasons with status and propagate fatal errors after logging.
108
-
109
- **Step 5: Run reconciliation suites**
110
- `npm run test:unit -- src/tools/reconciliation/__tests__/executor.test.ts`
111
- `npm run test:integration:reconciliation` (or project pattern)
112
-
113
- **Step 6: Commit**
114
- `git add src/tools/reconciliation/executor.ts src/tools/reconciliation/__tests__/executor*.test.ts && git commit -m "fix: propagate fatal YNAB errors during reconciliation"`
115
-
116
- ### Task 5: Strongly type dry-run transaction outputs
117
-
118
- **Files:**
119
- - Modify: `src/tools/schemas/outputs/transactionMutationOutputs.ts`
120
- - Modify: `src/tools/schemas/outputs/__tests__/transactionMutationSchemas.test.ts`
121
- - Modify: `src/tools/transactionTools.ts`
122
- - Modify: `src/tools/__tests__/transactionTools.test.ts`
123
- - (Optional) Modify: `src/tools/__tests__/transactionTools.integration.test.ts`, `src/__tests__/workflows.e2e.test.ts`
124
-
125
- **Step 1: Add failing schema tests**
126
- Assert dry-run `request` for create/update/delete matches explicit schemas (no `budget_id`/`dry_run`, required ids present) and rejects arbitrary `z.record` payloads.
127
-
128
- **Step 2: Define typed dry-run request schemas**
129
- In `transactionMutationOutputs.ts`, introduce `CreateTransactionDryRunRequestSchema`, `UpdateTransactionDryRunRequestSchema`, and `DeleteTransactionDryRunRequestSchema` (omit `budget_id`/`dry_run`), export inferred types, and replace existing `z.record` uses in dry-run branches.
130
-
131
- **Step 3: Update handler dry-run branches**
132
- In `transactionTools.ts`, build `request` objects that include only allowed fields (exclude `budget_id`/`dry_run`) for create/update/delete dry-runs.
133
-
134
- **Step 4: Update unit tests**
135
- Adjust/create tests in `transactionTools.test.ts` to assert dry-run outputs match the new schemas and make no API calls.
136
-
137
- **Step 5: (Optional) Integration/E2E checks**
138
- Add integration/E2E assertions that dry-run outputs validate against updated schemas.
139
-
140
- **Step 6: Run targeted suites**
141
- `npm run test:unit -- src/tools/schemas/outputs/__tests__/transactionMutationSchemas.test.ts src/tools/__tests__/transactionTools.test.ts`
142
- `npm run test:integration -- --testPathPattern=transactionTools` (if present)
143
-
144
- **Step 7: Commit**
145
- `git add src/tools/schemas/outputs/transactionMutationOutputs.ts src/tools/schemas/outputs/__tests__/transactionMutationSchemas.test.ts src/tools/transactionTools.ts src/tools/__tests__/transactionTools.test.ts && git commit -m "feat: type-safe dry-run transaction outputs"`
146
-
147
- ### Final verification (after all tasks)
148
-
149
- - `npm run lint`
150
- - `npm run type-check`
151
- - `npm test`
152
- - `npm run build` (or `npm run build:prod` if cutting release)
153
- - Update `CHANGELOG.md` and `.pr-description.md` with changes and test commands.