@dizzlkheinz/ynab-mcpb 0.16.0 → 0.17.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.
Files changed (114) hide show
  1. package/.code/agents/0098661e-0fa3-4990-beb9-c0cbf3f123aa/status.txt +1 -0
  2. package/.code/agents/1324/exec-call_tIpx9uV1TpARbAMZonRQm8AO.txt +757 -0
  3. package/.code/agents/1572/exec-call_GjVFBFOWcY7lE0idc5nWlLNh.txt +781 -0
  4. package/.code/agents/1846/exec-call_1YNAVD18RjrMN7JnfkkQhUP3.txt +766 -0
  5. package/.code/agents/1846/exec-call_lh3lDzE4WJAh1lFiomiiZ73D.txt +766 -0
  6. package/.code/agents/2038/exec-call_DYwOukaYsL8VCONWmV2rUW5u.txt +766 -0
  7. package/.code/agents/2038/exec-call_c7fOQ7UrpVcTtvdfGBRM146V.txt +652 -0
  8. package/.code/agents/2038/exec-call_ySNyq9Mm55jWE480s54r5QcA.txt +766 -0
  9. package/.code/agents/2256/exec-call_AtPcRWPmFPMcmX6qOFm1fCEY.txt +766 -0
  10. package/.code/agents/2454/exec-call_aFJpupwjfZeOBm7ixI5Vc8z2.txt +766 -0
  11. package/.code/agents/2454/exec-call_wogZ4HfXTodTEXvdgXlVUBpv.txt +766 -0
  12. package/.code/agents/2e905864-aa07-4314-bcf9-c5b32277e4ac/result.txt +36 -0
  13. package/.code/agents/3073/exec-call_Peeagc9DxGYLgE6pNdMZhqIE.txt +766 -0
  14. package/.code/agents/3073/exec-call_d2YSE3hXF08KRSoUM3qd8Z3x.txt +766 -0
  15. package/.code/agents/335aa031-466d-4fb7-925f-3cd864e264d0/result.txt +191 -0
  16. package/.code/agents/3364/exec-call_NbhIrsM5HhyDZDmJZG5CuCYL.txt +766 -0
  17. package/.code/agents/3364/exec-call_cKtJg0NrXiwXEFwlsE3uPZRA.txt +766 -0
  18. package/.code/agents/36d98414-5cde-4d9d-9a67-a240a18c1f07/result.txt +189 -0
  19. package/.code/agents/4604e866-b7b8-44f5-992f-2f683b0a523b/status.txt +1 -0
  20. package/.code/agents/5f8dc01c-47b3-4163-b0b3-aa31be89fcdc/status.txt +1 -0
  21. package/.code/agents/7/exec-call_HltHpkDox0Zm1vGEjdksUgpE.txt +1120 -0
  22. package/.code/agents/7/exec-call_LCATrOPPAgbxW9Q1z0XaVi2E.txt +2646 -0
  23. package/.code/agents/7/exec-call_W8DeRfNG9hvbgVFvf0clBf6R.txt +2646 -0
  24. package/.code/agents/94a0ddf3-a304-4ec3-913e-3cceef509948/error.txt +1 -0
  25. package/.code/agents/e2c752b7-711d-423a-af57-f53c809deb84/result.txt +160 -0
  26. package/.code/agents/e6601719-c31f-4a0e-8c71-d70787d0ab71/status.txt +1 -0
  27. package/.code/agents/f250b7ed-5bd5-4036-aa8c-ce63caee7d61/result.txt +20 -0
  28. package/AGENTS.md +1 -36
  29. package/CLAUDE.md +131 -51
  30. package/NUL +0 -1
  31. package/README.md +27 -14
  32. package/dist/bundle/index.cjs +41 -41
  33. package/dist/server/YNABMCPServer.js +28 -381
  34. package/dist/server/config.d.ts +2 -0
  35. package/dist/server/config.js +1 -0
  36. package/dist/tools/accountTools.d.ts +2 -0
  37. package/dist/tools/accountTools.js +45 -0
  38. package/dist/tools/adapters.d.ts +12 -0
  39. package/dist/tools/adapters.js +25 -0
  40. package/dist/tools/budgetTools.d.ts +2 -0
  41. package/dist/tools/budgetTools.js +30 -0
  42. package/dist/tools/categoryTools.d.ts +2 -0
  43. package/dist/tools/categoryTools.js +45 -0
  44. package/dist/tools/monthTools.d.ts +2 -0
  45. package/dist/tools/monthTools.js +32 -0
  46. package/dist/tools/payeeTools.d.ts +2 -0
  47. package/dist/tools/payeeTools.js +32 -0
  48. package/dist/tools/reconciliation/index.d.ts +2 -0
  49. package/dist/tools/reconciliation/index.js +33 -0
  50. package/dist/tools/schemas/common.d.ts +3 -0
  51. package/dist/tools/schemas/common.js +3 -0
  52. package/dist/tools/schemas/outputs/comparisonOutputs.d.ts +1 -1
  53. package/dist/tools/transactionTools.d.ts +2 -0
  54. package/dist/tools/transactionTools.js +129 -0
  55. package/dist/tools/utilityTools.d.ts +3 -1
  56. package/dist/tools/utilityTools.js +32 -2
  57. package/dist/types/index.d.ts +1 -0
  58. package/dist/types/toolRegistration.d.ts +27 -0
  59. package/dist/types/toolRegistration.js +1 -0
  60. package/package.json +2 -2
  61. package/scripts/run-domain-integration-tests.js +4 -1
  62. package/src/__tests__/workflows.e2e.test.ts +1 -7
  63. package/src/server/YNABMCPServer.ts +33 -519
  64. package/src/server/__tests__/toolRegistration.test.ts +236 -0
  65. package/src/server/config.ts +1 -0
  66. package/src/tools/__tests__/adapters.test.ts +113 -0
  67. package/src/tools/__tests__/transactionTools.test.ts +90 -17
  68. package/src/tools/__tests__/utilityTools.test.ts +7 -7
  69. package/src/tools/accountTools.ts +53 -0
  70. package/src/tools/adapters.ts +74 -0
  71. package/src/tools/budgetTools.ts +37 -0
  72. package/src/tools/categoryTools.ts +53 -0
  73. package/src/tools/monthTools.ts +39 -0
  74. package/src/tools/payeeTools.ts +39 -0
  75. package/src/tools/reconciliation/index.ts +45 -0
  76. package/src/tools/schemas/common.ts +18 -0
  77. package/src/tools/transactionTools.ts +150 -0
  78. package/src/tools/utilityTools.ts +42 -2
  79. package/src/types/index.ts +3 -0
  80. package/src/types/toolRegistration.ts +88 -0
  81. package/.dxtignore +0 -57
  82. package/.github/workflows/pr-description-check.yml +0 -88
  83. package/CODEREVIEW_RESPONSE.md +0 -128
  84. package/SCHEMA_IMPROVEMENT_SUMMARY.md +0 -120
  85. package/TESTING_NOTES.md +0 -217
  86. package/accountactivity-merged.csv +0 -149
  87. package/bundle-analysis.html +0 -13110
  88. package/docs/README.md +0 -72
  89. package/docs/getting-started/CONFIGURATION.md +0 -175
  90. package/docs/getting-started/INSTALLATION.md +0 -333
  91. package/docs/getting-started/QUICKSTART.md +0 -282
  92. package/docs/guides/ARCHITECTURE.md +0 -533
  93. package/docs/guides/DEPLOYMENT.md +0 -189
  94. package/docs/guides/INTEGRATION_TESTING.md +0 -730
  95. package/docs/guides/TESTING.md +0 -591
  96. package/docs/plans/2025-11-20-reloadable-config-token-validation.md +0 -93
  97. package/docs/plans/2025-11-21-fix-transaction-cached-property.md +0 -362
  98. package/docs/plans/2025-11-21-reconciliation-error-handling.md +0 -90
  99. package/docs/plans/2025-11-21-v014-hardening.md +0 -153
  100. package/docs/plans/reconciliation-v2-redesign.md +0 -1571
  101. package/docs/reconciliation-flow.md +0 -83
  102. package/docs/reference/EXAMPLES.md +0 -946
  103. package/docs/reference/TOOLS.md +0 -348
  104. package/docs/reference/TROUBLESHOOTING.md +0 -481
  105. package/fix-types.sh +0 -17
  106. package/test-csv-sample.csv +0 -28
  107. package/test-exports/sample_bank_statement.csv +0 -7
  108. package/test-reconcile-autodetect.js +0 -40
  109. package/test-reconcile-tool.js +0 -152
  110. package/test-reconcile-with-csv.cjs +0 -89
  111. package/test-statement.csv +0 -8
  112. package/test_debug.js +0 -47
  113. package/test_mcp_tools.mjs +0 -75
  114. package/test_simple.mjs +0 -16
