@wundr.io/mcp-registry 1.0.3

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.
@@ -0,0 +1,626 @@
1
+ "use strict";
2
+ /**
3
+ * @wundr.io/mcp-registry - Health Monitor
4
+ *
5
+ * Server health tracking, monitoring, and automatic recovery.
6
+ * Provides continuous health checks and status reporting.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.ServerHealthMonitor = exports.HealthCheckError = void 0;
12
+ exports.createServerHealthMonitor = createServerHealthMonitor;
13
+ const eventemitter3_1 = require("eventemitter3");
14
+ const types_1 = require("./types");
15
+ // =============================================================================
16
+ // Health Monitor Error Types
17
+ // =============================================================================
18
+ /**
19
+ * Error thrown when health check fails
20
+ */
21
+ class HealthCheckError extends Error {
22
+ serverId;
23
+ checkName;
24
+ constructor(serverId, checkName, message) {
25
+ super(message ?? `Health check "${checkName}" failed for server: ${serverId}`);
26
+ this.serverId = serverId;
27
+ this.checkName = checkName;
28
+ this.name = 'HealthCheckError';
29
+ }
30
+ }
31
+ exports.HealthCheckError = HealthCheckError;
32
+ // =============================================================================
33
+ // ServerHealthMonitor Class
34
+ // =============================================================================
35
+ /**
36
+ * Server Health Monitor
37
+ *
38
+ * Provides continuous health monitoring for registered MCP servers.
39
+ * Tracks connection status, latency, and custom health checks.
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const monitor = new ServerHealthMonitor(registry, {
44
+ * checkInterval: 10000,
45
+ * pingTimeout: 5000,
46
+ * failureThreshold: 3,
47
+ * });
48
+ *
49
+ * // Register custom health check
50
+ * monitor.registerCheck({
51
+ * name: 'memory-usage',
52
+ * check: async (server) => ({
53
+ * name: 'memory-usage',
54
+ * status: 'healthy',
55
+ * durationMs: 10,
56
+ * timestamp: new Date(),
57
+ * }),
58
+ * critical: false,
59
+ * timeout: 5000,
60
+ * });
61
+ *
62
+ * // Start monitoring
63
+ * await monitor.start();
64
+ *
65
+ * // Get server health
66
+ * const health = monitor.getHealth('server-id');
67
+ * ```
68
+ */
69
+ class ServerHealthMonitor extends eventemitter3_1.EventEmitter {
70
+ registry;
71
+ /** Configuration */
72
+ config;
73
+ /** Registered health checks */
74
+ healthChecks;
75
+ /** Latency history by server ID */
76
+ latencyHistory;
77
+ /** Consecutive failure counts by server ID */
78
+ failureCounts;
79
+ /** Consecutive success counts by server ID */
80
+ successCounts;
81
+ /** Monitoring interval handle */
82
+ monitoringInterval;
83
+ /** Whether monitoring is active */
84
+ isMonitoring;
85
+ /** Request counts by server ID */
86
+ requestCounts;
87
+ /**
88
+ * Creates a new ServerHealthMonitor
89
+ *
90
+ * @param registry - The server registry
91
+ * @param config - Health monitor configuration
92
+ */
93
+ constructor(registry, config = {}) {
94
+ super();
95
+ this.registry = registry;
96
+ // Validate and merge config with defaults
97
+ const validation = types_1.HealthMonitorConfigSchema.safeParse(config);
98
+ if (!validation.success) {
99
+ throw new Error(`Invalid health monitor config: ${validation.error.message}`);
100
+ }
101
+ this.config = {
102
+ checkInterval: config.checkInterval ?? 30000,
103
+ pingTimeout: config.pingTimeout ?? 5000,
104
+ failureThreshold: config.failureThreshold ?? 3,
105
+ recoveryThreshold: config.recoveryThreshold ?? 2,
106
+ degradedLatencyThreshold: config.degradedLatencyThreshold ?? 1000,
107
+ autoReconnect: config.autoReconnect ?? true,
108
+ maxReconnectAttempts: config.maxReconnectAttempts ?? 5,
109
+ };
110
+ this.healthChecks = new Map();
111
+ this.latencyHistory = new Map();
112
+ this.failureCounts = new Map();
113
+ this.successCounts = new Map();
114
+ this.requestCounts = new Map();
115
+ this.isMonitoring = false;
116
+ // Register default ping check
117
+ this.registerCheck({
118
+ name: 'ping',
119
+ check: this.createPingCheck(),
120
+ critical: true,
121
+ timeout: this.config.pingTimeout,
122
+ });
123
+ }
124
+ // ===========================================================================
125
+ // Lifecycle Methods
126
+ // ===========================================================================
127
+ /**
128
+ * Start health monitoring
129
+ */
130
+ async start() {
131
+ if (this.isMonitoring) {
132
+ return;
133
+ }
134
+ this.isMonitoring = true;
135
+ // Perform initial health check on all servers
136
+ await this.checkAllServers();
137
+ // Start periodic monitoring
138
+ this.monitoringInterval = setInterval(() => {
139
+ this.checkAllServers().catch(error => {
140
+ console.error('Health check cycle failed:', error);
141
+ });
142
+ }, this.config.checkInterval);
143
+ this.emit('monitor:started');
144
+ }
145
+ /**
146
+ * Stop health monitoring
147
+ */
148
+ async stop() {
149
+ if (!this.isMonitoring) {
150
+ return;
151
+ }
152
+ this.isMonitoring = false;
153
+ if (this.monitoringInterval) {
154
+ clearInterval(this.monitoringInterval);
155
+ this.monitoringInterval = undefined;
156
+ }
157
+ this.emit('monitor:stopped');
158
+ }
159
+ /**
160
+ * Check if monitoring is active
161
+ *
162
+ * @returns True if monitoring is active
163
+ */
164
+ isActive() {
165
+ return this.isMonitoring;
166
+ }
167
+ // ===========================================================================
168
+ // Health Check Registration
169
+ // ===========================================================================
170
+ /**
171
+ * Register a custom health check
172
+ *
173
+ * @param check - Health check to register
174
+ */
175
+ registerCheck(check) {
176
+ this.healthChecks.set(check.name, check);
177
+ }
178
+ /**
179
+ * Unregister a health check
180
+ *
181
+ * @param name - Check name to unregister
182
+ */
183
+ unregisterCheck(name) {
184
+ this.healthChecks.delete(name);
185
+ }
186
+ /**
187
+ * Get all registered checks
188
+ *
189
+ * @returns Array of registered health checks
190
+ */
191
+ getRegisteredChecks() {
192
+ return Array.from(this.healthChecks.values());
193
+ }
194
+ // ===========================================================================
195
+ // Health Status Methods
196
+ // ===========================================================================
197
+ /**
198
+ * Get health status for a server
199
+ *
200
+ * @param serverId - Server ID
201
+ * @returns Health status or undefined
202
+ */
203
+ getHealth(serverId) {
204
+ return this.registry.getHealthStatus(serverId);
205
+ }
206
+ /**
207
+ * Get health statuses for all servers
208
+ *
209
+ * @returns Map of server ID to health status
210
+ */
211
+ getAllHealth() {
212
+ const statuses = new Map();
213
+ for (const server of this.registry.getAll()) {
214
+ const health = this.registry.getHealthStatus(server.id);
215
+ if (health) {
216
+ statuses.set(server.id, health);
217
+ }
218
+ }
219
+ return statuses;
220
+ }
221
+ /**
222
+ * Force a health check for a specific server
223
+ *
224
+ * @param serverId - Server ID
225
+ * @returns Health status after check
226
+ */
227
+ async checkServer(serverId) {
228
+ const server = this.registry.get(serverId);
229
+ if (!server) {
230
+ throw new Error(`Server not found: ${serverId}`);
231
+ }
232
+ return this.performHealthCheck(server);
233
+ }
234
+ /**
235
+ * Check health of all servers
236
+ */
237
+ async checkAllServers() {
238
+ const servers = this.registry.getAll();
239
+ await Promise.all(servers.map(server => this.performHealthCheck(server).catch(error => {
240
+ console.error(`Health check failed for server ${server.id}:`, error);
241
+ })));
242
+ }
243
+ // ===========================================================================
244
+ // Request Tracking Methods
245
+ // ===========================================================================
246
+ /**
247
+ * Record a request for a server
248
+ *
249
+ * @param serverId - Server ID
250
+ * @param success - Whether request was successful
251
+ * @param latencyMs - Request latency in milliseconds
252
+ */
253
+ recordRequest(serverId, success, latencyMs) {
254
+ // Update request counts
255
+ const counts = this.requestCounts.get(serverId) ?? {
256
+ total: 0,
257
+ successful: 0,
258
+ };
259
+ counts.total++;
260
+ if (success) {
261
+ counts.successful++;
262
+ }
263
+ this.requestCounts.set(serverId, counts);
264
+ // Update latency history
265
+ if (latencyMs !== undefined) {
266
+ this.recordLatency(serverId, latencyMs);
267
+ }
268
+ // Update consecutive counts
269
+ if (success) {
270
+ this.incrementSuccessCount(serverId);
271
+ this.resetFailureCount(serverId);
272
+ }
273
+ else {
274
+ this.incrementFailureCount(serverId);
275
+ this.resetSuccessCount(serverId);
276
+ }
277
+ // Update health status
278
+ this.updateHealthFromCounts(serverId);
279
+ }
280
+ // ===========================================================================
281
+ // Private Health Check Methods
282
+ // ===========================================================================
283
+ /**
284
+ * Perform health check on a server
285
+ */
286
+ async performHealthCheck(server) {
287
+ const startTime = Date.now();
288
+ const checkResults = [];
289
+ let allPassed = true;
290
+ let hasCriticalFailure = false;
291
+ // Run all registered health checks
292
+ for (const [name, check] of this.healthChecks) {
293
+ try {
294
+ const result = await this.runCheckWithTimeout(check, server);
295
+ checkResults.push(result);
296
+ if (result.status === 'unhealthy') {
297
+ allPassed = false;
298
+ if (check.critical) {
299
+ hasCriticalFailure = true;
300
+ }
301
+ }
302
+ else if (result.status === 'degraded') {
303
+ allPassed = false;
304
+ }
305
+ }
306
+ catch (error) {
307
+ const result = {
308
+ name,
309
+ status: 'unhealthy',
310
+ message: error instanceof Error ? error.message : String(error),
311
+ durationMs: Date.now() - startTime,
312
+ timestamp: new Date(),
313
+ };
314
+ checkResults.push(result);
315
+ allPassed = false;
316
+ if (check.critical) {
317
+ hasCriticalFailure = true;
318
+ }
319
+ }
320
+ }
321
+ // Calculate overall status
322
+ const previousStatus = this.registry.getHealthStatus(server.id);
323
+ const previousLevel = previousStatus?.status ?? 'unknown';
324
+ let newStatus;
325
+ if (hasCriticalFailure) {
326
+ newStatus = 'unhealthy';
327
+ }
328
+ else if (!allPassed) {
329
+ newStatus = 'degraded';
330
+ }
331
+ else {
332
+ newStatus = 'healthy';
333
+ }
334
+ // Get latency metrics
335
+ const latencyMs = Date.now() - startTime;
336
+ this.recordLatency(server.id, latencyMs);
337
+ const avgLatencyMs = this.calculateAverageLatency(server.id);
338
+ // Check for latency-based degradation
339
+ if (newStatus === 'healthy' &&
340
+ avgLatencyMs > this.config.degradedLatencyThreshold) {
341
+ newStatus = 'degraded';
342
+ }
343
+ // Get request stats
344
+ const requestStats = this.requestCounts.get(server.id) ?? {
345
+ total: 0,
346
+ successful: 0,
347
+ };
348
+ const errorRate = requestStats.total > 0
349
+ ? 1 - requestStats.successful / requestStats.total
350
+ : 0;
351
+ // Build health status
352
+ const healthStatus = {
353
+ serverId: server.id,
354
+ status: newStatus,
355
+ connected: newStatus !== 'unhealthy',
356
+ lastPing: new Date(),
357
+ latencyMs,
358
+ avgLatencyMs,
359
+ consecutiveFailures: this.failureCounts.get(server.id) ?? 0,
360
+ totalRequests: requestStats.total,
361
+ successfulRequests: requestStats.successful,
362
+ errorRate,
363
+ checks: checkResults,
364
+ updatedAt: new Date(),
365
+ };
366
+ // Update registry
367
+ this.registry.updateHealthStatus(server.id, healthStatus);
368
+ // Emit events
369
+ this.emitHealthCheckEvent(server.id, healthStatus, checkResults);
370
+ if (previousLevel !== newStatus) {
371
+ this.emitHealthChangeEvent(server.id, previousLevel, newStatus);
372
+ }
373
+ return healthStatus;
374
+ }
375
+ /**
376
+ * Run a health check with timeout
377
+ */
378
+ async runCheckWithTimeout(check, server) {
379
+ return new Promise((resolve, reject) => {
380
+ const timer = setTimeout(() => {
381
+ reject(new HealthCheckError(server.id, check.name, 'Health check timed out'));
382
+ }, check.timeout);
383
+ check
384
+ .check(server)
385
+ .then(result => {
386
+ clearTimeout(timer);
387
+ resolve(result);
388
+ })
389
+ .catch(error => {
390
+ clearTimeout(timer);
391
+ reject(error);
392
+ });
393
+ });
394
+ }
395
+ /**
396
+ * Create the default ping check
397
+ */
398
+ createPingCheck() {
399
+ return async (server) => {
400
+ const startTime = Date.now();
401
+ // Simulate a ping check (in real implementation, would ping the server)
402
+ // For now, check if server is in registry and has valid transport config
403
+ const isValid = server.transport.type !== undefined &&
404
+ (server.transport.command !== undefined ||
405
+ server.transport.url !== undefined);
406
+ return {
407
+ name: 'ping',
408
+ status: isValid ? 'healthy' : 'unhealthy',
409
+ message: isValid
410
+ ? 'Server is reachable'
411
+ : 'Server configuration invalid',
412
+ durationMs: Date.now() - startTime,
413
+ timestamp: new Date(),
414
+ };
415
+ };
416
+ }
417
+ // ===========================================================================
418
+ // Private Helper Methods
419
+ // ===========================================================================
420
+ /**
421
+ * Record latency for a server
422
+ */
423
+ recordLatency(serverId, latencyMs) {
424
+ let history = this.latencyHistory.get(serverId);
425
+ if (!history) {
426
+ history = [];
427
+ this.latencyHistory.set(serverId, history);
428
+ }
429
+ // Keep last 100 latency measurements
430
+ history.push(latencyMs);
431
+ if (history.length > 100) {
432
+ history.shift();
433
+ }
434
+ }
435
+ /**
436
+ * Calculate average latency for a server
437
+ */
438
+ calculateAverageLatency(serverId) {
439
+ const history = this.latencyHistory.get(serverId);
440
+ if (!history || history.length === 0) {
441
+ return 0;
442
+ }
443
+ const sum = history.reduce((acc, val) => acc + val, 0);
444
+ return sum / history.length;
445
+ }
446
+ /**
447
+ * Increment failure count for a server
448
+ */
449
+ incrementFailureCount(serverId) {
450
+ const count = this.failureCounts.get(serverId) ?? 0;
451
+ this.failureCounts.set(serverId, count + 1);
452
+ }
453
+ /**
454
+ * Reset failure count for a server
455
+ */
456
+ resetFailureCount(serverId) {
457
+ this.failureCounts.set(serverId, 0);
458
+ }
459
+ /**
460
+ * Increment success count for a server
461
+ */
462
+ incrementSuccessCount(serverId) {
463
+ const count = this.successCounts.get(serverId) ?? 0;
464
+ this.successCounts.set(serverId, count + 1);
465
+ }
466
+ /**
467
+ * Reset success count for a server
468
+ */
469
+ resetSuccessCount(serverId) {
470
+ this.successCounts.set(serverId, 0);
471
+ }
472
+ /**
473
+ * Update health status from consecutive counts
474
+ */
475
+ updateHealthFromCounts(serverId) {
476
+ const failureCount = this.failureCounts.get(serverId) ?? 0;
477
+ const successCount = this.successCounts.get(serverId) ?? 0;
478
+ const currentHealth = this.registry.getHealthStatus(serverId);
479
+ const previousStatus = currentHealth?.status ?? 'unknown';
480
+ let newStatus = previousStatus;
481
+ if (failureCount >= this.config.failureThreshold) {
482
+ newStatus = 'unhealthy';
483
+ }
484
+ else if (previousStatus === 'unhealthy' &&
485
+ successCount >= this.config.recoveryThreshold) {
486
+ newStatus = 'healthy';
487
+ }
488
+ else if (failureCount > 0 && previousStatus === 'healthy') {
489
+ newStatus = 'degraded';
490
+ }
491
+ if (previousStatus !== newStatus) {
492
+ this.registry.updateHealthStatus(serverId, { status: newStatus });
493
+ this.emitHealthChangeEvent(serverId, previousStatus, newStatus);
494
+ }
495
+ }
496
+ /**
497
+ * Emit health check event
498
+ */
499
+ emitHealthCheckEvent(serverId, status, checks) {
500
+ const event = {
501
+ serverId,
502
+ status,
503
+ checks,
504
+ timestamp: new Date(),
505
+ };
506
+ this.emit('health:checked', event);
507
+ }
508
+ /**
509
+ * Emit health change event
510
+ */
511
+ emitHealthChangeEvent(serverId, previousStatus, newStatus) {
512
+ const event = {
513
+ serverId,
514
+ previousStatus,
515
+ newStatus,
516
+ timestamp: new Date(),
517
+ };
518
+ this.emit('health:changed', event);
519
+ // Emit specific events
520
+ if (newStatus === 'degraded' && previousStatus === 'healthy') {
521
+ this.emit('health:degraded', event);
522
+ }
523
+ else if (newStatus === 'healthy' && previousStatus !== 'healthy') {
524
+ this.emit('health:recovered', event);
525
+ }
526
+ else if (newStatus === 'unhealthy') {
527
+ this.emit('health:failed', event);
528
+ }
529
+ // Emit connection events
530
+ if (previousStatus !== 'unhealthy' && newStatus === 'unhealthy') {
531
+ this.emit('server:disconnected', {
532
+ serverId,
533
+ connected: false,
534
+ timestamp: new Date(),
535
+ });
536
+ }
537
+ else if (previousStatus === 'unhealthy' && newStatus !== 'unhealthy') {
538
+ this.emit('server:connected', {
539
+ serverId,
540
+ connected: true,
541
+ timestamp: new Date(),
542
+ });
543
+ }
544
+ }
545
+ // ===========================================================================
546
+ // Utility Methods
547
+ // ===========================================================================
548
+ /**
549
+ * Get monitoring statistics
550
+ *
551
+ * @returns Health monitor statistics
552
+ */
553
+ getStats() {
554
+ const allHealth = this.getAllHealth();
555
+ let healthy = 0;
556
+ let degraded = 0;
557
+ let unhealthy = 0;
558
+ let unknown = 0;
559
+ for (const status of allHealth.values()) {
560
+ switch (status.status) {
561
+ case 'healthy':
562
+ healthy++;
563
+ break;
564
+ case 'degraded':
565
+ degraded++;
566
+ break;
567
+ case 'unhealthy':
568
+ unhealthy++;
569
+ break;
570
+ default:
571
+ unknown++;
572
+ }
573
+ }
574
+ return {
575
+ isMonitoring: this.isMonitoring,
576
+ checkInterval: this.config.checkInterval,
577
+ totalServers: allHealth.size,
578
+ healthyServers: healthy,
579
+ degradedServers: degraded,
580
+ unhealthyServers: unhealthy,
581
+ unknownServers: unknown,
582
+ registeredChecks: this.healthChecks.size,
583
+ };
584
+ }
585
+ /**
586
+ * Reset all monitoring state
587
+ */
588
+ reset() {
589
+ this.latencyHistory.clear();
590
+ this.failureCounts.clear();
591
+ this.successCounts.clear();
592
+ this.requestCounts.clear();
593
+ }
594
+ /**
595
+ * Get configuration
596
+ *
597
+ * @returns Current configuration
598
+ */
599
+ getConfig() {
600
+ return { ...this.config };
601
+ }
602
+ }
603
+ exports.ServerHealthMonitor = ServerHealthMonitor;
604
+ // =============================================================================
605
+ // Factory Function
606
+ // =============================================================================
607
+ /**
608
+ * Create a new ServerHealthMonitor
609
+ *
610
+ * @param registry - The server registry
611
+ * @param config - Optional health monitor configuration
612
+ * @returns New health monitor instance
613
+ *
614
+ * @example
615
+ * ```typescript
616
+ * const monitor = createServerHealthMonitor(registry, {
617
+ * checkInterval: 10000,
618
+ * pingTimeout: 5000,
619
+ * });
620
+ * await monitor.start();
621
+ * ```
622
+ */
623
+ function createServerHealthMonitor(registry, config) {
624
+ return new ServerHealthMonitor(registry, config);
625
+ }
626
+ //# sourceMappingURL=health-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-monitor.js","sourceRoot":"","sources":["../src/health-monitor.ts"],"names":[],"mappings":"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"}