@dizzlkheinz/ynab-mcpb 0.16.1 → 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 (92) 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 +28 -43
  30. package/NUL +0 -1
  31. package/README.md +8 -10
  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 +124 -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__/utilityTools.test.ts +7 -7
  68. package/src/tools/accountTools.ts +53 -0
  69. package/src/tools/adapters.ts +74 -0
  70. package/src/tools/budgetTools.ts +37 -0
  71. package/src/tools/categoryTools.ts +53 -0
  72. package/src/tools/monthTools.ts +39 -0
  73. package/src/tools/payeeTools.ts +39 -0
  74. package/src/tools/reconciliation/index.ts +45 -0
  75. package/src/tools/schemas/common.ts +18 -0
  76. package/src/tools/transactionTools.ts +140 -0
  77. package/src/tools/utilityTools.ts +42 -2
  78. package/src/types/index.ts +3 -0
  79. package/src/types/toolRegistration.ts +88 -0
  80. package/.github/workflows/pr-description-check.yml +0 -88
  81. package/docs/README.md +0 -72
  82. package/docs/getting-started/CONFIGURATION.md +0 -175
  83. package/docs/getting-started/INSTALLATION.md +0 -333
  84. package/docs/getting-started/QUICKSTART.md +0 -282
  85. package/docs/guides/ARCHITECTURE.md +0 -533
  86. package/docs/guides/DEPLOYMENT.md +0 -189
  87. package/docs/guides/INTEGRATION_TESTING.md +0 -730
  88. package/docs/guides/TESTING.md +0 -591
  89. package/docs/reconciliation-flow.md +0 -83
  90. package/docs/reference/EXAMPLES.md +0 -946
  91. package/docs/reference/TOOLS.md +0 -348
  92. package/docs/reference/TROUBLESHOOTING.md +0 -481