@@ -1,152 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Test script for reconcile_account_v2 tool
4
- *
5
- * Usage:
6
- * node test-reconcile-tool.js <csv-file> <budget-id> <account-id> <statement-balance>
7
- *
8
- * Example:
9
- * node test-reconcile-tool.js test.csv last-used checking -1500.00
10
- */
11
-
12
- import { API } from 'ynab';
13
- import { handleReconcileAccountV2 } from './dist/tools/reconciliation/index.js';
14
- import { readFileSync } from 'fs';
15
-
16
- async function testReconciliation() {
17
- // Parse arguments
18
- const csvFile = process.argv[2];
19
- const budgetId = process.argv[3] || 'last-used';
20
- const accountId = process.argv[4];
21
- const statementBalance = parseFloat(process.argv[5] || '0');
22
-
23
- if (!csvFile || !accountId) {
24
- console.error(
25
- 'Usage: node test-reconcile-tool.js <csv-file> <budget-id> <account-id> <statement-balance>',
26
- );
27
- console.error('Example: node test-reconcile-tool.js test.csv last-used checking -1500.00');
28
- process.exit(1);
29
- }
30
-
31
- // Check for YNAB token
32
- const token = process.env.YNAB_ACCESS_TOKEN;
33
- if (!token) {
34
- console.error('❌ YNAB_ACCESS_TOKEN environment variable not set');
35
- process.exit(1);
36
- }
37
-
38
- // Initialize YNAB API
39
- const ynabAPI = new API(token);
40
-
41
- console.log('🔍 Testing reconcile_account_v2...\n');
42
- console.log(`CSV File: ${csvFile}`);
43
- console.log(`Budget ID: ${budgetId}`);
44
- console.log(`Account ID: ${accountId}`);
45
- console.log(`Statement Balance: $${statementBalance}`);
46
- console.log('\n---\n');
47
-
48
- try {
49
- // Read CSV content
50
- const csvContent = readFileSync(csvFile, 'utf-8');
51
-
52
- // Call the tool
53
- const result = await handleReconcileAccountV2(ynabAPI, {
54
- budget_id: budgetId,
55
- account_id: accountId,
56
- csv_data: csvContent,
57
- statement_balance: statementBalance,
58
- date_tolerance_days: 2,
59
- amount_tolerance_cents: 1,
60
- auto_match_threshold: 90,
61
- suggestion_threshold: 60,
62
- });
63
-
64
- // Parse and display results
65
- const analysis = JSON.parse(result.content[0].text);
66
-
67
- console.log('✅ Analysis Complete!\n');
68
- console.log('📊 Summary:');
69
- console.log(` Bank Transactions: ${analysis.summary.bank_transactions_count}`);
70
- console.log(` YNAB Transactions: ${analysis.summary.ynab_transactions_count}`);
71
- console.log(` Auto-Matched: ${analysis.summary.auto_matched} (≥90% confidence)`);
72
- console.log(` Suggested Matches: ${analysis.summary.suggested_matches} (60-89% confidence)`);
73
- console.log(` Unmatched Bank: ${analysis.summary.unmatched_bank}`);
74
- console.log(` Unmatched YNAB: ${analysis.summary.unmatched_ynab}`);
75
- console.log('\n💰 Balance:');
76
- console.log(` Current Cleared: $${analysis.balance_info.current_cleared.toFixed(2)}`);
77
- console.log(` Target Statement: $${analysis.balance_info.target_statement.toFixed(2)}`);
78
- console.log(` Discrepancy: $${analysis.balance_info.discrepancy.toFixed(2)}`);
79
- console.log(` On Track: ${analysis.balance_info.on_track ? '✅' : '❌'}`);
80
-
81
- if (analysis.auto_matches.length > 0) {
82
- console.log('\n✨ Auto-Matched Transactions:');
83
- analysis.auto_matches.slice(0, 5).forEach((match, i) => {
84
- console.log(
85
- ` ${i + 1}. ${match.bank_transaction.payee} - $${match.bank_transaction.amount.toFixed(2)}`,
86
- );
87
- console.log(` → Matched to YNAB: ${match.ynab_transaction.payee_name}`);
88
- console.log(` Confidence: ${match.confidence_score}%`);
89
- });
90
- if (analysis.auto_matches.length > 5) {
91
- console.log(` ... and ${analysis.auto_matches.length - 5} more`);
92
- }
93
- }
94
-
95
- if (analysis.suggested_matches.length > 0) {
96
- console.log('\n💡 Suggested Matches (need review):');
97
- analysis.suggested_matches.slice(0, 3).forEach((match, i) => {
98
- console.log(
99
- ` ${i + 1}. ${match.bank_transaction.payee} - $${match.bank_transaction.amount.toFixed(2)}`,
100
- );
101
- if (match.candidates && match.candidates.length > 0) {
102
- console.log(
103
- ` Top candidate: ${match.candidates[0].ynab_transaction.payee_name} (${match.candidates[0].confidence}%)`,
104
- );
105
- }
106
- });
107
- if (analysis.suggested_matches.length > 3) {
108
- console.log(` ... and ${analysis.suggested_matches.length - 3} more`);
109
- }
110
- }
111
-
112
- if (analysis.unmatched_bank.length > 0) {
113
- console.log('\n❓ Unmatched Bank Transactions (not in YNAB):');
114
- analysis.unmatched_bank.slice(0, 3).forEach((txn, i) => {
115
- console.log(` ${i + 1}. ${txn.payee} - $${txn.amount.toFixed(2)} on ${txn.date}`);
116
- });
117
- if (analysis.unmatched_bank.length > 3) {
118
- console.log(` ... and ${analysis.unmatched_bank.length - 3} more`);
119
- }
120
- }
121
-
122
- if (analysis.insights && analysis.insights.length > 0) {
123
- console.log('\n💡 Insights:');
124
- analysis.insights.forEach((insight) => {
125
- const icon =
126
- insight.severity === 'critical' ? '🔴' : insight.severity === 'warning' ? '⚠️' : 'ℹ️';
127
- console.log(` ${icon} ${insight.title}`);
128
- console.log(` ${insight.description}`);
129
- });
130
- }
131
-
132
- console.log('\n📋 Next Steps:');
133
- analysis.next_steps.forEach((step, i) => {
134
- console.log(` ${i + 1}. ${step}`);
135
- });
136
-
137
- console.log('\n✅ Test complete!');
138
- console.log('\nFull results saved to: reconcile-analysis-result.json');
139
-
140
- // Save full results
141
- require('fs').writeFileSync(
142
- 'reconcile-analysis-result.json',
143
- JSON.stringify(analysis, null, 2),
144
- );
145
- } catch (error) {
146
- console.error('❌ Error:', error.message);
147
- console.error(error);
148
- process.exit(1);
149
- }
150
- }
151
-
152
- testReconciliation();
@@ -1,89 +0,0 @@
1
- /**
2
- * Test reconciliation with merged CSV data
3
- * Run this script using the YNAB MCP server in your other context
4
- */
5
-
6
- const fs = require('fs');
7
- const path = require('path');
8
-
9
- // Read the CSV files
10
- const downloadsPath = path.join(process.env.USERPROFILE, 'Downloads');
11
- const csv1Path = path.join(downloadsPath, 'accountactivity.csv');
12
- const csv2Path = path.join(downloadsPath, 'accountactivity1.csv');
13
- const csv3Path = path.join(downloadsPath, 'accountactivity2.csv');
14
-
15
- let csv1, csv2, csv3;
16
- try {
17
- csv1 = fs.readFileSync(csv1Path, 'utf-8');
18
- csv2 = fs.readFileSync(csv2Path, 'utf-8');
19
- csv3 = fs.readFileSync(csv3Path, 'utf-8');
20
- } catch (error) {
21
- console.error('Error reading CSV files:', error.message);
22
- process.exit(1);
23
- }
24
- // Merge CSVs (skip header from second and third files)
25
- const lines1 = csv1.split('\n');
26
- const lines2 = csv2.split('\n');
27
- const lines3 = csv3.split('\n');
28
-
29
- // Get header from first file
30
- const header = lines1[0];
31
-
32
- // Get data rows (skip header from all files, skip empty lines)
33
- const data1 = lines1.slice(1).filter(line => line.trim());
34
- const data2 = lines2.slice(1).filter(line => line.trim());
35
- const data3 = lines3.slice(1).filter(line => line.trim());
36
-
37
- // Combine and deduplicate
38
- const allData = [...data1, ...data2, ...data3];
39
- const uniqueData = [...new Set(allData)];
40
-
41
- // Reconstruct CSV
42
- const mergedCsv = [header, ...uniqueData].join('\n');
43
-
44
- const BUDGET_ID = process.env.YNAB_BUDGET_ID || '00dd8b56-cca8-4a1f-a3ea-02b13df8c2ff';
45
- const ACCOUNT_ID = process.env.YNAB_ACCOUNT_ID || '083f96c0-ed01-497d-93ab-f94c5ba89509';
46
- const STATEMENT_BALANCE = parseFloat(process.env.STATEMENT_BALANCE || '-1234.91');
47
- if (isNaN(STATEMENT_BALANCE)) {
48
- console.error('Invalid STATEMENT_BALANCE value');
49
- process.exit(1);
50
- }const STATEMENT_DATE = process.env.STATEMENT_DATE || '2025-01-11';
51
-
52
- const reconciliationCall = {
53
- tool: 'reconcile_account',
54
- params: {
55
- budget_id: BUDGET_ID,
56
- account_id: ACCOUNT_ID,
57
- statement_balance: STATEMENT_BALANCE,
58
- statement_date: STATEMENT_DATE,
59
- csv_data: mergedCsv,
60
- csv_format: {
61
- date_column: 'Transaction Date',
62
- description_column: 'Description',
63
- amount_column: 'Amount',
64
- date_format: 'YYYY-MM-DD',
65
- has_header: true,
66
- delimiter: ','
67
- },
68
- dry_run: false,
69
- auto_create_transactions: true,
70
- auto_update_cleared_status: true,
71
- auto_unclear_missing: true,
72
- include_structured_data: false
73
- }
74
- }; auto_update_cleared_status: true,
75
- auto_unclear_missing: true,
76
- include_structured_data: false
77
- }
78
- };
79
- const mergedCsvPath = path.join(downloadsPath, 'accountactivity-merged.csv');
80
- try {
81
- fs.writeFileSync(mergedCsvPath, mergedCsv);
82
- console.log(`\n\nMerged CSV saved to: ${mergedCsvPath}`);
83
- } catch (error) {
84
- console.error('Error saving merged CSV:', error.message);
85
- }
86
- // Also save the merged CSV for reference
87
- const mergedCsvPath = path.join(downloadsPath, 'accountactivity-merged.csv');
88
- fs.writeFileSync(mergedCsvPath, mergedCsv);
89
- console.log(`\n\nMerged CSV saved to: ${mergedCsvPath}`);
@@ -1,8 +0,0 @@
1
- Date,Description,Amount
2
- 2025-10-23,EvoCarShare,-2.24
3
- 2025-10-22,Amazon.ca*NU6MP0D91,-23.47
4
- 2025-10-22,Amazon.ca*NU1G88CB2,-9.49
5
- 2025-10-20,OXIO.CA,-54.88
6
- 2025-10-20,PAYMENT - THANK YOU,1097.27
7
- 2025-10-20,BURGER KING # 6271,-23.09
8
- 2025-10-30,EvoCarShare,-22.22
package/test_debug.js DELETED
@@ -1,47 +0,0 @@
1
- import { handleCreateTransaction } from './dist/tools/transactionTools.js';
2
- import * as ynab from 'ynab';
3
- import { vi } from 'vitest';
4
-
5
- const mockYnabAPI = {
6
- transactions: {
7
- createTransaction: async () => ({
8
- data: {
9
- transaction: {
10
- id: 'new-transaction-123',
11
- date: '2024-01-01',
12
- amount: -50000,
13
- memo: null,
14
- cleared: 'cleared',
15
- approved: true,
16
- flag_color: 'red',
17
- account_id: 'account-456',
18
- },
19
- },
20
- }),
21
- },
22
- accounts: {
23
- getAccountById: async () => ({
24
- data: {
25
- account: {
26
- id: 'account-456',
27
- balance: 100000,
28
- cleared_balance: 95000,
29
- },
30
- },
31
- }),
32
- },
33
- };
34
-
35
- const params = {
36
- budget_id: 'budget-123',
37
- account_id: 'account-456',
38
- amount: -50000,
39
- date: '2024-01-01',
40
- };
41
-
42
- try {
43
- const result = await handleCreateTransaction(mockYnabAPI, params);
44
- console.log('Result:', JSON.stringify(result, null, 2));
45
- } catch (error) {
46
- console.error('Error:', error);
47
- }
@@ -1,75 +0,0 @@
1
- import { spawn } from 'child_process';
2
-
3
- const server = spawn('node', ['dist/index.js'], {
4
- stdio: ['pipe', 'pipe', 'inherit'],
5
- env: process.env,
6
- });
7
-
8
- // Send initialize request
9
- const initRequest = {
10
- jsonrpc: '2.0',
11
- id: 1,
12
- method: 'initialize',
13
- params: {
14
- protocolVersion: '2024-11-05',
15
- capabilities: {},
16
- clientInfo: {
17
- name: 'test-client',
18
- version: '1.0.0',
19
- },
20
- },
21
- };
22
-
23
- // Send list tools request
24
- const listToolsRequest = {
25
- jsonrpc: '2.0',
26
- id: 2,
27
- method: 'tools/list',
28
- params: {},
29
- };
30
-
31
- let buffer = '';
32
- server.stdout.on('data', (data) => {
33
- buffer += data.toString();
34
- const lines = buffer.split('\n');
35
- buffer = lines.pop() || '';
36
-
37
- for (const line of lines) {
38
- if (line.trim()) {
39
- try {
40
- const response = JSON.parse(line);
41
- console.log('Response:', JSON.stringify(response, null, 2));
42
-
43
- if (response.id === 1) {
44
- // After init, send list tools
45
- server.stdin.write(JSON.stringify(listToolsRequest) + '\n');
46
- } else if (response.id === 2) {
47
- // Got tools list
48
- if (response.result && response.result.tools) {
49
- console.log(`\n✅ Found ${response.result.tools.length} tools`);
50
- response.result.tools.forEach((tool) => {
51
- const desc = tool.description.substring(0, 60);
52
- console.log(` - ${tool.name}: ${desc}...`);
53
- });
54
- } else {
55
- console.log('\n❌ No tools found in response');
56
- }
57
- server.kill();
58
- }
59
- } catch (e) {
60
- // Ignore parse errors for non-JSON output
61
- }
62
- }
63
- }
64
- });
65
-
66
- setTimeout(() => {
67
- console.log('\n⏱️ Timeout - sending requests');
68
- server.stdin.write(JSON.stringify(initRequest) + '\n');
69
- }, 1000);
70
-
71
- setTimeout(() => {
72
- console.log('❌ Test timed out');
73
- server.kill();
74
- process.exit(1);
75
- }, 10000);
package/test_simple.mjs DELETED
@@ -1,16 +0,0 @@
1
- // Simplified test to debug the issue
2
- const mockResponse = {
3
- data: {
4
- transaction: {
5
- id: 'new-transaction-123',
6
- date: '2024-01-01',
7
- amount: -50000,
8
- account_id: 'account-456',
9
- },
10
- server_knowledge: 1,
11
- },
12
- };
13
-
14
- console.log('Mock response:', JSON.stringify(mockResponse, null, 2));
15
- console.log('Transaction:', mockResponse.data.transaction);
16
- console.log('Server knowledge:', mockResponse.data.server_knowledge);