regen-koi-mcp 1.0.6 → 1.2.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.
@@ -0,0 +1,279 @@
1
+ /**
2
+ * Metrics Module - Performance Tracking for KOI MCP Server
3
+ *
4
+ * Tracks query latency, error rates, cache hit rates, and other metrics.
5
+ * Provides in-memory metrics collection with percentile calculations.
6
+ */
7
+ /**
8
+ * Calculate percentile from sorted array
9
+ */
10
+ function percentile(sortedArr, p) {
11
+ if (sortedArr.length === 0)
12
+ return 0;
13
+ const index = Math.ceil((p / 100) * sortedArr.length) - 1;
14
+ return sortedArr[Math.max(0, index)];
15
+ }
16
+ /**
17
+ * Sliding window for tracking recent values
18
+ */
19
+ class SlidingWindow {
20
+ values = [];
21
+ maxSize;
22
+ constructor(maxSize = 1000) {
23
+ this.maxSize = maxSize;
24
+ }
25
+ add(value) {
26
+ this.values.push(value);
27
+ if (this.values.length > this.maxSize) {
28
+ this.values.shift();
29
+ }
30
+ }
31
+ getValues() {
32
+ return [...this.values];
33
+ }
34
+ getSorted() {
35
+ return [...this.values].sort((a, b) => a - b);
36
+ }
37
+ clear() {
38
+ this.values = [];
39
+ }
40
+ get length() {
41
+ return this.values.length;
42
+ }
43
+ }
44
+ /**
45
+ * Counter for tracking counts (errors, requests, etc.)
46
+ */
47
+ class Counter {
48
+ value = 0;
49
+ increment(amount = 1) {
50
+ this.value += amount;
51
+ }
52
+ getValue() {
53
+ return this.value;
54
+ }
55
+ reset() {
56
+ this.value = 0;
57
+ }
58
+ }
59
+ /**
60
+ * Main Metrics class - singleton pattern
61
+ */
62
+ class Metrics {
63
+ static instance;
64
+ // Per-tool metrics
65
+ toolMetrics = new Map();
66
+ // Cache metrics
67
+ cacheHits = new Counter();
68
+ cacheMisses = new Counter();
69
+ // Circuit breaker metrics
70
+ circuitBreaks = new Counter();
71
+ // API call metrics
72
+ apiLatencies = new SlidingWindow(500);
73
+ apiErrors = new Counter();
74
+ apiCalls = new Counter();
75
+ // Start time for uptime calculation
76
+ startTime = new Date();
77
+ constructor() { }
78
+ static getInstance() {
79
+ if (!Metrics.instance) {
80
+ Metrics.instance = new Metrics();
81
+ }
82
+ return Metrics.instance;
83
+ }
84
+ /**
85
+ * Get or create metrics for a specific tool
86
+ */
87
+ getToolMetrics(toolName) {
88
+ let metrics = this.toolMetrics.get(toolName);
89
+ if (!metrics) {
90
+ metrics = {
91
+ latencies: new SlidingWindow(200),
92
+ successCount: new Counter(),
93
+ errorCount: new Counter()
94
+ };
95
+ this.toolMetrics.set(toolName, metrics);
96
+ }
97
+ return metrics;
98
+ }
99
+ /**
100
+ * Record a query execution
101
+ */
102
+ recordQuery(toolName, durationMs, success, errorMessage) {
103
+ const metrics = this.getToolMetrics(toolName);
104
+ metrics.latencies.add(durationMs);
105
+ if (success) {
106
+ metrics.successCount.increment();
107
+ }
108
+ else {
109
+ metrics.errorCount.increment();
110
+ metrics.lastError = {
111
+ message: errorMessage || 'Unknown error',
112
+ timestamp: new Date()
113
+ };
114
+ }
115
+ }
116
+ /**
117
+ * Record cache hit/miss
118
+ */
119
+ recordCacheHit() {
120
+ this.cacheHits.increment();
121
+ }
122
+ recordCacheMiss() {
123
+ this.cacheMisses.increment();
124
+ }
125
+ /**
126
+ * Record circuit breaker open
127
+ */
128
+ recordCircuitBreak() {
129
+ this.circuitBreaks.increment();
130
+ }
131
+ /**
132
+ * Record API call
133
+ */
134
+ recordApiCall(durationMs, success) {
135
+ this.apiLatencies.add(durationMs);
136
+ this.apiCalls.increment();
137
+ if (!success) {
138
+ this.apiErrors.increment();
139
+ }
140
+ }
141
+ /**
142
+ * Get metrics for a specific tool
143
+ */
144
+ getToolStats(toolName) {
145
+ const metrics = this.getToolMetrics(toolName);
146
+ const sorted = metrics.latencies.getSorted();
147
+ const totalQueries = metrics.successCount.getValue() + metrics.errorCount.getValue();
148
+ const avgLatency = sorted.length > 0
149
+ ? sorted.reduce((a, b) => a + b, 0) / sorted.length
150
+ : 0;
151
+ return {
152
+ total_queries: totalQueries,
153
+ success_rate: totalQueries > 0
154
+ ? metrics.successCount.getValue() / totalQueries
155
+ : 1,
156
+ error_count: metrics.errorCount.getValue(),
157
+ p50_latency_ms: percentile(sorted, 50),
158
+ p95_latency_ms: percentile(sorted, 95),
159
+ p99_latency_ms: percentile(sorted, 99),
160
+ avg_latency_ms: Math.round(avgLatency * 100) / 100,
161
+ last_error: metrics.lastError ? {
162
+ message: metrics.lastError.message,
163
+ timestamp: metrics.lastError.timestamp.toISOString()
164
+ } : undefined
165
+ };
166
+ }
167
+ /**
168
+ * Get cache statistics
169
+ */
170
+ getCacheStats() {
171
+ const hits = this.cacheHits.getValue();
172
+ const misses = this.cacheMisses.getValue();
173
+ const total = hits + misses;
174
+ return {
175
+ hits,
176
+ misses,
177
+ hit_rate: total > 0 ? hits / total : 0
178
+ };
179
+ }
180
+ /**
181
+ * Get API statistics
182
+ */
183
+ getApiStats() {
184
+ const sorted = this.apiLatencies.getSorted();
185
+ const totalCalls = this.apiCalls.getValue();
186
+ return {
187
+ total_calls: totalCalls,
188
+ error_rate: totalCalls > 0
189
+ ? this.apiErrors.getValue() / totalCalls
190
+ : 0,
191
+ p50_latency_ms: percentile(sorted, 50),
192
+ p95_latency_ms: percentile(sorted, 95),
193
+ p99_latency_ms: percentile(sorted, 99)
194
+ };
195
+ }
196
+ /**
197
+ * Get all metrics as a summary object
198
+ */
199
+ getSummary() {
200
+ const tools = {};
201
+ for (const [toolName] of this.toolMetrics) {
202
+ tools[toolName] = this.getToolStats(toolName);
203
+ }
204
+ return {
205
+ uptime_seconds: Math.round((Date.now() - this.startTime.getTime()) / 1000),
206
+ tools,
207
+ cache: this.getCacheStats(),
208
+ api: this.getApiStats(),
209
+ circuit_breaks: this.circuitBreaks.getValue()
210
+ };
211
+ }
212
+ /**
213
+ * Format metrics as markdown for display
214
+ */
215
+ formatAsMarkdown() {
216
+ const summary = this.getSummary();
217
+ let md = `# KOI MCP Server Metrics\n\n`;
218
+ md += `**Uptime:** ${summary.uptime_seconds}s\n\n`;
219
+ md += `## Cache\n`;
220
+ md += `- Hit Rate: ${(summary.cache.hit_rate * 100).toFixed(1)}%\n`;
221
+ md += `- Hits: ${summary.cache.hits} | Misses: ${summary.cache.misses}\n\n`;
222
+ md += `## API Calls\n`;
223
+ md += `- Total: ${summary.api.total_calls}\n`;
224
+ md += `- Error Rate: ${(summary.api.error_rate * 100).toFixed(2)}%\n`;
225
+ md += `- Latency: p50=${summary.api.p50_latency_ms}ms, p95=${summary.api.p95_latency_ms}ms, p99=${summary.api.p99_latency_ms}ms\n\n`;
226
+ if (Object.keys(summary.tools).length > 0) {
227
+ md += `## Tools\n\n`;
228
+ md += `| Tool | Queries | Success Rate | p95 Latency |\n`;
229
+ md += `|------|---------|--------------|-------------|\n`;
230
+ for (const [toolName, stats] of Object.entries(summary.tools)) {
231
+ md += `| ${toolName} | ${stats.total_queries} | ${(stats.success_rate * 100).toFixed(1)}% | ${stats.p95_latency_ms}ms |\n`;
232
+ }
233
+ }
234
+ if (summary.circuit_breaks > 0) {
235
+ md += `\n## Circuit Breaker\n`;
236
+ md += `- Circuit Breaks: ${summary.circuit_breaks}\n`;
237
+ }
238
+ return md;
239
+ }
240
+ /**
241
+ * Reset all metrics (useful for testing)
242
+ */
243
+ reset() {
244
+ this.toolMetrics.clear();
245
+ this.cacheHits = new Counter();
246
+ this.cacheMisses = new Counter();
247
+ this.circuitBreaks = new Counter();
248
+ this.apiLatencies = new SlidingWindow(500);
249
+ this.apiErrors = new Counter();
250
+ this.apiCalls = new Counter();
251
+ this.startTime = new Date();
252
+ }
253
+ }
254
+ // Export singleton instance
255
+ export const metrics = Metrics.getInstance();
256
+ // Export convenience functions
257
+ export function recordQuery(toolName, durationMs, success, errorMessage) {
258
+ metrics.recordQuery(toolName, durationMs, success, errorMessage);
259
+ }
260
+ export function recordCacheHit() {
261
+ metrics.recordCacheHit();
262
+ }
263
+ export function recordCacheMiss() {
264
+ metrics.recordCacheMiss();
265
+ }
266
+ export function recordCircuitBreak() {
267
+ metrics.recordCircuitBreak();
268
+ }
269
+ export function recordApiCall(durationMs, success) {
270
+ metrics.recordApiCall(durationMs, success);
271
+ }
272
+ export function getMetricsSummary() {
273
+ return metrics.getSummary();
274
+ }
275
+ export function getMetricsMarkdown() {
276
+ return metrics.formatAsMarkdown();
277
+ }
278
+ export default metrics;
279
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Resilience Module - Retry Logic, Circuit Breaker, Timeouts
3
+ *
4
+ * Provides utilities for making the MCP server fault-tolerant:
5
+ * - Exponential backoff retry for transient failures
6
+ * - Circuit breaker to prevent cascading failures
7
+ * - Timeout wrapper for long-running operations
8
+ */
9
+ /**
10
+ * Check if an error is retriable (transient failure)
11
+ */
12
+ export declare function isRetriableError(error: any): boolean;
13
+ /**
14
+ * Options for retry logic
15
+ */
16
+ export interface RetryOptions {
17
+ maxRetries?: number;
18
+ initialDelayMs?: number;
19
+ maxDelayMs?: number;
20
+ backoffMultiplier?: number;
21
+ shouldRetry?: (error: any) => boolean;
22
+ onRetry?: (error: any, attempt: number, delayMs: number) => void;
23
+ }
24
+ /**
25
+ * Execute a function with exponential backoff retry
26
+ */
27
+ export declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
28
+ /**
29
+ * Circuit Breaker State
30
+ */
31
+ type CircuitState = 'closed' | 'open' | 'half-open';
32
+ /**
33
+ * Circuit Breaker options
34
+ */
35
+ export interface CircuitBreakerOptions {
36
+ failureThreshold?: number;
37
+ resetTimeoutMs?: number;
38
+ halfOpenMaxCalls?: number;
39
+ onStateChange?: (from: CircuitState, to: CircuitState) => void;
40
+ }
41
+ /**
42
+ * Circuit Breaker class for preventing cascading failures
43
+ */
44
+ export declare class CircuitBreaker {
45
+ private state;
46
+ private failureCount;
47
+ private successCount;
48
+ private lastFailureTime?;
49
+ private halfOpenCalls;
50
+ private options;
51
+ private serviceName;
52
+ constructor(serviceName: string, options?: CircuitBreakerOptions);
53
+ /**
54
+ * Get current circuit state
55
+ */
56
+ getState(): CircuitState;
57
+ /**
58
+ * Transition to a new state
59
+ */
60
+ private transitionTo;
61
+ /**
62
+ * Execute a function through the circuit breaker
63
+ */
64
+ execute<T>(fn: () => Promise<T>): Promise<T>;
65
+ /**
66
+ * Record a successful call
67
+ */
68
+ private recordSuccess;
69
+ /**
70
+ * Record a failed call
71
+ */
72
+ private recordFailure;
73
+ /**
74
+ * Manually reset the circuit breaker
75
+ */
76
+ reset(): void;
77
+ /**
78
+ * Get circuit breaker stats
79
+ */
80
+ getStats(): {
81
+ state: CircuitState;
82
+ failureCount: number;
83
+ successCount: number;
84
+ lastFailure?: string;
85
+ };
86
+ }
87
+ /**
88
+ * Custom error for circuit breaker open state
89
+ */
90
+ export declare class CircuitBreakerError extends Error {
91
+ serviceName: string;
92
+ retryAfter?: Date | undefined;
93
+ constructor(message: string, serviceName: string, retryAfter?: Date | undefined);
94
+ }
95
+ /**
96
+ * Custom error for timeouts
97
+ */
98
+ export declare class TimeoutError extends Error {
99
+ timeoutMs: number;
100
+ constructor(message: string, timeoutMs: number);
101
+ }
102
+ /**
103
+ * Execute a function with a timeout
104
+ */
105
+ export declare function withTimeout<T>(fn: () => Promise<T>, timeoutMs: number, operationName?: string): Promise<T>;
106
+ /**
107
+ * Combine retry and timeout
108
+ */
109
+ export declare function withRetryAndTimeout<T>(fn: () => Promise<T>, timeoutMs: number, retryOptions?: RetryOptions, operationName?: string): Promise<T>;
110
+ export declare const circuitBreakers: {
111
+ graphApi: CircuitBreaker;
112
+ koiApi: CircuitBreaker;
113
+ database: CircuitBreaker;
114
+ };
115
+ declare const _default: {
116
+ withRetry: typeof withRetry;
117
+ withTimeout: typeof withTimeout;
118
+ withRetryAndTimeout: typeof withRetryAndTimeout;
119
+ CircuitBreaker: typeof CircuitBreaker;
120
+ circuitBreakers: {
121
+ graphApi: CircuitBreaker;
122
+ koiApi: CircuitBreaker;
123
+ database: CircuitBreaker;
124
+ };
125
+ isRetriableError: typeof isRetriableError;
126
+ };
127
+ export default _default;
128
+ //# sourceMappingURL=resilience.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resilience.d.ts","sourceRoot":"","sources":["../src/resilience.ts"],"names":[],"mappings":"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"}