@dizzlkheinz/ynab-mcpb 0.16.1 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +33 -33
- package/.github/workflows/ci-tests.yml +45 -45
- package/.github/workflows/claude-code-review.yml +57 -57
- package/.github/workflows/claude.yml +50 -50
- package/.github/workflows/full-integration.yml +22 -22
- package/.github/workflows/publish.yml +11 -2
- package/CLAUDE.md +33 -47
- package/README.md +8 -10
- package/dist/bundle/index.cjs +54 -54
- package/dist/server/YNABMCPServer.d.ts +120 -54
- package/dist/server/YNABMCPServer.js +28 -381
- package/dist/server/config.d.ts +2 -0
- package/dist/server/config.js +1 -0
- package/dist/server/securityMiddleware.d.ts +37 -8
- package/dist/tools/accountTools.d.ts +2 -0
- package/dist/tools/accountTools.js +45 -0
- package/dist/tools/adapters.d.ts +12 -0
- package/dist/tools/adapters.js +25 -0
- package/dist/tools/budgetTools.d.ts +2 -0
- package/dist/tools/budgetTools.js +30 -0
- package/dist/tools/categoryTools.d.ts +2 -0
- package/dist/tools/categoryTools.js +45 -0
- package/dist/tools/monthTools.d.ts +2 -0
- package/dist/tools/monthTools.js +32 -0
- package/dist/tools/payeeTools.d.ts +2 -0
- package/dist/tools/payeeTools.js +32 -0
- package/dist/tools/reconciliation/index.d.ts +2 -0
- package/dist/tools/reconciliation/index.js +33 -0
- package/dist/tools/schemas/common.d.ts +3 -0
- package/dist/tools/schemas/common.js +3 -0
- package/dist/tools/schemas/outputs/comparisonOutputs.d.ts +1 -1
- package/dist/tools/schemas/outputs/index.d.ts +2 -2
- package/dist/tools/schemas/outputs/index.js +2 -2
- package/dist/tools/schemas/outputs/utilityOutputs.d.ts +0 -15
- package/dist/tools/schemas/outputs/utilityOutputs.js +0 -9
- package/dist/tools/transactionTools.d.ts +2 -0
- package/dist/tools/transactionTools.js +124 -0
- package/dist/tools/utilityTools.d.ts +2 -7
- package/dist/tools/utilityTools.js +19 -38
- package/dist/types/index.d.ts +1 -0
- package/dist/types/toolRegistration.d.ts +27 -0
- package/dist/types/toolRegistration.js +1 -0
- package/docs/maintainers/npm-publishing.md +27 -0
- package/docs/reference/API.md +15 -70
- package/docs/technical/reconciliation-system-architecture.md +2251 -2251
- package/package.json +6 -6
- package/scripts/analyze-bundle.mjs +41 -41
- package/scripts/generate-mcpb.ps1 +95 -95
- package/scripts/run-domain-integration-tests.js +4 -1
- package/scripts/watch-and-restart.ps1 +49 -49
- package/src/__tests__/comprehensive.integration.test.ts +0 -28
- package/src/__tests__/performance.test.ts +4 -12
- package/src/__tests__/setup.ts +45 -14
- package/src/__tests__/workflows.e2e.test.ts +1 -51
- package/src/server/YNABMCPServer.ts +33 -519
- package/src/server/__tests__/YNABMCPServer.test.ts +0 -1
- package/src/server/__tests__/toolRegistration.test.ts +236 -0
- package/src/server/config.ts +1 -0
- package/src/tools/__tests__/adapters.test.ts +113 -0
- package/src/tools/__tests__/transactionTools.integration.test.ts +63 -3
- package/src/tools/__tests__/utilityTools.integration.test.ts +1 -85
- package/src/tools/__tests__/utilityTools.test.ts +1 -123
- package/src/tools/accountTools.ts +53 -0
- package/src/tools/adapters.ts +74 -0
- package/src/tools/budgetTools.ts +37 -0
- package/src/tools/categoryTools.ts +53 -0
- package/src/tools/monthTools.ts +39 -0
- package/src/tools/payeeTools.ts +39 -0
- package/src/tools/reconciliation/index.ts +45 -0
- package/src/tools/schemas/common.ts +18 -0
- package/src/tools/schemas/outputs/index.ts +0 -3
- package/src/tools/schemas/outputs/utilityOutputs.ts +2 -43
- package/src/tools/toolCategories.ts +0 -1
- package/src/tools/transactionTools.ts +140 -0
- package/src/tools/utilityTools.ts +24 -55
- package/src/types/index.ts +3 -0
- package/src/types/toolRegistration.ts +88 -0
- package/vitest.config.ts +2 -1
- package/.chunkhound.json +0 -11
- package/.code/agents/01a13ef4-3f23-4f52-b33b-3585b73cfa60/error.txt +0 -3
- package/.code/agents/084fd32f-e298-4728-9103-a78d7dc39613/error.txt +0 -3
- package/.code/agents/0fed51e1-a943-4b97-a2a8-a6f0f27c844d/status.txt +0 -1
- package/.code/agents/1059b6bd-5ccd-4d83-a12c-7c9d89137399/error.txt +0 -5
- package/.code/agents/110/exec-call_F9BDNG7JfxKkq7Vc8ESAvdft.txt +0 -1569
- package/.code/agents/11ebcef3-b13f-4e44-ad80-d94a866804b7/error.txt +0 -3
- package/.code/agents/1398/exec-call_CjItcWMU1G6JoPshX62QvpaR.txt +0 -2832
- package/.code/agents/1398/exec-call_SUVq2ivmONQ5LMCmd7ngmOqr.txt +0 -2709
- package/.code/agents/1398/exec-call_SdNY4NOffdcC5pRYjVXHjPCK.txt +0 -2832
- package/.code/agents/1398/exec-call_qblJo9et1gsFFB63TtLOiji2.txt +0 -2832
- package/.code/agents/1398/exec-call_zaRrzlGz7GJcNzVfkAmML7Zg.txt +0 -2709
- package/.code/agents/171834fd-5905-42fc-bbcc-2c755145b0fc/status.txt +0 -1
- package/.code/agents/1724/exec-call_HvHQe0w5CCG3T7Q3ULT6MO3g.txt +0 -5217
- package/.code/agents/1724/exec-call_QwUNESVzfxxk78K1frh1Vahb.txt +0 -2594
- package/.code/agents/1724/exec-call_aJ1Xwz71XmIpD4SBxSHERzLe.txt +0 -2594
- package/.code/agents/1d7d7ab7-7473-4b69-8b97-6e914f56056a/result.txt +0 -231
- package/.code/agents/210/exec-call_0tQCsKNJ1WTuIchb8wlcFJpW.txt +0 -2590
- package/.code/agents/210/exec-call_8ZlY9cUc8Ft1twi4ch8UJ6IN.txt +0 -5195
- package/.code/agents/2188/exec-call_5HqayBxIteJtoI8oPTiLWgvJ.txt +0 -286
- package/.code/agents/2188/exec-call_XRbBKBq3adZe6dcppAvQtM7G.txt +0 -218
- package/.code/agents/2188/exec-call_ehA0SjpYtrUi6GJXmibLjp4i.txt +0 -180
- package/.code/agents/21902821-ecaf-4759-bb9d-222b90921af5/error.txt +0 -3
- package/.code/agents/232073be-aa0e-46da-b478-5b64dbf03cf5/status.txt +0 -1
- package/.code/agents/234ff534-2336-4771-a8d9-aa04421a63be/result.txt +0 -747
- package/.code/agents/253e2695-dc36-4022-b436-27655e0fc6c7/status.txt +0 -1
- package/.code/agents/2583/exec-call_M59I4eDjpjlBIWBiSxyS0YlJ.txt +0 -2594
- package/.code/agents/2583/exec-call_usLRGh7OhVHtsRBL4iUwRhjq.txt +0 -2594
- package/.code/agents/292aa3ff-dbab-470f-97c9-e7e8fd65e0db/result.txt +0 -144
- package/.code/agents/3134/exec-call_IgCAMGx19lWfuo8zfYIt5FFC.txt +0 -416
- package/.code/agents/3134/exec-call_IxvLR2Oo7kba2QTsI1gHVko8.txt +0 -2590
- package/.code/agents/3134/exec-call_jYvc8hksZChSiysbzKjl2ZbB.txt +0 -2590
- package/.code/agents/329/exec-call_4QdP3SfSO7HGPCwVcqZIth6s.txt +0 -2590
- package/.code/agents/472/exec-call_4AxzEEcWwkKhpqRB3bE8Ha4L.txt +0 -790
- package/.code/agents/472/exec-call_CB3LPYQA8QIZRi8I6kj4J17A.txt +0 -766
- package/.code/agents/472/exec-call_YeoUWvaFoktay2nqVUsa9KKX.txt +0 -790
- package/.code/agents/472/exec-call_jPWgKVquBBXTg0T3Lks5ZfkK.txt +0 -2594
- package/.code/agents/472/exec-call_qBkvunpGBDEHph2jPmTwtcsb.txt +0 -1000
- package/.code/agents/472/exec-call_v0ffRV1p0kTckBmJPzzHAEy0.txt +0 -3489
- package/.code/agents/472/exec-call_xAX5FXqWIlk02d9WubHbHWh8.txt +0 -766
- package/.code/agents/5346/exec-call_9q0muXUuLaucwEqI51Pt7idT.txt +0 -2594
- package/.code/agents/5346/exec-call_B2el3B79rVkq9LhWTI2VYlz7.txt +0 -2456
- package/.code/agents/5346/exec-call_BfX08f02qkZI9uJD5dvCvuoj.txt +0 -2594
- package/.code/agents/543328d0-61d6-4fd1-a723-bb168656e2e2/error.txt +0 -18
- package/.code/agents/5580c02c-1383-4d18-9cbd-cc8a06e3408d/result.txt +0 -48
- package/.code/agents/60ce1a22-5126-44b2-b977-1d5b56142a7b/status.txt +0 -1
- package/.code/agents/6215d9db-7fa9-4429-aeec-3835c3212291/error.txt +0 -1
- package/.code/agents/6743db55-30e5-4b4e-9366-a8214fc7f714/error.txt +0 -1
- package/.code/agents/6bf9591b-b9c9-422c-b0a5-e968c7d8422a/status.txt +0 -1
- package/.code/agents/7/exec-call_eww3GfdEiJZx61sJEQ9wNmt3.txt +0 -1271
- package/.code/agents/70/exec-call_owUtDMYiVgqDf8vsz1i32PFf.txt +0 -1570
- package/.code/agents/8/exec-call_UtrjAcLbhYLatxR4O97fZgnm.txt +0 -2590
- package/.code/agents/82490bc9-f34e-4b1b-8a8e-bccc2e6254f5/error.txt +0 -3
- package/.code/agents/841/exec-call_7nTNhSBCNjTDUIJv7py6CepO.txt +0 -3299
- package/.code/agents/841/exec-call_TLI0yUdUijuUAvI4o3DXEvHO.txt +0 -3299
- package/.code/agents/9/exec-call_XaABQT1hIlRpnKZ2uyBMWsTC.txt +0 -1882
- package/.code/agents/941/exec-call_GuGHRx7NNXWIDAnxUG2NEWPa.txt +0 -2594
- package/.code/agents/95d9fbab-19a2-48af-83f9-c792566a347f/error.txt +0 -1
- package/.code/agents/b0098cb8-cb32-4ada-9bc4-37c587518896/result.txt +0 -170
- package/.code/agents/b4fe59a4-81df-42e2-a112-0153e504faca/error.txt +0 -1
- package/.code/agents/bf4ce152-f623-49d7-aa52-c18631625c3c/error.txt +0 -3
- package/.code/agents/d7d1db75-d7eb-468e-adea-4ef4d916d187/status.txt +0 -1
- package/.code/agents/e2baa9c8-bac3-49e3-a39d-024333e6a990/status.txt +0 -1
- package/.code/agents/e350b8c3-8483-408c-b2bb-94515f492a11/error.txt +0 -3
- package/.code/agents/e63f9919-719f-4ad0-bccf-01b1a596e1e9/status.txt +0 -1
- package/.code/agents/e71695a8-3044-478d-8f12-ed13d02884c7/status.txt +0 -1
- package/.code/agents/f95b7464-3e25-4897-b153-c8dfd63fd605/error.txt +0 -5
- package/.code/agents/fa3c5ddf-cdf7-47a2-930a-b806c6363689/status.txt +0 -1
- package/.github/workflows/pr-description-check.yml +0 -88
- package/AGENTS.md +0 -36
- package/NUL +0 -1
- package/docs/README.md +0 -72
- package/docs/getting-started/CONFIGURATION.md +0 -175
- package/docs/getting-started/INSTALLATION.md +0 -333
- package/docs/getting-started/QUICKSTART.md +0 -282
- package/docs/guides/ARCHITECTURE.md +0 -533
- package/docs/guides/DEPLOYMENT.md +0 -189
- package/docs/guides/INTEGRATION_TESTING.md +0 -730
- package/docs/guides/TESTING.md +0 -591
- package/docs/reconciliation-flow.md +0 -83
- package/docs/reference/EXAMPLES.md +0 -946
- package/docs/reference/TOOLS.md +0 -348
- package/docs/reference/TROUBLESHOOTING.md +0 -481
- package/package.json.tmp +0 -105
- package/temp-recon.ts +0 -126
- package/test-exports/ynab_account_e9ddc2a6_minimal_1items_2025-11-19_09-04-53.json +0 -23
- package/test-exports/ynab_account_e9ddc2a6_minimal_1items_2025-11-19_10-37-42.json +0 -23
- package/test-exports/ynab_account_e9ddc2a6_minimal_4items_2025-11-19_09-02-09.json +0 -44
- package/test-exports/ynab_account_e9ddc2a6_minimal_6items_2025-11-19_10-37-52.json +0 -58
- package/test-exports/ynab_since_2025-10-16_account_53298e13_238items_2025-11-28_13-46-20.json +0 -3662
- package/test-exports/ynab_since_2025-11-01_account_4c18e9f0_minimal_14items_2025-11-16_10-07-10.json +0 -115
|
@@ -1,481 +0,0 @@
|
|
|
1
|
-
# YNAB MCP Server Troubleshooting Guide
|
|
2
|
-
|
|
3
|
-
Common issues, solutions, and debugging techniques for the YNAB MCP Server.
|
|
4
|
-
|
|
5
|
-
## Table of Contents
|
|
6
|
-
|
|
7
|
-
- [Common Issues](#common-issues)
|
|
8
|
-
- [Error Messages](#error-messages)
|
|
9
|
-
- [Connection Problems](#connection-problems)
|
|
10
|
-
- [Performance Issues](#performance-issues)
|
|
11
|
-
- [Data Issues](#data-issues)
|
|
12
|
-
- [Debug Techniques](#debug-techniques)
|
|
13
|
-
|
|
14
|
-
## Common Issues
|
|
15
|
-
|
|
16
|
-
### 1. Invalid or Expired YNAB Access Token
|
|
17
|
-
|
|
18
|
-
**Symptoms**: 401 authentication errors, "Invalid or expired token" messages
|
|
19
|
-
|
|
20
|
-
**Solutions**:
|
|
21
|
-
- Check if `YNAB_ACCESS_TOKEN` environment variable is set
|
|
22
|
-
- Verify token in YNAB Developer Settings
|
|
23
|
-
- Generate new token if expired
|
|
24
|
-
- Ensure token has no extra spaces or characters
|
|
25
|
-
- For Claude Desktop: Check extension settings for correct token configuration
|
|
26
|
-
|
|
27
|
-
**How to generate a new token**:
|
|
28
|
-
1. Log in to [YNAB Web App](https://app.youneedabudget.com)
|
|
29
|
-
2. Go to Account Settings → Developer Settings
|
|
30
|
-
3. Click "New Token"
|
|
31
|
-
4. Provide a descriptive name (e.g., "MCP Server")
|
|
32
|
-
5. Copy the generated token immediately (it's only shown once)
|
|
33
|
-
6. Add it to your `.env` file or Claude Desktop extension settings
|
|
34
|
-
|
|
35
|
-
### 2. Rate Limit Exceeded
|
|
36
|
-
|
|
37
|
-
**Symptoms**: 429 errors, especially during bulk operations
|
|
38
|
-
|
|
39
|
-
**Solutions**:
|
|
40
|
-
- Implement retry logic with exponential backoff
|
|
41
|
-
- Add delays between API calls
|
|
42
|
-
- Use batch processing with smaller batch sizes
|
|
43
|
-
- Leverage caching to reduce API calls
|
|
44
|
-
- The v0.8.x enhanced caching helps prevent rate limit issues
|
|
45
|
-
|
|
46
|
-
**Example retry logic**:
|
|
47
|
-
```javascript
|
|
48
|
-
async function withRetry(operation, maxRetries = 3, baseDelay = 1000) {
|
|
49
|
-
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
50
|
-
try {
|
|
51
|
-
return await operation();
|
|
52
|
-
} catch (error) {
|
|
53
|
-
if (attempt === maxRetries) throw error;
|
|
54
|
-
const delay = baseDelay * Math.pow(2, attempt - 1);
|
|
55
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### 3. Resource Not Found
|
|
62
|
-
|
|
63
|
-
**Symptoms**: 404 errors when accessing budgets, accounts, or transactions
|
|
64
|
-
|
|
65
|
-
**Solutions**:
|
|
66
|
-
- Verify IDs are correct and current
|
|
67
|
-
- Check if resources have been deleted in YNAB
|
|
68
|
-
- Use list operations to discover valid IDs
|
|
69
|
-
- Handle deleted/hidden items in your code
|
|
70
|
-
- Ensure you're using the correct budget context
|
|
71
|
-
|
|
72
|
-
**Example ID verification**:
|
|
73
|
-
```javascript
|
|
74
|
-
// Always verify IDs exist before operations
|
|
75
|
-
const accounts = await client.callTool('list_accounts', { budget_id: budgetId });
|
|
76
|
-
const accountIds = accounts.accounts.map(a => a.id);
|
|
77
|
-
if (!accountIds.includes(targetAccountId)) {
|
|
78
|
-
throw new Error(`Account ${targetAccountId} not found`);
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### 4. Incorrect Transaction Amounts
|
|
83
|
-
|
|
84
|
-
**Symptoms**: Transactions appear with wrong amounts (off by factor of 1000)
|
|
85
|
-
|
|
86
|
-
**Solutions**:
|
|
87
|
-
- Always convert dollars to milliunits before API calls (multiply by 1000)
|
|
88
|
-
- Use the `convert_amount` tool for accuracy
|
|
89
|
-
- Remember negative amounts for outflows
|
|
90
|
-
- Consider account types (credit cards need negative amounts for payments)
|
|
91
|
-
|
|
92
|
-
**Conversion reference**:
|
|
93
|
-
```
|
|
94
|
-
$25.50 → 25500 milliunits
|
|
95
|
-
-$100.00 → -100000 milliunits
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### 5. Date-Related Errors
|
|
99
|
-
|
|
100
|
-
**Symptoms**: Validation errors or unexpected behavior with dates
|
|
101
|
-
|
|
102
|
-
**Solutions**:
|
|
103
|
-
- Use ISO format (YYYY-MM-DD) for all dates
|
|
104
|
-
- Validate date format before API calls
|
|
105
|
-
- Consider timezone differences
|
|
106
|
-
- Use first day of month (YYYY-MM-01) for monthly operations
|
|
107
|
-
|
|
108
|
-
**Valid date formats**:
|
|
109
|
-
```javascript
|
|
110
|
-
// ✅ Correct
|
|
111
|
-
'2024-01-15'
|
|
112
|
-
'2024-12-31'
|
|
113
|
-
|
|
114
|
-
// ❌ Wrong
|
|
115
|
-
'01/15/2024' // US format
|
|
116
|
-
'15-01-2024' // European format
|
|
117
|
-
'2024-1-15' // Missing zero padding
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## Error Messages
|
|
121
|
-
|
|
122
|
-
### AUTHENTICATION_ERROR
|
|
123
|
-
|
|
124
|
-
**Meaning**: YNAB access token is invalid or expired
|
|
125
|
-
|
|
126
|
-
**Solution**: Generate a new token and update configuration
|
|
127
|
-
|
|
128
|
-
### AUTHORIZATION_ERROR
|
|
129
|
-
|
|
130
|
-
**Meaning**: Token doesn't have permission for requested operation
|
|
131
|
-
|
|
132
|
-
**Solution**: Verify token scope and permissions in YNAB settings
|
|
133
|
-
|
|
134
|
-
### VALIDATION_ERROR
|
|
135
|
-
|
|
136
|
-
**Meaning**: Input parameters are invalid or missing
|
|
137
|
-
|
|
138
|
-
**Solution**: Check parameter format, types, and required fields
|
|
139
|
-
|
|
140
|
-
### RATE_LIMIT_EXCEEDED
|
|
141
|
-
|
|
142
|
-
**Meaning**: Too many requests to YNAB API
|
|
143
|
-
|
|
144
|
-
**Solution**: Implement retry logic, add delays, use caching
|
|
145
|
-
|
|
146
|
-
### RESOURCE_NOT_FOUND
|
|
147
|
-
|
|
148
|
-
**Meaning**: Requested budget, account, or transaction doesn't exist
|
|
149
|
-
|
|
150
|
-
**Solution**: Verify IDs, check for deleted items, use list operations
|
|
151
|
-
|
|
152
|
-
### OPERATION_FAILED
|
|
153
|
-
|
|
154
|
-
**Meaning**: Generic operation failure
|
|
155
|
-
|
|
156
|
-
**Solution**: Check error details, verify data validity, check YNAB API status
|
|
157
|
-
|
|
158
|
-
## Connection Problems
|
|
159
|
-
|
|
160
|
-
### Server Won't Start
|
|
161
|
-
|
|
162
|
-
**Symptoms**: Server fails to start, immediate crash
|
|
163
|
-
|
|
164
|
-
**Diagnostics**:
|
|
165
|
-
```bash
|
|
166
|
-
# Check Node.js version (must be 18+)
|
|
167
|
-
node --version
|
|
168
|
-
|
|
169
|
-
# Verify build completed
|
|
170
|
-
ls dist/index.js
|
|
171
|
-
|
|
172
|
-
# Check for syntax errors
|
|
173
|
-
npm run type-check
|
|
174
|
-
|
|
175
|
-
# View detailed error logs
|
|
176
|
-
npm start 2>&1 | tee server.log
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
**Solutions**:
|
|
180
|
-
- Ensure Node.js 18+ is installed
|
|
181
|
-
- Run `npm install` to install dependencies
|
|
182
|
-
- Run `npm run build` to compile TypeScript
|
|
183
|
-
- Check environment variables are set correctly
|
|
184
|
-
|
|
185
|
-
### Claude Desktop Can't Connect
|
|
186
|
-
|
|
187
|
-
**Symptoms**: Server shows as disconnected in Claude Desktop
|
|
188
|
-
|
|
189
|
-
**Diagnostics**:
|
|
190
|
-
1. Check Claude Desktop logs for error messages
|
|
191
|
-
2. Verify MCP server configuration in settings
|
|
192
|
-
3. Confirm working directory path is correct
|
|
193
|
-
4. Check that `dist/index.js` exists
|
|
194
|
-
|
|
195
|
-
**Solutions**:
|
|
196
|
-
- Verify server configuration in Claude Desktop settings:
|
|
197
|
-
- Command: `node`
|
|
198
|
-
- Arguments: `["dist/index.js"]`
|
|
199
|
-
- Working Directory: correct absolute path
|
|
200
|
-
- Restart Claude Desktop completely
|
|
201
|
-
- Check file permissions on dist directory
|
|
202
|
-
- Verify YNAB_ACCESS_TOKEN is set in extension settings
|
|
203
|
-
|
|
204
|
-
### Intermittent Connection Drops
|
|
205
|
-
|
|
206
|
-
**Symptoms**: Server disconnects randomly, reconnects after delay
|
|
207
|
-
|
|
208
|
-
**Diagnostics**:
|
|
209
|
-
```javascript
|
|
210
|
-
// Check diagnostic info for system health
|
|
211
|
-
const result = await client.callTool('diagnostic_info');
|
|
212
|
-
const diagnostics = JSON.parse(result.content[0].text);
|
|
213
|
-
console.log('Server Health:', diagnostics.diagnostics.server_info);
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
**Solutions**:
|
|
217
|
-
- Check system resource usage (CPU, memory)
|
|
218
|
-
- Review cache configuration (may need to reduce cache size)
|
|
219
|
-
- Check for network connectivity issues
|
|
220
|
-
- Update to latest version
|
|
221
|
-
|
|
222
|
-
## Performance Issues
|
|
223
|
-
|
|
224
|
-
### Slow Response Times
|
|
225
|
-
|
|
226
|
-
**Symptoms**: Requests take longer than expected (>5 seconds)
|
|
227
|
-
|
|
228
|
-
**Diagnostics**:
|
|
229
|
-
```javascript
|
|
230
|
-
// Check cache performance
|
|
231
|
-
const result = await client.callTool('diagnostic_info');
|
|
232
|
-
const stats = JSON.parse(result.content[0].text).diagnostics.cache_stats;
|
|
233
|
-
console.log('Cache Hit Rate:', stats.hit_rate); // Should be >60%
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
**Solutions**:
|
|
237
|
-
- Verify cache warming is enabled (v0.8.x)
|
|
238
|
-
- Check cache hit rate (should be 60-80% after warmup)
|
|
239
|
-
- Increase cache TTL for static data
|
|
240
|
-
- Use cache warming by setting default budget
|
|
241
|
-
- Check network latency to YNAB API
|
|
242
|
-
|
|
243
|
-
**Expected performance**:
|
|
244
|
-
- Cached requests: <1 second
|
|
245
|
-
- Fresh API requests: 1-5 seconds
|
|
246
|
-
- Large data sets: 5-10 seconds
|
|
247
|
-
|
|
248
|
-
### High Memory Usage
|
|
249
|
-
|
|
250
|
-
**Symptoms**: Memory usage grows over time, eventual crashes
|
|
251
|
-
|
|
252
|
-
**Diagnostics**:
|
|
253
|
-
```javascript
|
|
254
|
-
// Check memory usage
|
|
255
|
-
const result = await client.callTool('diagnostic_info');
|
|
256
|
-
const memory = JSON.parse(result.content[0].text).diagnostics.server_info.memory_usage;
|
|
257
|
-
console.log('Memory:', memory);
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
**Solutions**:
|
|
261
|
-
- Check cache size limits (default: 1000 entries)
|
|
262
|
-
- Reduce `YNAB_MCP_CACHE_MAX_ENTRIES` if needed
|
|
263
|
-
- Verify LRU eviction is working
|
|
264
|
-
- Restart server periodically for long-running instances
|
|
265
|
-
- Check for memory leaks (monitor over time)
|
|
266
|
-
|
|
267
|
-
**Healthy memory usage**:
|
|
268
|
-
- Baseline: 50-100MB
|
|
269
|
-
- Under load: 100-200MB
|
|
270
|
-
- Max acceptable: <500MB
|
|
271
|
-
|
|
272
|
-
### Cache Not Working
|
|
273
|
-
|
|
274
|
-
**Symptoms**: Every request hits YNAB API, no performance improvement
|
|
275
|
-
|
|
276
|
-
**Diagnostics**:
|
|
277
|
-
```javascript
|
|
278
|
-
// Verify cache stats
|
|
279
|
-
const stats = cacheManager.getStats();
|
|
280
|
-
console.log('Cache Stats:', {
|
|
281
|
-
hitRate: stats.hit_rate,
|
|
282
|
-
totalHits: stats.total_hits,
|
|
283
|
-
totalMisses: stats.total_misses
|
|
284
|
-
});
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
**Solutions**:
|
|
288
|
-
- Verify cache is enabled (check environment variables)
|
|
289
|
-
- Ensure consistent cache keys are used
|
|
290
|
-
- Check TTL configuration isn't too short
|
|
291
|
-
- Verify cache warming triggered (use `set_default_budget`)
|
|
292
|
-
- Check cache isn't being cleared unintentionally
|
|
293
|
-
|
|
294
|
-
## Data Issues
|
|
295
|
-
|
|
296
|
-
### Missing Transactions
|
|
297
|
-
|
|
298
|
-
**Symptoms**: Transactions exist in YNAB but don't appear in results
|
|
299
|
-
|
|
300
|
-
**Solutions**:
|
|
301
|
-
- Check date filters (transactions may be outside range)
|
|
302
|
-
- Verify account/category filters
|
|
303
|
-
- Check for hidden/deleted transactions
|
|
304
|
-
- Clear cache and retry
|
|
305
|
-
- Verify budget context is correct
|
|
306
|
-
|
|
307
|
-
### Incorrect Balances
|
|
308
|
-
|
|
309
|
-
**Symptoms**: Account or category balances don't match YNAB
|
|
310
|
-
|
|
311
|
-
**Solutions**:
|
|
312
|
-
- Clear cache to get fresh data
|
|
313
|
-
- Verify all transactions are included
|
|
314
|
-
- Check for pending/uncleared transactions
|
|
315
|
-
- Ensure milliunits conversion is correct
|
|
316
|
-
- Verify reconciliation status
|
|
317
|
-
|
|
318
|
-
### Duplicate Transactions
|
|
319
|
-
|
|
320
|
-
**Symptoms**: Same transaction appears multiple times
|
|
321
|
-
|
|
322
|
-
**Solutions**:
|
|
323
|
-
- Use transaction IDs to deduplicate
|
|
324
|
-
- Check import detection settings
|
|
325
|
-
- Verify transaction matching logic
|
|
326
|
-
- Use the `compare_transactions` tool for CSV imports
|
|
327
|
-
- Review reconciliation recommendations
|
|
328
|
-
|
|
329
|
-
## Debug Techniques
|
|
330
|
-
|
|
331
|
-
### Enable Detailed Logging
|
|
332
|
-
|
|
333
|
-
```bash
|
|
334
|
-
# Set environment variable for debug logging
|
|
335
|
-
LOG_LEVEL=debug npm start
|
|
336
|
-
|
|
337
|
-
# Or in .env file
|
|
338
|
-
LOG_LEVEL=debug
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
### Use Diagnostic Info Tool
|
|
342
|
-
|
|
343
|
-
```javascript
|
|
344
|
-
// Get comprehensive server diagnostics
|
|
345
|
-
async function runDiagnostics() {
|
|
346
|
-
const result = await client.callTool('diagnostic_info');
|
|
347
|
-
const diagnostics = JSON.parse(result.content[0].text);
|
|
348
|
-
|
|
349
|
-
console.log('Server Info:', diagnostics.diagnostics.server_info);
|
|
350
|
-
console.log('Environment:', diagnostics.diagnostics.environment);
|
|
351
|
-
console.log('Cache Stats:', diagnostics.diagnostics.cache_stats);
|
|
352
|
-
console.log('Security Stats:', diagnostics.diagnostics.security_stats);
|
|
353
|
-
|
|
354
|
-
return diagnostics;
|
|
355
|
-
}
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
### Log API Calls
|
|
359
|
-
|
|
360
|
-
```javascript
|
|
361
|
-
class DebugLogger {
|
|
362
|
-
static logAPICall(toolName, params, result) {
|
|
363
|
-
console.log(`[API] ${toolName}:`, {
|
|
364
|
-
params: this.sanitizeParams(params),
|
|
365
|
-
resultSize: JSON.stringify(result).length,
|
|
366
|
-
timestamp: new Date().toISOString()
|
|
367
|
-
});
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
static sanitizeParams(params) {
|
|
371
|
-
// Remove sensitive data from logs
|
|
372
|
-
const sanitized = { ...params };
|
|
373
|
-
if (sanitized.budget_id) {
|
|
374
|
-
sanitized.budget_id = sanitized.budget_id.substring(0, 8) + '...';
|
|
375
|
-
}
|
|
376
|
-
return sanitized;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
static logError(error, context) {
|
|
380
|
-
console.error(`[ERROR] ${context}:`, {
|
|
381
|
-
message: error.message,
|
|
382
|
-
code: error.code,
|
|
383
|
-
timestamp: new Date().toISOString()
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
// Usage in your code
|
|
389
|
-
const result = await client.callTool('list_budgets', {});
|
|
390
|
-
DebugLogger.logAPICall('list_budgets', {}, result);
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
### Monitor Cache Performance
|
|
394
|
-
|
|
395
|
-
```javascript
|
|
396
|
-
// Periodically log cache performance
|
|
397
|
-
setInterval(async () => {
|
|
398
|
-
const result = await client.callTool('diagnostic_info');
|
|
399
|
-
const stats = JSON.parse(result.content[0].text).diagnostics.cache_stats;
|
|
400
|
-
|
|
401
|
-
console.log('Cache Performance:', {
|
|
402
|
-
hitRate: stats.hit_rate.toFixed(2),
|
|
403
|
-
entries: stats.total_entries,
|
|
404
|
-
hits: stats.total_hits,
|
|
405
|
-
misses: stats.total_misses
|
|
406
|
-
});
|
|
407
|
-
}, 60000); // Every minute
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
### Test Specific Scenarios
|
|
411
|
-
|
|
412
|
-
```javascript
|
|
413
|
-
// Create a test suite for specific issues
|
|
414
|
-
async function testScenario() {
|
|
415
|
-
console.log('Testing budget access...');
|
|
416
|
-
const budgets = await client.callTool('list_budgets', {});
|
|
417
|
-
console.log('✓ Budgets retrieved');
|
|
418
|
-
|
|
419
|
-
console.log('Testing account access...');
|
|
420
|
-
const accounts = await client.callTool('list_accounts', {
|
|
421
|
-
budget_id: budgets.budgets[0].id
|
|
422
|
-
});
|
|
423
|
-
console.log('✓ Accounts retrieved');
|
|
424
|
-
|
|
425
|
-
console.log('Testing transaction access...');
|
|
426
|
-
const transactions = await client.callTool('list_transactions', {
|
|
427
|
-
budget_id: budgets.budgets[0].id
|
|
428
|
-
});
|
|
429
|
-
console.log('✓ Transactions retrieved');
|
|
430
|
-
|
|
431
|
-
console.log('All tests passed!');
|
|
432
|
-
}
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
### Compare with YNAB Web App
|
|
436
|
-
|
|
437
|
-
When data discrepancies occur:
|
|
438
|
-
|
|
439
|
-
1. **Check same data in YNAB web app**
|
|
440
|
-
2. **Compare IDs, amounts, dates**
|
|
441
|
-
3. **Verify account/budget context matches**
|
|
442
|
-
4. **Check for timezone differences**
|
|
443
|
-
5. **Clear cache and retry**
|
|
444
|
-
|
|
445
|
-
### Check YNAB API Status
|
|
446
|
-
|
|
447
|
-
If experiencing widespread issues:
|
|
448
|
-
|
|
449
|
-
1. Visit [YNAB API Status](https://status.youneedabudget.com/)
|
|
450
|
-
2. Check for reported incidents
|
|
451
|
-
3. Verify API availability
|
|
452
|
-
4. Check for maintenance windows
|
|
453
|
-
|
|
454
|
-
## Getting Additional Help
|
|
455
|
-
|
|
456
|
-
If issues persist:
|
|
457
|
-
|
|
458
|
-
1. **Check Documentation**:
|
|
459
|
-
- [API Reference](API.md)
|
|
460
|
-
- [Development Guide](../guides/DEVELOPMENT.md)
|
|
461
|
-
- [Architecture Guide](../guides/ARCHITECTURE.md)
|
|
462
|
-
|
|
463
|
-
2. **Review Logs**:
|
|
464
|
-
- Claude Desktop logs
|
|
465
|
-
- Server console output
|
|
466
|
-
- Diagnostic info output
|
|
467
|
-
|
|
468
|
-
3. **Report Issues**:
|
|
469
|
-
- GitHub Issues for bug reports
|
|
470
|
-
- Include: version, error messages, steps to reproduce
|
|
471
|
-
- Provide diagnostic info (sanitize sensitive data)
|
|
472
|
-
|
|
473
|
-
4. **Community Resources**:
|
|
474
|
-
- YNAB API Documentation
|
|
475
|
-
- MCP Protocol Documentation
|
|
476
|
-
- Project GitHub Discussions
|
|
477
|
-
|
|
478
|
-
---
|
|
479
|
-
|
|
480
|
-
For development patterns and best practices, see [`../guides/DEVELOPMENT.md`](../guides/DEVELOPMENT.md).
|
|
481
|
-
For testing strategies, see [`../guides/TESTING.md`](../guides/TESTING.md).
|
package/package.json.tmp
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@dizzlkheinz/ynab-mcp-server",
|
|
3
|
-
"version": "0.12.0",
|
|
4
|
-
"description": "Model Context Protocol server for YNAB (You Need A Budget) integration",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"bin": {
|
|
8
|
-
"ynab-mcp-server": "bin/ynab-mcp-server.cjs"
|
|
9
|
-
},
|
|
10
|
-
"scripts": {
|
|
11
|
-
"prebuild": "npm run clean",
|
|
12
|
-
"build": "npm run build:prod",
|
|
13
|
-
"postbuild": "node scripts/run-generate-mcpb.js",
|
|
14
|
-
"build:dev": "npm run clean && tsc && npm run bundle",
|
|
15
|
-
"build:no-lint": "npm run clean && tsc && npm run bundle:prod",
|
|
16
|
-
"build:prod": "npm run lint:fix && npm run prebuild && tsc --project tsconfig.prod.json && npm run bundle:prod && npm run verify-build",
|
|
17
|
-
"clean": "rimraf dist",
|
|
18
|
-
"dev": "tsc --watch",
|
|
19
|
-
"start": "node -r dotenv/config dist/index.js",
|
|
20
|
-
"start:prod": "NODE_ENV=production node dist/index.js",
|
|
21
|
-
"start:mcp": "node dist/index.js",
|
|
22
|
-
"validate-env": "node scripts/validate-env.js",
|
|
23
|
-
"verify-build": "node scripts/verify-build.js",
|
|
24
|
-
"lint": "npm run lint:eslint && npm run format:check",
|
|
25
|
-
"lint:eslint": "eslint src --ext .ts",
|
|
26
|
-
"lint:fix": "eslint src --ext .ts --fix && prettier --write .",
|
|
27
|
-
"format": "prettier --write .",
|
|
28
|
-
"format:check": "prettier --check .",
|
|
29
|
-
"type-check": "tsc --noEmit",
|
|
30
|
-
"test": "vitest run --project unit && npm run filter-test-results",
|
|
31
|
-
"test:watch": "vitest",
|
|
32
|
-
"test:unit": "vitest run --project unit",
|
|
33
|
-
"test:integration": "npm run test:integration:core",
|
|
34
|
-
"test:integration:core": "vitest run --project integration:core",
|
|
35
|
-
"test:integration:domain": "vitest run --project integration:domain",
|
|
36
|
-
"test:integration:full": "node scripts/run-throttled-integration-tests.js",
|
|
37
|
-
"test:integration:budgets": "node scripts/run-domain-integration-tests.js budgets",
|
|
38
|
-
"test:integration:accounts": "node scripts/run-domain-integration-tests.js accounts",
|
|
39
|
-
"test:integration:transactions": "node scripts/run-domain-integration-tests.js transactions",
|
|
40
|
-
"test:integration:categories": "node scripts/run-domain-integration-tests.js categories",
|
|
41
|
-
"test:integration:payees": "node scripts/run-domain-integration-tests.js payees",
|
|
42
|
-
"test:integration:months": "node scripts/run-domain-integration-tests.js months",
|
|
43
|
-
"test:integration:delta": "node scripts/run-domain-integration-tests.js delta",
|
|
44
|
-
"test:integration:reconciliation": "node scripts/run-domain-integration-tests.js reconciliation",
|
|
45
|
-
"test:e2e": "vitest run --project e2e",
|
|
46
|
-
"test:coverage": "vitest run --coverage --project unit",
|
|
47
|
-
"test:performance": "vitest run src/__tests__/performance.test.ts",
|
|
48
|
-
"test:comprehensive": "tsx src/__tests__/testRunner.ts",
|
|
49
|
-
"test:all": "npm run test:unit && npm run test:integration:core && npm run test:e2e && npm run test:performance",
|
|
50
|
-
"filter-test-results": "node -e \"const fs = require('fs'); try { const results = JSON.parse(fs.readFileSync('test-results.json', 'utf-8')); results.testResults = results.testResults.filter(r => r.status === 'fail'); fs.writeFileSync('test-results.json', JSON.stringify(results, null, 2)); } catch (e) { console.error('Failed to filter test results:', e); process.exit(1); }\"",
|
|
51
|
-
"generate:mcpb": "node scripts/run-generate-mcpb.js",
|
|
52
|
-
"bundle": "node esbuild.config.mjs",
|
|
53
|
-
"bundle:prod": "node esbuild.config.mjs --production",
|
|
54
|
-
"package:mcpb": "npm run build:prod && npm run generate:mcpb",
|
|
55
|
-
"pr:description": "node scripts/create-pr-description.js",
|
|
56
|
-
"pr:create": "npm run pr:description && gh pr create --body-file .pr-description.md",
|
|
57
|
-
"prepare": "npm run build:prod",
|
|
58
|
-
"prepublishOnly": "npm run test:unit && npm run build:prod"
|
|
59
|
-
},
|
|
60
|
-
"keywords": [
|
|
61
|
-
"mcp",
|
|
62
|
-
"ynab",
|
|
63
|
-
"budget",
|
|
64
|
-
"finance"
|
|
65
|
-
],
|
|
66
|
-
"author": "",
|
|
67
|
-
"license": "AGPL-3.0",
|
|
68
|
-
"dependencies": {
|
|
69
|
-
"@modelcontextprotocol/sdk": "^1.22.0",
|
|
70
|
-
"csv-parse": "^6.1.0",
|
|
71
|
-
"d3-array": "^3.2.4",
|
|
72
|
-
"date-fns": "^4.1.0",
|
|
73
|
-
"dotenv": "^17.2.1",
|
|
74
|
-
"ynab": "^2.9.0",
|
|
75
|
-
"zod": "^4.1.11"
|
|
76
|
-
},
|
|
77
|
-
"devDependencies": {
|
|
78
|
-
"@eslint/js": "^9.35.0",
|
|
79
|
-
"@types/d3-array": "^3.2.1",
|
|
80
|
-
"@types/node": "^24.5.2",
|
|
81
|
-
"@vitest/coverage-v8": "^3.2.4",
|
|
82
|
-
"@vitest/ui": "^3.2.4",
|
|
83
|
-
"esbuild": "^0.25.10",
|
|
84
|
-
"eslint": "^9.35.0",
|
|
85
|
-
"eslint-config-prettier": "^10.1.8",
|
|
86
|
-
"prettier": "^3.3.3",
|
|
87
|
-
"rimraf": "^6.0.1",
|
|
88
|
-
"tsx": "^4.20.6",
|
|
89
|
-
"typescript": "^5.9.2",
|
|
90
|
-
"typescript-eslint": "^8.42.0",
|
|
91
|
-
"vitest": "^3.2.4"
|
|
92
|
-
},
|
|
93
|
-
"directories": {
|
|
94
|
-
"doc": "docs"
|
|
95
|
-
},
|
|
96
|
-
"repository": {
|
|
97
|
-
"type": "git",
|
|
98
|
-
"url": "git+https://github.com/dizzlkheinz/ynab-mcp-dxt.git"
|
|
99
|
-
},
|
|
100
|
-
"types": "./dist/index.d.ts",
|
|
101
|
-
"bugs": {
|
|
102
|
-
"url": "https://github.com/dizzlkheinz/ynab-mcp-dxt/issues"
|
|
103
|
-
},
|
|
104
|
-
"homepage": "https://github.com/dizzlkheinz/ynab-mcp-dxt#readme"
|
|
105
|
-
}
|
package/temp-recon.ts
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import 'dotenv/config';
|
|
2
|
-
import * as ynab from 'ynab';
|
|
3
|
-
import { executeReconciliation } from './src/tools/reconciliation/executor.js';
|
|
4
|
-
|
|
5
|
-
async function main() {
|
|
6
|
-
const token = process.env['YNAB_ACCESS_TOKEN'];
|
|
7
|
-
if (!token) throw new Error('No token');
|
|
8
|
-
const api = new ynab.API(token);
|
|
9
|
-
const budgets = await api.budgets.getBudgets();
|
|
10
|
-
const budgetId = budgets.data.budgets[0]?.id;
|
|
11
|
-
if (!budgetId) throw new Error('no budget');
|
|
12
|
-
const accounts = await api.accounts.getAccounts(budgetId);
|
|
13
|
-
const account = accounts.data.accounts.find((a) => !a.closed);
|
|
14
|
-
if (!account) throw new Error('no account');
|
|
15
|
-
const snapshot = {
|
|
16
|
-
balance: account.balance,
|
|
17
|
-
cleared_balance: account.cleared_balance ?? account.balance,
|
|
18
|
-
uncleared_balance: account.uncleared_balance ?? 0,
|
|
19
|
-
};
|
|
20
|
-
const count = 2;
|
|
21
|
-
const transactionAmount = 7;
|
|
22
|
-
const clearedDollars = snapshot.cleared_balance / 1000;
|
|
23
|
-
const totalDelta = transactionAmount * count;
|
|
24
|
-
const statementBalance = clearedDollars + totalDelta;
|
|
25
|
-
const today = new Date().toISOString().slice(0, 10);
|
|
26
|
-
const unmatchedBank = Array.from({ length: count }, (_, i) => {
|
|
27
|
-
const date = new Date(Date.now() + i * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
28
|
-
return {
|
|
29
|
-
id: `integration-bank-${i}`,
|
|
30
|
-
date,
|
|
31
|
-
amount: transactionAmount,
|
|
32
|
-
payee: `Integration Payee ${i}`,
|
|
33
|
-
memo: `Integration memo ${i}`,
|
|
34
|
-
original_csv_row: i + 1,
|
|
35
|
-
};
|
|
36
|
-
});
|
|
37
|
-
const analysis = {
|
|
38
|
-
success: true,
|
|
39
|
-
phase: 'analysis',
|
|
40
|
-
summary: {
|
|
41
|
-
statement_date_range: 'Integration test',
|
|
42
|
-
bank_transactions_count: count,
|
|
43
|
-
ynab_transactions_count: 0,
|
|
44
|
-
auto_matched: 0,
|
|
45
|
-
suggested_matches: 0,
|
|
46
|
-
unmatched_bank: count,
|
|
47
|
-
unmatched_ynab: 0,
|
|
48
|
-
current_cleared_balance: clearedDollars,
|
|
49
|
-
target_statement_balance: statementBalance,
|
|
50
|
-
discrepancy: totalDelta,
|
|
51
|
-
discrepancy_explanation: 'Synthetic integration delta',
|
|
52
|
-
},
|
|
53
|
-
auto_matches: [],
|
|
54
|
-
suggested_matches: [],
|
|
55
|
-
unmatched_bank: unmatchedBank,
|
|
56
|
-
unmatched_ynab: [],
|
|
57
|
-
balance_info: {
|
|
58
|
-
current_cleared: clearedDollars,
|
|
59
|
-
current_uncleared: snapshot.uncleared_balance / 1000,
|
|
60
|
-
current_total: snapshot.balance / 1000,
|
|
61
|
-
target_statement: statementBalance,
|
|
62
|
-
discrepancy: totalDelta,
|
|
63
|
-
on_track: false,
|
|
64
|
-
},
|
|
65
|
-
next_steps: [],
|
|
66
|
-
insights: [],
|
|
67
|
-
} as const;
|
|
68
|
-
|
|
69
|
-
const params = {
|
|
70
|
-
budget_id: budgetId,
|
|
71
|
-
account_id: account.id,
|
|
72
|
-
csv_data: 'Date,Description,Amount',
|
|
73
|
-
statement_balance: statementBalance,
|
|
74
|
-
statement_date: today,
|
|
75
|
-
date_tolerance_days: 1,
|
|
76
|
-
amount_tolerance_cents: 1,
|
|
77
|
-
auto_match_threshold: 90,
|
|
78
|
-
suggestion_threshold: 60,
|
|
79
|
-
auto_create_transactions: true,
|
|
80
|
-
auto_update_cleared_status: false,
|
|
81
|
-
auto_unclear_missing: false,
|
|
82
|
-
auto_adjust_dates: false,
|
|
83
|
-
dry_run: false,
|
|
84
|
-
require_exact_match: true,
|
|
85
|
-
confidence_threshold: 0.8,
|
|
86
|
-
max_resolution_attempts: 3,
|
|
87
|
-
include_structured_data: false,
|
|
88
|
-
} as const;
|
|
89
|
-
|
|
90
|
-
const result = await executeReconciliation({
|
|
91
|
-
ynabAPI: api,
|
|
92
|
-
analysis: analysis as any,
|
|
93
|
-
params: params as any,
|
|
94
|
-
budgetId,
|
|
95
|
-
accountId: account.id,
|
|
96
|
-
initialAccount: snapshot,
|
|
97
|
-
currencyCode: 'USD',
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
console.log(
|
|
101
|
-
JSON.stringify(
|
|
102
|
-
{
|
|
103
|
-
summary: result.summary,
|
|
104
|
-
bulk: result.bulk_operation_details,
|
|
105
|
-
actions: result.actions_taken.slice(0, 5),
|
|
106
|
-
},
|
|
107
|
-
null,
|
|
108
|
-
2,
|
|
109
|
-
),
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
const ids: string[] = [];
|
|
113
|
-
for (const action of result.actions_taken) {
|
|
114
|
-
if (action.type === 'create_transaction' && (action.transaction as any)?.id) {
|
|
115
|
-
ids.push((action.transaction as any).id);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
for (const id of ids) {
|
|
119
|
-
await api.transactions.deleteTransaction(budgetId, id);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
main().catch((err) => {
|
|
124
|
-
console.error(err);
|
|
125
|
-
process.exit(1);
|
|
126
|
-
});
|