@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.
- package/README.md +890 -0
- package/dist/aggregator.d.ts +330 -0
- package/dist/aggregator.d.ts.map +1 -0
- package/dist/aggregator.js +708 -0
- package/dist/aggregator.js.map +1 -0
- package/dist/discovery.d.ts +274 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +536 -0
- package/dist/discovery.js.map +1 -0
- package/dist/health-monitor.d.ts +304 -0
- package/dist/health-monitor.d.ts.map +1 -0
- package/dist/health-monitor.js +626 -0
- package/dist/health-monitor.js.map +1 -0
- package/dist/index.d.ts +109 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +185 -0
- package/dist/index.js.map +1 -0
- package/dist/registry.d.ts +323 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +647 -0
- package/dist/registry.js.map +1 -0
- package/dist/types.d.ts +663 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +120 -0
- package/dist/types.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @wundr.io/mcp-registry - Health Monitor
|
|
3
|
+
*
|
|
4
|
+
* Server health tracking, monitoring, and automatic recovery.
|
|
5
|
+
* Provides continuous health checks and status reporting.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
import { EventEmitter } from 'eventemitter3';
|
|
10
|
+
import type { MCPServerRegistry } from './registry';
|
|
11
|
+
import type { HealthStatus, HealthLevel, HealthCheckResult, HealthMonitorConfig, MCPServerRegistration } from './types';
|
|
12
|
+
/**
|
|
13
|
+
* Error thrown when health check fails
|
|
14
|
+
*/
|
|
15
|
+
export declare class HealthCheckError extends Error {
|
|
16
|
+
readonly serverId: string;
|
|
17
|
+
readonly checkName: string;
|
|
18
|
+
constructor(serverId: string, checkName: string, message?: string);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Event map for health monitor events
|
|
22
|
+
*/
|
|
23
|
+
export interface HealthMonitorEvents {
|
|
24
|
+
'health:checked': (event: HealthCheckEvent) => void;
|
|
25
|
+
'health:changed': (event: HealthChangeEvent) => void;
|
|
26
|
+
'health:degraded': (event: HealthChangeEvent) => void;
|
|
27
|
+
'health:recovered': (event: HealthChangeEvent) => void;
|
|
28
|
+
'health:failed': (event: HealthChangeEvent) => void;
|
|
29
|
+
'server:connected': (event: ConnectionEvent) => void;
|
|
30
|
+
'server:disconnected': (event: ConnectionEvent) => void;
|
|
31
|
+
'monitor:started': () => void;
|
|
32
|
+
'monitor:stopped': () => void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Health check event data
|
|
36
|
+
*/
|
|
37
|
+
export interface HealthCheckEvent {
|
|
38
|
+
readonly serverId: string;
|
|
39
|
+
readonly status: HealthStatus;
|
|
40
|
+
readonly checks: readonly HealthCheckResult[];
|
|
41
|
+
readonly timestamp: Date;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Health change event data
|
|
45
|
+
*/
|
|
46
|
+
export interface HealthChangeEvent {
|
|
47
|
+
readonly serverId: string;
|
|
48
|
+
readonly previousStatus: HealthLevel;
|
|
49
|
+
readonly newStatus: HealthLevel;
|
|
50
|
+
readonly reason?: string;
|
|
51
|
+
readonly timestamp: Date;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Connection event data
|
|
55
|
+
*/
|
|
56
|
+
export interface ConnectionEvent {
|
|
57
|
+
readonly serverId: string;
|
|
58
|
+
readonly connected: boolean;
|
|
59
|
+
readonly timestamp: Date;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Health check function type
|
|
63
|
+
*/
|
|
64
|
+
export type HealthCheckFn = (server: MCPServerRegistration) => Promise<HealthCheckResult>;
|
|
65
|
+
/**
|
|
66
|
+
* Registered health check
|
|
67
|
+
*/
|
|
68
|
+
export interface RegisteredHealthCheck {
|
|
69
|
+
/** Check name */
|
|
70
|
+
readonly name: string;
|
|
71
|
+
/** Check function */
|
|
72
|
+
readonly check: HealthCheckFn;
|
|
73
|
+
/** Whether check is critical (affects overall status) */
|
|
74
|
+
readonly critical: boolean;
|
|
75
|
+
/** Check timeout in milliseconds */
|
|
76
|
+
readonly timeout: number;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Server Health Monitor
|
|
80
|
+
*
|
|
81
|
+
* Provides continuous health monitoring for registered MCP servers.
|
|
82
|
+
* Tracks connection status, latency, and custom health checks.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const monitor = new ServerHealthMonitor(registry, {
|
|
87
|
+
* checkInterval: 10000,
|
|
88
|
+
* pingTimeout: 5000,
|
|
89
|
+
* failureThreshold: 3,
|
|
90
|
+
* });
|
|
91
|
+
*
|
|
92
|
+
* // Register custom health check
|
|
93
|
+
* monitor.registerCheck({
|
|
94
|
+
* name: 'memory-usage',
|
|
95
|
+
* check: async (server) => ({
|
|
96
|
+
* name: 'memory-usage',
|
|
97
|
+
* status: 'healthy',
|
|
98
|
+
* durationMs: 10,
|
|
99
|
+
* timestamp: new Date(),
|
|
100
|
+
* }),
|
|
101
|
+
* critical: false,
|
|
102
|
+
* timeout: 5000,
|
|
103
|
+
* });
|
|
104
|
+
*
|
|
105
|
+
* // Start monitoring
|
|
106
|
+
* await monitor.start();
|
|
107
|
+
*
|
|
108
|
+
* // Get server health
|
|
109
|
+
* const health = monitor.getHealth('server-id');
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
export declare class ServerHealthMonitor extends EventEmitter<HealthMonitorEvents> {
|
|
113
|
+
private readonly registry;
|
|
114
|
+
/** Configuration */
|
|
115
|
+
private readonly config;
|
|
116
|
+
/** Registered health checks */
|
|
117
|
+
private readonly healthChecks;
|
|
118
|
+
/** Latency history by server ID */
|
|
119
|
+
private readonly latencyHistory;
|
|
120
|
+
/** Consecutive failure counts by server ID */
|
|
121
|
+
private readonly failureCounts;
|
|
122
|
+
/** Consecutive success counts by server ID */
|
|
123
|
+
private readonly successCounts;
|
|
124
|
+
/** Monitoring interval handle */
|
|
125
|
+
private monitoringInterval?;
|
|
126
|
+
/** Whether monitoring is active */
|
|
127
|
+
private isMonitoring;
|
|
128
|
+
/** Request counts by server ID */
|
|
129
|
+
private readonly requestCounts;
|
|
130
|
+
/**
|
|
131
|
+
* Creates a new ServerHealthMonitor
|
|
132
|
+
*
|
|
133
|
+
* @param registry - The server registry
|
|
134
|
+
* @param config - Health monitor configuration
|
|
135
|
+
*/
|
|
136
|
+
constructor(registry: MCPServerRegistry, config?: HealthMonitorConfig);
|
|
137
|
+
/**
|
|
138
|
+
* Start health monitoring
|
|
139
|
+
*/
|
|
140
|
+
start(): Promise<void>;
|
|
141
|
+
/**
|
|
142
|
+
* Stop health monitoring
|
|
143
|
+
*/
|
|
144
|
+
stop(): Promise<void>;
|
|
145
|
+
/**
|
|
146
|
+
* Check if monitoring is active
|
|
147
|
+
*
|
|
148
|
+
* @returns True if monitoring is active
|
|
149
|
+
*/
|
|
150
|
+
isActive(): boolean;
|
|
151
|
+
/**
|
|
152
|
+
* Register a custom health check
|
|
153
|
+
*
|
|
154
|
+
* @param check - Health check to register
|
|
155
|
+
*/
|
|
156
|
+
registerCheck(check: RegisteredHealthCheck): void;
|
|
157
|
+
/**
|
|
158
|
+
* Unregister a health check
|
|
159
|
+
*
|
|
160
|
+
* @param name - Check name to unregister
|
|
161
|
+
*/
|
|
162
|
+
unregisterCheck(name: string): void;
|
|
163
|
+
/**
|
|
164
|
+
* Get all registered checks
|
|
165
|
+
*
|
|
166
|
+
* @returns Array of registered health checks
|
|
167
|
+
*/
|
|
168
|
+
getRegisteredChecks(): readonly RegisteredHealthCheck[];
|
|
169
|
+
/**
|
|
170
|
+
* Get health status for a server
|
|
171
|
+
*
|
|
172
|
+
* @param serverId - Server ID
|
|
173
|
+
* @returns Health status or undefined
|
|
174
|
+
*/
|
|
175
|
+
getHealth(serverId: string): HealthStatus | undefined;
|
|
176
|
+
/**
|
|
177
|
+
* Get health statuses for all servers
|
|
178
|
+
*
|
|
179
|
+
* @returns Map of server ID to health status
|
|
180
|
+
*/
|
|
181
|
+
getAllHealth(): ReadonlyMap<string, HealthStatus>;
|
|
182
|
+
/**
|
|
183
|
+
* Force a health check for a specific server
|
|
184
|
+
*
|
|
185
|
+
* @param serverId - Server ID
|
|
186
|
+
* @returns Health status after check
|
|
187
|
+
*/
|
|
188
|
+
checkServer(serverId: string): Promise<HealthStatus>;
|
|
189
|
+
/**
|
|
190
|
+
* Check health of all servers
|
|
191
|
+
*/
|
|
192
|
+
checkAllServers(): Promise<void>;
|
|
193
|
+
/**
|
|
194
|
+
* Record a request for a server
|
|
195
|
+
*
|
|
196
|
+
* @param serverId - Server ID
|
|
197
|
+
* @param success - Whether request was successful
|
|
198
|
+
* @param latencyMs - Request latency in milliseconds
|
|
199
|
+
*/
|
|
200
|
+
recordRequest(serverId: string, success: boolean, latencyMs?: number): void;
|
|
201
|
+
/**
|
|
202
|
+
* Perform health check on a server
|
|
203
|
+
*/
|
|
204
|
+
private performHealthCheck;
|
|
205
|
+
/**
|
|
206
|
+
* Run a health check with timeout
|
|
207
|
+
*/
|
|
208
|
+
private runCheckWithTimeout;
|
|
209
|
+
/**
|
|
210
|
+
* Create the default ping check
|
|
211
|
+
*/
|
|
212
|
+
private createPingCheck;
|
|
213
|
+
/**
|
|
214
|
+
* Record latency for a server
|
|
215
|
+
*/
|
|
216
|
+
private recordLatency;
|
|
217
|
+
/**
|
|
218
|
+
* Calculate average latency for a server
|
|
219
|
+
*/
|
|
220
|
+
private calculateAverageLatency;
|
|
221
|
+
/**
|
|
222
|
+
* Increment failure count for a server
|
|
223
|
+
*/
|
|
224
|
+
private incrementFailureCount;
|
|
225
|
+
/**
|
|
226
|
+
* Reset failure count for a server
|
|
227
|
+
*/
|
|
228
|
+
private resetFailureCount;
|
|
229
|
+
/**
|
|
230
|
+
* Increment success count for a server
|
|
231
|
+
*/
|
|
232
|
+
private incrementSuccessCount;
|
|
233
|
+
/**
|
|
234
|
+
* Reset success count for a server
|
|
235
|
+
*/
|
|
236
|
+
private resetSuccessCount;
|
|
237
|
+
/**
|
|
238
|
+
* Update health status from consecutive counts
|
|
239
|
+
*/
|
|
240
|
+
private updateHealthFromCounts;
|
|
241
|
+
/**
|
|
242
|
+
* Emit health check event
|
|
243
|
+
*/
|
|
244
|
+
private emitHealthCheckEvent;
|
|
245
|
+
/**
|
|
246
|
+
* Emit health change event
|
|
247
|
+
*/
|
|
248
|
+
private emitHealthChangeEvent;
|
|
249
|
+
/**
|
|
250
|
+
* Get monitoring statistics
|
|
251
|
+
*
|
|
252
|
+
* @returns Health monitor statistics
|
|
253
|
+
*/
|
|
254
|
+
getStats(): HealthMonitorStats;
|
|
255
|
+
/**
|
|
256
|
+
* Reset all monitoring state
|
|
257
|
+
*/
|
|
258
|
+
reset(): void;
|
|
259
|
+
/**
|
|
260
|
+
* Get configuration
|
|
261
|
+
*
|
|
262
|
+
* @returns Current configuration
|
|
263
|
+
*/
|
|
264
|
+
getConfig(): Readonly<Required<HealthMonitorConfig>>;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Health monitor statistics
|
|
268
|
+
*/
|
|
269
|
+
export interface HealthMonitorStats {
|
|
270
|
+
/** Whether monitoring is active */
|
|
271
|
+
readonly isMonitoring: boolean;
|
|
272
|
+
/** Check interval in milliseconds */
|
|
273
|
+
readonly checkInterval: number;
|
|
274
|
+
/** Total number of servers */
|
|
275
|
+
readonly totalServers: number;
|
|
276
|
+
/** Number of healthy servers */
|
|
277
|
+
readonly healthyServers: number;
|
|
278
|
+
/** Number of degraded servers */
|
|
279
|
+
readonly degradedServers: number;
|
|
280
|
+
/** Number of unhealthy servers */
|
|
281
|
+
readonly unhealthyServers: number;
|
|
282
|
+
/** Number of servers with unknown status */
|
|
283
|
+
readonly unknownServers: number;
|
|
284
|
+
/** Number of registered health checks */
|
|
285
|
+
readonly registeredChecks: number;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Create a new ServerHealthMonitor
|
|
289
|
+
*
|
|
290
|
+
* @param registry - The server registry
|
|
291
|
+
* @param config - Optional health monitor configuration
|
|
292
|
+
* @returns New health monitor instance
|
|
293
|
+
*
|
|
294
|
+
* @example
|
|
295
|
+
* ```typescript
|
|
296
|
+
* const monitor = createServerHealthMonitor(registry, {
|
|
297
|
+
* checkInterval: 10000,
|
|
298
|
+
* pingTimeout: 5000,
|
|
299
|
+
* });
|
|
300
|
+
* await monitor.start();
|
|
301
|
+
* ```
|
|
302
|
+
*/
|
|
303
|
+
export declare function createServerHealthMonitor(registry: MCPServerRegistry, config?: HealthMonitorConfig): ServerHealthMonitor;
|
|
304
|
+
//# sourceMappingURL=health-monitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-monitor.d.ts","sourceRoot":"","sources":["../src/health-monitor.ts"],"names":[],"mappings":"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"}
|