@@ -1,533 +0,0 @@
1
- # YNAB MCP Server Architecture
2
-
3
- This guide explains the modular architecture, core components, and architectural patterns.
4
-
5
- ## Table of Contents
6
-
7
- - [Modular Architecture](#modular-architecture)
8
- - [Core Components](#core-components)
9
- - [Dependency Injection Pattern](#dependency-injection-pattern)
10
- - [Developing Tools](#developing-tools)
11
- - [Cache Management](#cache-management)
12
- - [Service Module Patterns](#service-module-patterns)
13
-
14
- ## Modular Architecture
15
-
16
- The server uses a modular architecture that improves maintainability, testability, and performance.
17
-
18
- ### Architecture Overview
19
-
20
- The architecture consists of several key components working together:
21
-
22
- ```
23
- ┌─────────────────────────────────────────────────────────────┐
24
- │ YNABMCPServer │
25
- │ (Main Orchestrator) │
26
- ├─────────────────────────────────────────────────────────────┤
27
- │ ┌──────────────┐ ┌───────────────┐ ┌─────────────────┐ │
28
- │ │ Tool Registry│ │ Cache Manager │ │ Budget Resolver │ │
29
- │ │ │ │ │ │ │ │
30
- │ └──────────────┘ └───────────────┘ └─────────────────┘ │
31
- │ ┌──────────────┐ ┌───────────────┐ ┌─────────────────┐ │
32
- │ │Config Module │ │Resource Mgr │ │ Prompt Manager │ │
33
- │ │ │ │ │ │ │ │
34
- │ └──────────────┘ └───────────────┘ └─────────────────┘ │
35
- │ ┌──────────────┐ ┌───────────────┐ ┌─────────────────┐ │
36
- │ │Error Handler │ │Security Mdlwr │ │Diagnostic Mgr │ │
37
- │ │ │ │ │ │ │ │
38
- │ └──────────────┘ └───────────────┘ └─────────────────┘ │
39
- └─────────────────────────────────────────────────────────────┘
40
- ```
41
-
42
- ## Core Components
43
-
44
- ### Tool Registry
45
- Centralized management of all MCP tools with consistent validation, security, and error handling.
46
-
47
- **Key Benefits:**
48
- - Uniform tool registration and validation
49
- - Consistent error messages across all tools
50
- - Centralized security checks
51
- - Automatic JSON schema generation
52
-
53
- **Example Tool Definition:**
54
- ```typescript
55
- registry.register({
56
- name: 'my_custom_tool',
57
- description: 'A custom tool for specific operations',
58
- inputSchema: MyToolSchema,
59
- handler: adapt(handleMyTool),
60
- defaultArgumentResolver: resolveBudgetId(),
61
- security: { requiresValidation: true }
62
- });
63
- ```
64
-
65
- ### Enhanced Cache Manager
66
- Advanced caching system with observability, LRU eviction, and performance optimization.
67
-
68
- **Key Features:**
69
- - Hit/miss tracking with detailed metrics
70
- - LRU eviction with configurable limits
71
- - Stale-while-revalidate for improved performance
72
- - Concurrent fetch deduplication
73
- - Cache warming for faster initial loads
74
-
75
- ### Budget Resolver
76
- Standardized budget ID resolution with consistent error handling across all tools.
77
-
78
- **Benefits:**
79
- - Uniform budget validation
80
- - Clear, actionable error messages
81
- - Automatic default budget injection
82
- - Consistent user experience
83
-
84
- ### Service Modules
85
- Focused modules handling specific server concerns:
86
-
87
- - **Config Module**: Environment validation and configuration management
88
- - **Resource Manager**: MCP resource definitions and handlers
89
- - **Prompt Manager**: MCP prompt definitions and handlers
90
- - **Diagnostic Manager**: System diagnostics and health monitoring
91
-
92
- ## Dependency Injection Pattern
93
-
94
- The architecture uses explicit dependency injection for better testability and maintainability:
95
-
96
- ```typescript
97
- // Explicit dependency injection pattern
98
- class MyService {
99
- constructor(
100
- private cacheManager: CacheManager,
101
- private errorHandler: ErrorHandler,
102
- private budgetResolver: BudgetResolver
103
- ) {}
104
-
105
- async performOperation(budgetId: string) {
106
- const resolved = this.budgetResolver.resolveBudgetId(budgetId, defaultBudgetId);
107
- if (typeof resolved !== 'string') {
108
- return resolved; // Error response
109
- }
110
-
111
- return this.cacheManager.wrap(`operation_${resolved}`, {
112
- ttl: CACHE_TTLS.MEDIUM,
113
- loader: () => this.executeOperation(resolved)
114
- });
115
- }
116
- }
117
-
118
- // Service instantiation with dependencies
119
- const myService = new MyService(cacheManager, errorHandler, budgetResolver);
120
- ```
121
-
122
- ## Developing Tools
123
-
124
- ### Tool Development Patterns
125
-
126
- Creating new tools follows the Tool Registry pattern for consistency and maintainability.
127
-
128
- #### 1. Define Tool Schema
129
-
130
- ```typescript
131
- import { z } from 'zod';
132
-
133
- export const MyToolSchema = z.object({
134
- budget_id: z.string().optional(),
135
- custom_parameter: z.string(),
136
- optional_parameter: z.number().optional().default(100)
137
- }).describe('Schema for my custom tool');
138
-
139
- export type MyToolRequest = z.infer<typeof MyToolSchema>;
140
- ```
141
-
142
- #### 2. Implement Tool Handler
143
-
144
- ```typescript
145
- import { adapt } from '../server/toolRegistry.js';
146
- import { BudgetResolver } from '../server/budgetResolver.js';
147
- import { cacheManager, CACHE_TTLS } from '../server/cacheManager.js';
148
-
149
- export async function handleMyTool(
150
- params: MyToolRequest
151
- ): Promise<any> {
152
- // Budget resolution is handled automatically by defaultArgumentResolver
153
- const { budget_id, custom_parameter, optional_parameter } = params;
154
-
155
- // Use enhanced caching
156
- return cacheManager.wrap(`my_tool_${budget_id}_${custom_parameter}`, {
157
- ttl: CACHE_TTLS.SHORT,
158
- staleWhileRevalidate: 60000,
159
- loader: async () => {
160
- // Implement your tool logic here
161
- const result = await performMyOperation(budget_id, custom_parameter);
162
- return {
163
- success: true,
164
- data: {
165
- custom_result: result,
166
- parameter_used: custom_parameter,
167
- optional_value: optional_parameter
168
- }
169
- };
170
- }
171
- });
172
- }
173
- ```
174
-
175
- #### 3. Register Tool with Registry
176
-
177
- ```typescript
178
- // In YNABMCPServer.ts or a tool registration module
179
- import { resolveBudgetId } from './budgetResolver.js';
180
-
181
- registry.register({
182
- name: 'my_custom_tool',
183
- description: 'Performs custom operation with enhanced caching and error handling',
184
- inputSchema: MyToolSchema,
185
- handler: adapt(handleMyTool),
186
- defaultArgumentResolver: resolveBudgetId(),
187
- cacheConfig: {
188
- enabled: true,
189
- ttl: CACHE_TTLS.SHORT
190
- }
191
- });
192
- ```
193
-
194
- ### Using Default Argument Resolution
195
-
196
- The Tool Registry provides automatic budget ID resolution:
197
-
198
- ```typescript
199
- // Budget ID is automatically resolved when not provided
200
- export const resolveBudgetId = (): DefaultArgumentResolver =>
201
- async (args, context) => {
202
- if (!args.budget_id) {
203
- const defaultBudget = context.getDefaultBudget();
204
- if (!defaultBudget) {
205
- return {
206
- isError: true,
207
- content: [{
208
- type: 'text',
209
- text: JSON.stringify({
210
- success: false,
211
- error: {
212
- code: 'VALIDATION_ERROR',
213
- message: 'No default budget set. Use set_default_budget first or provide budget_id parameter.'
214
- }
215
- })
216
- }]
217
- };
218
- }
219
- args.budget_id = defaultBudget;
220
- }
221
- return null; // No error, continue with resolved args
222
- };
223
- ```
224
-
225
- ### Error Handling Best Practices
226
-
227
- Use the centralized error handling system for consistent responses:
228
-
229
- ```typescript
230
- import { ErrorHandler } from '../server/errorHandler.js';
231
-
232
- export async function handleMyTool(params: MyToolRequest): Promise<any> {
233
- try {
234
- // Tool implementation
235
- const result = await performOperation(params);
236
- return result;
237
- } catch (error) {
238
- // Use centralized error handling
239
- return ErrorHandler.createErrorResponse(
240
- 'OPERATION_FAILED',
241
- `Custom tool operation failed: ${error.message}`,
242
- { operation: 'my_custom_tool', params }
243
- );
244
- }
245
- }
246
- ```
247
-
248
- ## Cache Management
249
-
250
- ### Understanding the Enhanced Cache System
251
-
252
- The server includes a sophisticated caching system designed for performance and observability.
253
-
254
- #### Cache Configuration
255
-
256
- ```typescript
257
- // Environment variables for cache tuning
258
- YNAB_MCP_CACHE_MAX_ENTRIES=1000 // Maximum cache entries
259
- YNAB_MCP_CACHE_DEFAULT_TTL_MS=1800000 // Default TTL (30 minutes)
260
- YNAB_MCP_CACHE_STALE_MS=120000 // Stale-while-revalidate window
261
- ```
262
-
263
- #### Using Cache.wrap() Method
264
-
265
- The primary interface for caching is the `wrap()` method:
266
-
267
- ```typescript
268
- import { cacheManager, CACHE_TTLS } from '../server/cacheManager.js';
269
-
270
- // Basic usage
271
- const result = await cacheManager.wrap('my_cache_key', {
272
- ttl: CACHE_TTLS.ACCOUNTS,
273
- loader: async () => {
274
- // Expensive operation (API call, computation, etc.)
275
- return await ynabAPI.accounts.getAccounts(budgetId);
276
- }
277
- });
278
-
279
- // Advanced usage with stale-while-revalidate
280
- const result = await cacheManager.wrap('complex_operation', {
281
- ttl: CACHE_TTLS.LONG,
282
- staleWhileRevalidate: 300000, // 5 minutes
283
- loader: async () => {
284
- return await performComplexAnalysis(budgetId);
285
- }
286
- });
287
- ```
288
-
289
- #### Cache Strategy Guidelines
290
-
291
- **Long TTL (1 hour+):** Budget data, categories, accounts
292
- ```typescript
293
- // Budget data changes infrequently
294
- const budgets = await cacheManager.wrap(`budgets_${userId}`, {
295
- ttl: CACHE_TTLS.BUDGETS, // 1 hour
296
- loader: () => ynabAPI.budgets.getBudgets()
297
- });
298
- ```
299
-
300
- **Medium TTL (30 minutes):** Account balances, category balances
301
- ```typescript
302
- // Account data changes moderately
303
- const accounts = await cacheManager.wrap(`accounts_${budgetId}`, {
304
- ttl: CACHE_TTLS.ACCOUNTS, // 30 minutes
305
- staleWhileRevalidate: 120000, // 2 minutes
306
- loader: () => ynabAPI.accounts.getAccounts(budgetId)
307
- });
308
- ```
309
-
310
- **Short TTL (5-15 minutes):** Recent transactions, monthly data
311
- ```typescript
312
- // Recent transactions change frequently
313
- const recentTransactions = await cacheManager.wrap(`recent_txns_${budgetId}`, {
314
- ttl: CACHE_TTLS.SHORT, // 5 minutes
315
- loader: () => ynabAPI.transactions.getTransactions(budgetId, { since_date })
316
- });
317
- ```
318
-
319
- **No Caching:** User-specific filtered transactions, write operations
320
- ```typescript
321
- // Don't cache filtered or user-specific data
322
- const filteredTransactions = await ynabAPI.transactions.getTransactions(budgetId, {
323
- account_id: accountId,
324
- category_id: categoryId,
325
- since_date: userSpecificDate
326
- });
327
- ```
328
-
329
- #### Cache Invalidation Patterns
330
-
331
- ```typescript
332
- // Invalidate related caches after write operations
333
- export async function handleCreateAccount(params: CreateAccountRequest) {
334
- const result = await ynabAPI.accounts.createAccount(params);
335
-
336
- // Invalidate related caches
337
- cacheManager.delete(`accounts_${params.budget_id}`);
338
- cacheManager.delete(`budget_${params.budget_id}`);
339
-
340
- return result;
341
- }
342
-
343
- // Pattern-based invalidation
344
- export function invalidateAccountCaches(budgetId: string) {
345
- const keysToInvalidate = [
346
- `accounts_${budgetId}`,
347
- `budget_${budgetId}`
348
- ];
349
-
350
- keysToInvalidate.forEach(key => cacheManager.delete(key));
351
- }
352
- ```
353
-
354
- #### Cache Observability
355
-
356
- Monitor cache performance with built-in metrics:
357
-
358
- ```typescript
359
- // Get cache statistics
360
- const stats = cacheManager.getStats();
361
- console.log('Cache Performance:', {
362
- hitRate: stats.hit_rate,
363
- totalHits: stats.total_hits,
364
- totalMisses: stats.total_misses,
365
- totalEntries: stats.total_entries,
366
- evictions: stats.evictions
367
- });
368
-
369
- // Example output:
370
- // Cache Performance: {
371
- // hitRate: 0.75, // 75% hit rate
372
- // totalHits: 150,
373
- // totalMisses: 50,
374
- // totalEntries: 45,
375
- // evictions: 5
376
- // }
377
- ```
378
-
379
- ### Cache Warming Strategies
380
-
381
- Implement proactive cache warming for better user experience:
382
-
383
- ```typescript
384
- // Cache warming after budget selection
385
- export async function warmBudgetCache(budgetId: string) {
386
- // Fire and forget - don't block user operations
387
- const warmingPromises = [
388
- cacheManager.wrap(`accounts_${budgetId}`, {
389
- ttl: CACHE_TTLS.ACCOUNTS,
390
- loader: () => ynabAPI.accounts.getAccounts(budgetId)
391
- }),
392
- cacheManager.wrap(`categories_${budgetId}`, {
393
- ttl: CACHE_TTLS.CATEGORIES,
394
- loader: () => ynabAPI.categories.getCategories(budgetId)
395
- }),
396
- cacheManager.wrap(`payees_${budgetId}`, {
397
- ttl: CACHE_TTLS.PAYEES,
398
- loader: () => ynabAPI.payees.getPayees(budgetId)
399
- })
400
- ];
401
-
402
- // Don't await - let these run in background
403
- Promise.all(warmingPromises).catch(error => {
404
- console.warn('Cache warming failed:', error.message);
405
- });
406
- }
407
-
408
- // Trigger cache warming
409
- export async function handleSetDefaultBudget(params: SetDefaultBudgetRequest) {
410
- const result = await setDefaultBudget(params.budget_id);
411
-
412
- // Warm cache for better subsequent performance
413
- if (result.success) {
414
- warmBudgetCache(params.budget_id);
415
- }
416
-
417
- return result;
418
- }
419
- ```
420
-
421
- ## Service Module Patterns
422
-
423
- ### Working with Service Modules
424
-
425
- The server decomposes functionality into focused service modules.
426
-
427
- #### Resource Manager
428
-
429
- Handle MCP resources consistently:
430
-
431
- ```typescript
432
- // Custom resource definition
433
- class MyResourceManager extends ResourceManager {
434
- getResources() {
435
- return [
436
- ...super.getResources(),
437
- {
438
- uri: 'my-app://custom-resource',
439
- name: 'Custom Resource',
440
- description: 'Application-specific resource',
441
- mimeType: 'application/json'
442
- }
443
- ];
444
- }
445
-
446
- async readResource(uri: string) {
447
- if (uri === 'my-app://custom-resource') {
448
- return {
449
- contents: [{
450
- type: 'text',
451
- text: JSON.stringify({
452
- custom_data: 'value',
453
- timestamp: new Date().toISOString()
454
- })
455
- }]
456
- };
457
- }
458
- return super.readResource(uri);
459
- }
460
- }
461
- ```
462
-
463
- #### Prompt Manager
464
-
465
- Create dynamic prompts with context:
466
-
467
- ```typescript
468
- // Custom prompt with dynamic context
469
- class MyPromptManager extends PromptManager {
470
- getPrompts() {
471
- return [
472
- ...super.getPrompts(),
473
- {
474
- name: 'analyze_spending',
475
- description: 'Analyze spending patterns with budget context'
476
- }
477
- ];
478
- }
479
-
480
- async getPrompt(name: string, args: any) {
481
- if (name === 'analyze_spending') {
482
- const budgetContext = await this.getBudgetContext(args.budget_id);
483
- return {
484
- messages: [{
485
- role: 'user',
486
- content: {
487
- type: 'text',
488
- text: `Analyze spending patterns for budget: ${budgetContext.name}.
489
- Current month: ${budgetContext.current_month}.
490
- Focus on categories with significant changes.`
491
- }
492
- }]
493
- };
494
- }
495
- return super.getPrompt(name, args);
496
- }
497
- }
498
- ```
499
-
500
- #### Diagnostic Manager
501
-
502
- Extend diagnostics for custom monitoring:
503
-
504
- ```typescript
505
- class MyDiagnosticManager extends DiagnosticManager {
506
- async getSystemDiagnostics() {
507
- const baseDiagnostics = await super.getSystemDiagnostics();
508
-
509
- return {
510
- ...baseDiagnostics,
511
- custom_metrics: {
512
- active_integrations: this.getActiveIntegrations(),
513
- last_sync_time: this.getLastSyncTime(),
514
- error_rate: this.calculateErrorRate()
515
- }
516
- };
517
- }
518
-
519
- private getActiveIntegrations() {
520
- // Custom integration monitoring
521
- return {
522
- external_apis: ['ynab', 'my_custom_api'],
523
- webhooks: this.activeWebhooks.length,
524
- background_jobs: this.backgroundJobs.size
525
- };
526
- }
527
- }
528
- ```
529
-
530
- ---
531
-
532
- For practical development patterns and examples, see [`DEVELOPMENT.md`](DEVELOPMENT.md).
533
- For troubleshooting guidance, see [`../reference/TROUBLESHOOTING.md`](../reference/TROUBLESHOOTING.md).
@@ -1,189 +0,0 @@
1
- # YNAB MCP Server Deployment Guide
2
-
3
- This guide provides instructions for deploying the YNAB MCP Server with security best practices.
4
-
5
- ## Prerequisites
6
-
7
- ### System Requirements
8
-
9
- - **Node.js**: Version 18.0.0 or higher
10
- - **npm**: Version 8.0.0 or higher
11
- - **Operating System**: Linux, macOS, or Windows
12
- - **Memory**: Minimum 512MB RAM
13
- - **Storage**: Minimum 100MB free space
14
-
15
- ### YNAB Requirements
16
-
17
- - Active YNAB subscription
18
- - YNAB Personal Access Token
19
-
20
- ## Environment Setup
21
-
22
- ### 1. YNAB Personal Access Token
23
-
24
- 1. Log in to your YNAB account at [app.youneedabudget.com](https://app.youneedabudget.com)
25
- 2. Go to Account Settings → Developer Settings
26
- 3. Click "New Token"
27
- 4. Enter a descriptive name (e.g., "MCP Server")
28
- 5. Copy the generated token immediately (it won't be shown again)
29
-
30
- ### 2. Environment Variables
31
-
32
- Create a `.env` file in your project root:
33
-
34
- ```bash
35
- # Required
36
- YNAB_ACCESS_TOKEN=your_personal_access_token_here
37
-
38
- # Optional
39
- NODE_ENV=production
40
- LOG_LEVEL=info
41
- ```
42
-
43
- ## Build Process
44
-
45
- ### Production Build
46
-
47
- ```bash
48
- # Install dependencies
49
- npm install
50
-
51
- # Validate environment
52
- npm run validate-env
53
-
54
- # Run tests
55
- npm run test:all
56
-
57
- # Build for production
58
- npm run build:prod
59
- ```
60
-
61
- ## Deployment Options
62
-
63
- ### Option 1: Local Development
64
-
65
- ```bash
66
- # Start the server
67
- npm start
68
-
69
- # Or with environment variables inline
70
- YNAB_ACCESS_TOKEN=your_token npm start
71
- ```
72
-
73
- ### Option 2: Docker Deployment
74
-
75
- 1. Create `Dockerfile`:
76
- ```dockerfile
77
- FROM node:18-alpine
78
-
79
- WORKDIR /usr/src/app
80
-
81
- COPY package*.json ./
82
- RUN npm ci --only=production
83
-
84
- COPY dist/ ./dist/
85
-
86
- RUN addgroup -g 1001 -S nodejs
87
- RUN adduser -S nodejs -u 1001
88
- RUN chown -R nodejs:nodejs /usr/src/app
89
- USER nodejs
90
-
91
- CMD ["node", "dist/index.js"]
92
- ```
93
-
94
- 2. Build and run:
95
- ```bash
96
- docker build -t ynab-mcp-server .
97
- docker run -d \
98
- --name ynab-mcp-server \
99
- -e YNAB_ACCESS_TOKEN=your_token \
100
- -e NODE_ENV=production \
101
- --restart unless-stopped \
102
- ynab-mcp-server
103
- ```
104
-
105
- ### Option 3: Claude Desktop Integration
106
-
107
- 1. Build the .mcpb package:
108
- ```bash
109
- npm run package:mcpb
110
- ```
111
-
112
- 2. Extract and configure:
113
- ```bash
114
- # Extract the .mcpb file
115
- Expand-Archive ynab-mcp-server-1.0.0.mcpb
116
-
117
- # Add to Claude Desktop MCP configuration
118
- ```
119
-
120
- ## Security Best Practices
121
-
122
- ### 1. Token Security
123
-
124
- - **Never commit tokens to version control**
125
- - Store tokens in environment variables only
126
- - Use different tokens for different environments
127
- - Rotate tokens regularly (every 90 days recommended)
128
-
129
- ### 2. File Permissions
130
-
131
- ```bash
132
- # Set restrictive permissions on sensitive files
133
- chmod 600 .env
134
- chmod 700 scripts/
135
- ```
136
-
137
- ### 3. Process Security
138
-
139
- - Run the server as a non-root user
140
- - Use process managers with automatic restart capabilities
141
- - Implement proper logging without exposing sensitive data
142
-
143
- ## Monitoring and Maintenance
144
-
145
- ### Health Checks
146
-
147
- Monitor server health and performance:
148
- - Monitor server response times
149
- - Track API rate limiting and usage patterns
150
- - Monitor for unusual access patterns
151
-
152
- ### Updates and Maintenance
153
-
154
- 1. **Regular Updates**:
155
- ```bash
156
- # Update dependencies
157
- npm audit
158
- npm update
159
-
160
- # Rebuild and test
161
- npm run build:prod
162
- npm run test:all
163
- ```
164
-
165
- 2. **Token Rotation**:
166
- - Generate new token in YNAB
167
- - Update environment variables
168
- - Restart the server
169
- - Revoke old token
170
-
171
- ## Troubleshooting
172
-
173
- ### Common Issues
174
-
175
- #### Authentication Errors
176
- **Symptoms**: 401 Unauthorized errors
177
- **Solutions**:
178
- - Verify `YNAB_ACCESS_TOKEN` is set correctly
179
- - Check token hasn't expired in YNAB settings
180
- - Ensure token has necessary permissions
181
-
182
- #### Rate Limiting
183
- **Symptoms**: 429 Too Many Requests errors
184
- **Solutions**:
185
- - Implement request throttling
186
- - Add retry logic with exponential backoff
187
- - Monitor API usage patterns
188
-
189
- For more deployment information, see the [Environment Guide](ENVIRONMENT.md).