@defai.digital/ax-cli 3.2.0 → 3.4.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.
- package/.ax-cli/memory.json +8 -1
- package/README.md +118 -2
- package/config/models.yaml +13 -0
- package/config/settings.yaml +6 -0
- package/dist/agent/context-manager.d.ts +5 -5
- package/dist/agent/context-manager.js +19 -9
- package/dist/agent/context-manager.js.map +1 -1
- package/dist/agent/dependency-resolver.js +2 -1
- package/dist/agent/dependency-resolver.js.map +1 -1
- package/dist/agent/llm-agent.d.ts +3 -2
- package/dist/agent/llm-agent.js +64 -58
- package/dist/agent/llm-agent.js.map +1 -1
- package/dist/agent/subagent.js +2 -1
- package/dist/agent/subagent.js.map +1 -1
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.d.ts +29 -0
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.js +103 -0
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.js.map +1 -0
- package/dist/analyzers/architecture/architecture-analyzer.d.ts +58 -0
- package/dist/analyzers/architecture/architecture-analyzer.js +276 -0
- package/dist/analyzers/architecture/architecture-analyzer.js.map +1 -0
- package/dist/analyzers/architecture/index.d.ts +12 -0
- package/dist/analyzers/architecture/index.js +14 -0
- package/dist/analyzers/architecture/index.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/base-detector.d.ts +27 -0
- package/dist/analyzers/architecture/pattern-detectors/base-detector.js +31 -0
- package/dist/analyzers/architecture/pattern-detectors/base-detector.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.d.ts +11 -0
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.js +57 -0
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.d.ts +11 -0
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.js +43 -0
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.d.ts +11 -0
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.js +49 -0
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.js.map +1 -0
- package/dist/analyzers/architecture/project-structure-scanner.d.ts +54 -0
- package/dist/analyzers/architecture/project-structure-scanner.js +200 -0
- package/dist/analyzers/architecture/project-structure-scanner.js.map +1 -0
- package/dist/analyzers/best-practices/base-rule.d.ts +45 -0
- package/dist/analyzers/best-practices/base-rule.js +45 -0
- package/dist/analyzers/best-practices/base-rule.js.map +1 -0
- package/dist/analyzers/best-practices/best-practice-validator.d.ts +35 -0
- package/dist/analyzers/best-practices/best-practice-validator.js +181 -0
- package/dist/analyzers/best-practices/best-practice-validator.js.map +1 -0
- package/dist/analyzers/best-practices/rules/index.d.ts +7 -0
- package/dist/analyzers/best-practices/rules/index.js +56 -0
- package/dist/analyzers/best-practices/rules/index.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.js +41 -0
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.d.ts +27 -0
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.js +76 -0
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/index.d.ts +15 -0
- package/dist/analyzers/best-practices/rules/typescript/index.js +16 -0
- package/dist/analyzers/best-practices/rules/typescript/index.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.d.ts +18 -0
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.js +25 -0
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.js +27 -0
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.d.ts +18 -0
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.js +39 -0
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.js +32 -0
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.js +36 -0
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.js +33 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.js +34 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.js +27 -0
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.js.map +1 -0
- package/dist/analyzers/best-practices/types.d.ts +86 -0
- package/dist/analyzers/best-practices/types.js +7 -0
- package/dist/analyzers/best-practices/types.js.map +1 -0
- package/dist/analyzers/cache/analysis-cache.d.ts +41 -0
- package/dist/analyzers/cache/analysis-cache.js +84 -0
- package/dist/analyzers/cache/analysis-cache.js.map +1 -0
- package/dist/analyzers/errors.d.ts +51 -0
- package/dist/analyzers/errors.js +79 -0
- package/dist/analyzers/errors.js.map +1 -0
- package/dist/commands/doctor.js +3 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/frontend.d.ts +9 -0
- package/dist/commands/frontend.js +645 -0
- package/dist/commands/frontend.js.map +1 -0
- package/dist/commands/mcp.js +652 -3
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/models.js +2 -2
- package/dist/commands/models.js.map +1 -1
- package/dist/commands/setup.js +100 -41
- package/dist/commands/setup.js.map +1 -1
- package/dist/constants.d.ts +4 -0
- package/dist/constants.js +4 -0
- package/dist/constants.js.map +1 -1
- package/dist/hooks/use-enhanced-input.js +16 -3
- package/dist/hooks/use-enhanced-input.js.map +1 -1
- package/dist/hooks/use-input-handler.js +9 -4
- package/dist/hooks/use-input-handler.js.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/llm/client.d.ts +1 -0
- package/dist/llm/tools.js +86 -0
- package/dist/llm/tools.js.map +1 -1
- package/dist/llm/types.d.ts +49 -22
- package/dist/llm/types.js +12 -8
- package/dist/llm/types.js.map +1 -1
- package/dist/mcp/client.d.ts +5 -0
- package/dist/mcp/client.js +55 -0
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/config.d.ts +1 -1
- package/dist/mcp/config.js +2 -2
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/health.d.ts +120 -0
- package/dist/mcp/health.js +267 -0
- package/dist/mcp/health.js.map +1 -0
- package/dist/mcp/reconnection.d.ts +93 -0
- package/dist/mcp/reconnection.js +216 -0
- package/dist/mcp/reconnection.js.map +1 -0
- package/dist/mcp/registry.d.ts +71 -0
- package/dist/mcp/registry.js +257 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/resources.d.ts +53 -0
- package/dist/mcp/resources.js +135 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/templates.d.ts +52 -0
- package/dist/mcp/templates.js +624 -0
- package/dist/mcp/templates.js.map +1 -0
- package/dist/mcp/validation.d.ts +25 -0
- package/dist/mcp/validation.js +209 -0
- package/dist/mcp/validation.js.map +1 -0
- package/dist/memory/context-generator.js +1 -2
- package/dist/memory/context-generator.js.map +1 -1
- package/dist/planner/types.d.ts +2 -2
- package/dist/schemas/api-schemas.d.ts +2 -1
- package/dist/schemas/api-schemas.js +6 -4
- package/dist/schemas/api-schemas.js.map +1 -1
- package/dist/schemas/index.d.ts +4 -4
- package/dist/schemas/tool-schemas.d.ts +2 -2
- package/dist/schemas/yaml-schemas.d.ts +15 -0
- package/dist/schemas/yaml-schemas.js +3 -0
- package/dist/schemas/yaml-schemas.js.map +1 -1
- package/dist/sdk/index.d.ts +138 -0
- package/dist/sdk/index.js +173 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/types.d.ts +53 -0
- package/dist/sdk/types.js +8 -0
- package/dist/sdk/types.js.map +1 -0
- package/dist/tools/analysis-tools/architecture-tool.d.ts +46 -0
- package/dist/tools/analysis-tools/architecture-tool.js +124 -0
- package/dist/tools/analysis-tools/architecture-tool.js.map +1 -0
- package/dist/tools/analysis-tools/validation-tool.d.ts +51 -0
- package/dist/tools/analysis-tools/validation-tool.js +121 -0
- package/dist/tools/analysis-tools/validation-tool.js.map +1 -0
- package/dist/tools/bash.js +25 -10
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/web-search/cache.d.ts +62 -0
- package/dist/tools/web-search/cache.js +105 -0
- package/dist/tools/web-search/cache.js.map +1 -0
- package/dist/tools/web-search/engines/brave.d.ts +16 -0
- package/dist/tools/web-search/engines/brave.js +99 -0
- package/dist/tools/web-search/engines/brave.js.map +1 -0
- package/dist/tools/web-search/engines/crates.d.ts +19 -0
- package/dist/tools/web-search/engines/crates.js +87 -0
- package/dist/tools/web-search/engines/crates.js.map +1 -0
- package/dist/tools/web-search/engines/npm.d.ts +18 -0
- package/dist/tools/web-search/engines/npm.js +86 -0
- package/dist/tools/web-search/engines/npm.js.map +1 -0
- package/dist/tools/web-search/engines/pypi.d.ts +18 -0
- package/dist/tools/web-search/engines/pypi.js +75 -0
- package/dist/tools/web-search/engines/pypi.js.map +1 -0
- package/dist/tools/web-search/engines/tavily.d.ts +17 -0
- package/dist/tools/web-search/engines/tavily.js +73 -0
- package/dist/tools/web-search/engines/tavily.js.map +1 -0
- package/dist/tools/web-search/index.d.ts +13 -0
- package/dist/tools/web-search/index.js +13 -0
- package/dist/tools/web-search/index.js.map +1 -0
- package/dist/tools/web-search/router.d.ts +36 -0
- package/dist/tools/web-search/router.js +280 -0
- package/dist/tools/web-search/router.js.map +1 -0
- package/dist/tools/web-search/types.d.ts +45 -0
- package/dist/tools/web-search/types.js +6 -0
- package/dist/tools/web-search/types.js.map +1 -0
- package/dist/tools/web-search/web-search-tool.d.ts +51 -0
- package/dist/tools/web-search/web-search-tool.js +256 -0
- package/dist/tools/web-search/web-search-tool.js.map +1 -0
- package/dist/types/analysis.d.ts +177 -0
- package/dist/types/analysis.js +8 -0
- package/dist/types/analysis.js.map +1 -0
- package/dist/ui/components/api-key-input.js +2 -2
- package/dist/ui/components/api-key-input.js.map +1 -1
- package/dist/ui/components/chat-history.js +14 -7
- package/dist/ui/components/chat-history.js.map +1 -1
- package/dist/ui/components/chat-input.js +12 -7
- package/dist/ui/components/chat-input.js.map +1 -1
- package/dist/ui/components/chat-interface.js +75 -54
- package/dist/ui/components/chat-interface.js.map +1 -1
- package/dist/ui/components/keyboard-hints.js +5 -4
- package/dist/ui/components/keyboard-hints.js.map +1 -1
- package/dist/ui/components/quick-actions.js +1 -0
- package/dist/ui/components/quick-actions.js.map +1 -1
- package/dist/ui/components/reasoning-display.js +14 -4
- package/dist/ui/components/reasoning-display.js.map +1 -1
- package/dist/ui/components/status-bar.d.ts +1 -0
- package/dist/ui/components/status-bar.js +37 -39
- package/dist/ui/components/status-bar.js.map +1 -1
- package/dist/ui/components/toast-notification.d.ts +29 -0
- package/dist/ui/components/toast-notification.js +17 -3
- package/dist/ui/components/toast-notification.js.map +1 -1
- package/dist/ui/components/welcome-panel.d.ts +1 -0
- package/dist/ui/components/welcome-panel.js +106 -4
- package/dist/ui/components/welcome-panel.js.map +1 -1
- package/dist/utils/analysis-logger.d.ts +47 -0
- package/dist/utils/analysis-logger.js +70 -0
- package/dist/utils/analysis-logger.js.map +1 -0
- package/dist/utils/automatosx-detector.d.ts +19 -0
- package/dist/utils/automatosx-detector.js +52 -0
- package/dist/utils/automatosx-detector.js.map +1 -0
- package/dist/utils/config-loader.d.ts +4 -0
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/confirmation-service.js +1 -1
- package/dist/utils/confirmation-service.js.map +1 -1
- package/dist/utils/init-previewer.js +26 -4
- package/dist/utils/init-previewer.js.map +1 -1
- package/dist/utils/setup-validator.js +1 -0
- package/dist/utils/setup-validator.js.map +1 -1
- package/dist/utils/text-utils.d.ts +1 -0
- package/dist/utils/text-utils.js +12 -0
- package/dist/utils/text-utils.js.map +1 -1
- package/package.json +19 -4
- package/vitest.config.ts +1 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server Health Monitoring
|
|
3
|
+
*
|
|
4
|
+
* Provides health checking, status monitoring, and automatic reconnection
|
|
5
|
+
* for MCP servers.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
import { ReconnectionManager } from './reconnection.js';
|
|
9
|
+
/**
|
|
10
|
+
* MCP Health Monitor
|
|
11
|
+
*
|
|
12
|
+
* Monitors the health of MCP servers and provides automatic reconnection
|
|
13
|
+
*/
|
|
14
|
+
export class MCPHealthMonitor extends EventEmitter {
|
|
15
|
+
mcpManager;
|
|
16
|
+
healthCheckInterval = null;
|
|
17
|
+
reconnectionManager;
|
|
18
|
+
serverStats = new Map();
|
|
19
|
+
constructor(mcpManager, reconnectionStrategy) {
|
|
20
|
+
super();
|
|
21
|
+
this.mcpManager = mcpManager;
|
|
22
|
+
this.reconnectionManager = new ReconnectionManager(reconnectionStrategy);
|
|
23
|
+
// Forward reconnection events
|
|
24
|
+
this.reconnectionManager.on('reconnection-scheduled', (data) => this.emit('reconnection-scheduled', data));
|
|
25
|
+
this.reconnectionManager.on('reconnection-attempt', (data) => this.emit('reconnection-attempt', data));
|
|
26
|
+
this.reconnectionManager.on('reconnection-success', (data) => this.emit('reconnection-success', data));
|
|
27
|
+
this.reconnectionManager.on('reconnection-failed', (data) => this.emit('reconnection-failed', data));
|
|
28
|
+
this.reconnectionManager.on('max-retries-reached', (data) => this.emit('max-retries-reached', data));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Start health monitoring with specified interval
|
|
32
|
+
*/
|
|
33
|
+
start(intervalMs = 60000) {
|
|
34
|
+
if (this.healthCheckInterval) {
|
|
35
|
+
throw new Error('Health monitoring already started');
|
|
36
|
+
}
|
|
37
|
+
// Initialize stats for existing servers
|
|
38
|
+
const servers = this.mcpManager.getServers();
|
|
39
|
+
for (const serverName of servers) {
|
|
40
|
+
if (!this.serverStats.has(serverName)) {
|
|
41
|
+
this.serverStats.set(serverName, {
|
|
42
|
+
connectedAt: Date.now(),
|
|
43
|
+
successCount: 0,
|
|
44
|
+
failureCount: 0,
|
|
45
|
+
latencies: [],
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
this.healthCheckInterval = setInterval(async () => {
|
|
50
|
+
await this.performHealthChecks();
|
|
51
|
+
}, intervalMs);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Stop health monitoring
|
|
55
|
+
*/
|
|
56
|
+
stop() {
|
|
57
|
+
if (this.healthCheckInterval) {
|
|
58
|
+
clearInterval(this.healthCheckInterval);
|
|
59
|
+
this.healthCheckInterval = null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Perform health checks on all servers
|
|
64
|
+
*/
|
|
65
|
+
async performHealthChecks() {
|
|
66
|
+
const servers = this.mcpManager.getServers();
|
|
67
|
+
for (const serverName of servers) {
|
|
68
|
+
try {
|
|
69
|
+
const health = await this.checkServerHealth(serverName);
|
|
70
|
+
this.emit('health-check', health);
|
|
71
|
+
// Check if server is unhealthy
|
|
72
|
+
if (!health.connected && health.successRate < 50) {
|
|
73
|
+
this.emit('server-disconnected', serverName);
|
|
74
|
+
// Note: Automatic reconnection disabled - config not available in health monitor
|
|
75
|
+
// Reconnection should be handled externally via the reconnection manager
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
this.emit('health-check-error', { serverName, error: error });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Check health of a specific server
|
|
85
|
+
*/
|
|
86
|
+
async checkServerHealth(serverName) {
|
|
87
|
+
const tools = this.mcpManager.getTools().filter((t) => t.serverName === serverName);
|
|
88
|
+
// Initialize stats if not present
|
|
89
|
+
if (!this.serverStats.has(serverName)) {
|
|
90
|
+
this.serverStats.set(serverName, {
|
|
91
|
+
connectedAt: Date.now(),
|
|
92
|
+
successCount: 0,
|
|
93
|
+
failureCount: 0,
|
|
94
|
+
latencies: [],
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
const stats = this.serverStats.get(serverName);
|
|
98
|
+
// Calculate success rate
|
|
99
|
+
const total = stats.successCount + stats.failureCount;
|
|
100
|
+
const successRate = total > 0 ? (stats.successCount / total) * 100 : 100;
|
|
101
|
+
// Calculate latencies
|
|
102
|
+
const avgLatency = stats.latencies.length > 0
|
|
103
|
+
? stats.latencies.reduce((a, b) => a + b, 0) / stats.latencies.length
|
|
104
|
+
: undefined;
|
|
105
|
+
const p95Latency = stats.latencies.length > 0
|
|
106
|
+
? this.calculatePercentile(stats.latencies, 0.95)
|
|
107
|
+
: undefined;
|
|
108
|
+
// Calculate uptime
|
|
109
|
+
const uptime = Date.now() - stats.connectedAt;
|
|
110
|
+
return {
|
|
111
|
+
serverName,
|
|
112
|
+
connected: tools.length > 0,
|
|
113
|
+
toolCount: tools.length,
|
|
114
|
+
uptime,
|
|
115
|
+
connectedAt: stats.connectedAt,
|
|
116
|
+
lastSuccess: stats.lastSuccess,
|
|
117
|
+
lastError: stats.lastError,
|
|
118
|
+
lastErrorAt: stats.lastErrorAt,
|
|
119
|
+
successCount: stats.successCount,
|
|
120
|
+
failureCount: stats.failureCount,
|
|
121
|
+
avgLatency,
|
|
122
|
+
p95Latency,
|
|
123
|
+
successRate,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Record a successful tool call
|
|
128
|
+
*/
|
|
129
|
+
recordSuccess(serverName, latencyMs) {
|
|
130
|
+
// Initialize stats if not present
|
|
131
|
+
if (!this.serverStats.has(serverName)) {
|
|
132
|
+
this.serverStats.set(serverName, {
|
|
133
|
+
connectedAt: Date.now(),
|
|
134
|
+
successCount: 0,
|
|
135
|
+
failureCount: 0,
|
|
136
|
+
latencies: [],
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
const stats = this.serverStats.get(serverName);
|
|
140
|
+
stats.successCount++;
|
|
141
|
+
stats.lastSuccess = Date.now();
|
|
142
|
+
stats.latencies.push(latencyMs);
|
|
143
|
+
// Keep only last 100 latencies
|
|
144
|
+
if (stats.latencies.length > 100) {
|
|
145
|
+
stats.latencies.shift();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Record a failed tool call
|
|
150
|
+
*/
|
|
151
|
+
recordFailure(serverName, error) {
|
|
152
|
+
// Initialize stats if not present
|
|
153
|
+
if (!this.serverStats.has(serverName)) {
|
|
154
|
+
this.serverStats.set(serverName, {
|
|
155
|
+
connectedAt: Date.now(),
|
|
156
|
+
successCount: 0,
|
|
157
|
+
failureCount: 0,
|
|
158
|
+
latencies: [],
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
const stats = this.serverStats.get(serverName);
|
|
162
|
+
stats.failureCount++;
|
|
163
|
+
stats.lastError = error;
|
|
164
|
+
stats.lastErrorAt = Date.now();
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Attempt to reconnect to a disconnected server
|
|
168
|
+
*
|
|
169
|
+
* NOTE: This method is currently not used because the health monitor
|
|
170
|
+
* doesn't have access to server configs. Reconnection should be handled
|
|
171
|
+
* externally by listening to 'server-disconnected' events.
|
|
172
|
+
*/
|
|
173
|
+
/* private async attemptReconnection(serverName: string, config: any): Promise<void> {
|
|
174
|
+
// Only schedule if not already reconnecting
|
|
175
|
+
if (this.reconnectionManager.isReconnecting(serverName)) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
await this.reconnectionManager.scheduleReconnection(
|
|
180
|
+
serverName,
|
|
181
|
+
config,
|
|
182
|
+
async (cfg) => {
|
|
183
|
+
await this.mcpManager.addServer(cfg);
|
|
184
|
+
}
|
|
185
|
+
);
|
|
186
|
+
} */
|
|
187
|
+
/**
|
|
188
|
+
* Get reconnection manager
|
|
189
|
+
*/
|
|
190
|
+
getReconnectionManager() {
|
|
191
|
+
return this.reconnectionManager;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Calculate percentile from array of values
|
|
195
|
+
*/
|
|
196
|
+
calculatePercentile(values, percentile) {
|
|
197
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
198
|
+
const index = Math.ceil(sorted.length * percentile) - 1;
|
|
199
|
+
return sorted[index] || 0;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Get health report for all servers
|
|
203
|
+
*/
|
|
204
|
+
async getHealthReport() {
|
|
205
|
+
const servers = this.mcpManager.getServers();
|
|
206
|
+
const report = [];
|
|
207
|
+
for (const serverName of servers) {
|
|
208
|
+
const health = await this.checkServerHealth(serverName);
|
|
209
|
+
report.push(health);
|
|
210
|
+
}
|
|
211
|
+
return report;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Get health status for a specific server
|
|
215
|
+
*/
|
|
216
|
+
async getServerStatus(serverName) {
|
|
217
|
+
const servers = this.mcpManager.getServers();
|
|
218
|
+
if (!servers.includes(serverName)) {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
return await this.checkServerHealth(serverName);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Reset stats for a server
|
|
225
|
+
*/
|
|
226
|
+
resetStats(serverName) {
|
|
227
|
+
this.serverStats.set(serverName, {
|
|
228
|
+
connectedAt: Date.now(),
|
|
229
|
+
successCount: 0,
|
|
230
|
+
failureCount: 0,
|
|
231
|
+
latencies: [],
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Get formatted uptime string
|
|
236
|
+
*/
|
|
237
|
+
static formatUptime(uptimeMs) {
|
|
238
|
+
const seconds = Math.floor(uptimeMs / 1000);
|
|
239
|
+
const minutes = Math.floor(seconds / 60);
|
|
240
|
+
const hours = Math.floor(minutes / 60);
|
|
241
|
+
const days = Math.floor(hours / 24);
|
|
242
|
+
if (days > 0) {
|
|
243
|
+
return `${days}d ${hours % 24}h`;
|
|
244
|
+
}
|
|
245
|
+
else if (hours > 0) {
|
|
246
|
+
return `${hours}h ${minutes % 60}m`;
|
|
247
|
+
}
|
|
248
|
+
else if (minutes > 0) {
|
|
249
|
+
return `${minutes}m ${seconds % 60}s`;
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
return `${seconds}s`;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Get formatted latency string
|
|
257
|
+
*/
|
|
258
|
+
static formatLatency(latencyMs) {
|
|
259
|
+
if (latencyMs < 1000) {
|
|
260
|
+
return `${Math.round(latencyMs)}ms`;
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
return `${(latencyMs / 1000).toFixed(2)}s`;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/mcp/health.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server Automatic Reconnection (Phase 5)
|
|
3
|
+
*
|
|
4
|
+
* Provides intelligent retry logic with exponential backoff for failed MCP connections
|
|
5
|
+
* Ensures production reliability without overwhelming servers
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
import type { MCPServerConfig } from '../schemas/settings-schemas.js';
|
|
9
|
+
export interface ReconnectionStrategy {
|
|
10
|
+
/** Maximum number of retry attempts */
|
|
11
|
+
maxRetries: number;
|
|
12
|
+
/** Initial delay in milliseconds */
|
|
13
|
+
baseDelayMs: number;
|
|
14
|
+
/** Maximum delay in milliseconds */
|
|
15
|
+
maxDelayMs: number;
|
|
16
|
+
/** Backoff multiplier (2 = double each time) */
|
|
17
|
+
backoffMultiplier: number;
|
|
18
|
+
/** Add random jitter to prevent thundering herd */
|
|
19
|
+
jitter: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare const DEFAULT_STRATEGY: ReconnectionStrategy;
|
|
22
|
+
export interface ReconnectionState {
|
|
23
|
+
serverName: string;
|
|
24
|
+
attempts: number;
|
|
25
|
+
lastAttempt: number;
|
|
26
|
+
nextAttempt: number | null;
|
|
27
|
+
status: 'idle' | 'scheduled' | 'connecting' | 'failed' | 'connected';
|
|
28
|
+
lastError?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Reconnection Manager
|
|
32
|
+
*
|
|
33
|
+
* Manages automatic reconnection attempts with exponential backoff
|
|
34
|
+
*/
|
|
35
|
+
export declare class ReconnectionManager extends EventEmitter {
|
|
36
|
+
private retryAttempts;
|
|
37
|
+
private reconnectTimers;
|
|
38
|
+
private reconnectionState;
|
|
39
|
+
private strategy;
|
|
40
|
+
constructor(strategy?: ReconnectionStrategy);
|
|
41
|
+
/**
|
|
42
|
+
* Schedule reconnection for a server
|
|
43
|
+
*/
|
|
44
|
+
scheduleReconnection(serverName: string, config: MCPServerConfig, reconnectFn: (config: MCPServerConfig) => Promise<void>): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Calculate delay for next attempt with exponential backoff
|
|
47
|
+
*/
|
|
48
|
+
private calculateDelay;
|
|
49
|
+
/**
|
|
50
|
+
* Cancel reconnection attempts for a server
|
|
51
|
+
*/
|
|
52
|
+
cancelReconnection(serverName: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* Cancel all reconnection attempts
|
|
55
|
+
*/
|
|
56
|
+
cancelAll(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Reset retry counter for a server
|
|
59
|
+
*/
|
|
60
|
+
resetRetries(serverName: string): void;
|
|
61
|
+
/**
|
|
62
|
+
* Get reconnection state for a server
|
|
63
|
+
*/
|
|
64
|
+
getState(serverName: string): ReconnectionState | null;
|
|
65
|
+
/**
|
|
66
|
+
* Get all reconnection states
|
|
67
|
+
*/
|
|
68
|
+
getAllStates(): ReconnectionState[];
|
|
69
|
+
/**
|
|
70
|
+
* Update reconnection state
|
|
71
|
+
*/
|
|
72
|
+
private updateState;
|
|
73
|
+
/**
|
|
74
|
+
* Get number of active reconnection attempts
|
|
75
|
+
*/
|
|
76
|
+
getActiveReconnections(): number;
|
|
77
|
+
/**
|
|
78
|
+
* Check if server is currently attempting to reconnect
|
|
79
|
+
*/
|
|
80
|
+
isReconnecting(serverName: string): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Format time until next reconnection attempt
|
|
83
|
+
*/
|
|
84
|
+
static formatNextAttempt(nextAttemptMs: number): string;
|
|
85
|
+
/**
|
|
86
|
+
* Get strategy configuration
|
|
87
|
+
*/
|
|
88
|
+
getStrategy(): ReconnectionStrategy;
|
|
89
|
+
/**
|
|
90
|
+
* Update strategy configuration
|
|
91
|
+
*/
|
|
92
|
+
setStrategy(strategy: Partial<ReconnectionStrategy>): void;
|
|
93
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server Automatic Reconnection (Phase 5)
|
|
3
|
+
*
|
|
4
|
+
* Provides intelligent retry logic with exponential backoff for failed MCP connections
|
|
5
|
+
* Ensures production reliability without overwhelming servers
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
export const DEFAULT_STRATEGY = {
|
|
9
|
+
maxRetries: 5,
|
|
10
|
+
baseDelayMs: 1000, // Start at 1 second
|
|
11
|
+
maxDelayMs: 30000, // Cap at 30 seconds
|
|
12
|
+
backoffMultiplier: 2, // Double each time: 1s, 2s, 4s, 8s, 16s, 30s
|
|
13
|
+
jitter: true // Add randomness
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Reconnection Manager
|
|
17
|
+
*
|
|
18
|
+
* Manages automatic reconnection attempts with exponential backoff
|
|
19
|
+
*/
|
|
20
|
+
export class ReconnectionManager extends EventEmitter {
|
|
21
|
+
retryAttempts = new Map();
|
|
22
|
+
reconnectTimers = new Map();
|
|
23
|
+
reconnectionState = new Map();
|
|
24
|
+
strategy;
|
|
25
|
+
constructor(strategy = DEFAULT_STRATEGY) {
|
|
26
|
+
super();
|
|
27
|
+
this.strategy = strategy;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Schedule reconnection for a server
|
|
31
|
+
*/
|
|
32
|
+
async scheduleReconnection(serverName, config, reconnectFn) {
|
|
33
|
+
const attempts = this.retryAttempts.get(serverName) || 0;
|
|
34
|
+
if (attempts >= this.strategy.maxRetries) {
|
|
35
|
+
this.updateState(serverName, {
|
|
36
|
+
serverName,
|
|
37
|
+
attempts,
|
|
38
|
+
lastAttempt: Date.now(),
|
|
39
|
+
nextAttempt: null,
|
|
40
|
+
status: 'failed',
|
|
41
|
+
lastError: 'Max reconnection attempts reached'
|
|
42
|
+
});
|
|
43
|
+
this.emit('max-retries-reached', {
|
|
44
|
+
serverName,
|
|
45
|
+
attempts,
|
|
46
|
+
config
|
|
47
|
+
});
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const delay = this.calculateDelay(attempts);
|
|
51
|
+
this.updateState(serverName, {
|
|
52
|
+
serverName,
|
|
53
|
+
attempts,
|
|
54
|
+
lastAttempt: Date.now(),
|
|
55
|
+
nextAttempt: Date.now() + delay,
|
|
56
|
+
status: 'scheduled'
|
|
57
|
+
});
|
|
58
|
+
this.emit('reconnection-scheduled', {
|
|
59
|
+
serverName,
|
|
60
|
+
attempt: attempts + 1,
|
|
61
|
+
maxAttempts: this.strategy.maxRetries,
|
|
62
|
+
delayMs: delay
|
|
63
|
+
});
|
|
64
|
+
const timer = setTimeout(async () => {
|
|
65
|
+
this.updateState(serverName, {
|
|
66
|
+
serverName,
|
|
67
|
+
attempts: attempts + 1,
|
|
68
|
+
lastAttempt: Date.now(),
|
|
69
|
+
nextAttempt: null,
|
|
70
|
+
status: 'connecting'
|
|
71
|
+
});
|
|
72
|
+
this.emit('reconnection-attempt', {
|
|
73
|
+
serverName,
|
|
74
|
+
attempt: attempts + 1,
|
|
75
|
+
maxAttempts: this.strategy.maxRetries
|
|
76
|
+
});
|
|
77
|
+
try {
|
|
78
|
+
await reconnectFn(config);
|
|
79
|
+
// Success - reset attempts
|
|
80
|
+
this.retryAttempts.set(serverName, 0);
|
|
81
|
+
this.updateState(serverName, {
|
|
82
|
+
serverName,
|
|
83
|
+
attempts: 0,
|
|
84
|
+
lastAttempt: Date.now(),
|
|
85
|
+
nextAttempt: null,
|
|
86
|
+
status: 'connected'
|
|
87
|
+
});
|
|
88
|
+
this.emit('reconnection-success', {
|
|
89
|
+
serverName,
|
|
90
|
+
totalAttempts: attempts + 1
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
// Failure - schedule next attempt
|
|
95
|
+
this.retryAttempts.set(serverName, attempts + 1);
|
|
96
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
97
|
+
this.updateState(serverName, {
|
|
98
|
+
serverName,
|
|
99
|
+
attempts: attempts + 1,
|
|
100
|
+
lastAttempt: Date.now(),
|
|
101
|
+
nextAttempt: null,
|
|
102
|
+
status: 'idle',
|
|
103
|
+
lastError: errorMessage
|
|
104
|
+
});
|
|
105
|
+
this.emit('reconnection-failed', {
|
|
106
|
+
serverName,
|
|
107
|
+
attempt: attempts + 1,
|
|
108
|
+
maxAttempts: this.strategy.maxRetries,
|
|
109
|
+
error: errorMessage
|
|
110
|
+
});
|
|
111
|
+
// Schedule next attempt
|
|
112
|
+
await this.scheduleReconnection(serverName, config, reconnectFn);
|
|
113
|
+
}
|
|
114
|
+
}, delay);
|
|
115
|
+
this.reconnectTimers.set(serverName, timer);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Calculate delay for next attempt with exponential backoff
|
|
119
|
+
*/
|
|
120
|
+
calculateDelay(attempts) {
|
|
121
|
+
let delay = this.strategy.baseDelayMs * Math.pow(this.strategy.backoffMultiplier, attempts);
|
|
122
|
+
// Cap at max delay
|
|
123
|
+
delay = Math.min(delay, this.strategy.maxDelayMs);
|
|
124
|
+
// Add jitter if enabled (±25% randomness)
|
|
125
|
+
if (this.strategy.jitter) {
|
|
126
|
+
const jitterRange = delay * 0.25;
|
|
127
|
+
const jitter = (Math.random() * 2 - 1) * jitterRange;
|
|
128
|
+
delay += jitter;
|
|
129
|
+
}
|
|
130
|
+
return Math.max(delay, 0);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Cancel reconnection attempts for a server
|
|
134
|
+
*/
|
|
135
|
+
cancelReconnection(serverName) {
|
|
136
|
+
const timer = this.reconnectTimers.get(serverName);
|
|
137
|
+
if (timer) {
|
|
138
|
+
clearTimeout(timer);
|
|
139
|
+
this.reconnectTimers.delete(serverName);
|
|
140
|
+
}
|
|
141
|
+
this.retryAttempts.delete(serverName);
|
|
142
|
+
this.reconnectionState.delete(serverName);
|
|
143
|
+
this.emit('reconnection-cancelled', { serverName });
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Cancel all reconnection attempts
|
|
147
|
+
*/
|
|
148
|
+
cancelAll() {
|
|
149
|
+
for (const serverName of this.reconnectTimers.keys()) {
|
|
150
|
+
this.cancelReconnection(serverName);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Reset retry counter for a server
|
|
155
|
+
*/
|
|
156
|
+
resetRetries(serverName) {
|
|
157
|
+
this.retryAttempts.set(serverName, 0);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get reconnection state for a server
|
|
161
|
+
*/
|
|
162
|
+
getState(serverName) {
|
|
163
|
+
return this.reconnectionState.get(serverName) || null;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get all reconnection states
|
|
167
|
+
*/
|
|
168
|
+
getAllStates() {
|
|
169
|
+
return Array.from(this.reconnectionState.values());
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Update reconnection state
|
|
173
|
+
*/
|
|
174
|
+
updateState(serverName, state) {
|
|
175
|
+
this.reconnectionState.set(serverName, state);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Get number of active reconnection attempts
|
|
179
|
+
*/
|
|
180
|
+
getActiveReconnections() {
|
|
181
|
+
return this.reconnectTimers.size;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Check if server is currently attempting to reconnect
|
|
185
|
+
*/
|
|
186
|
+
isReconnecting(serverName) {
|
|
187
|
+
const state = this.getState(serverName);
|
|
188
|
+
return state?.status === 'scheduled' || state?.status === 'connecting';
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Format time until next reconnection attempt
|
|
192
|
+
*/
|
|
193
|
+
static formatNextAttempt(nextAttemptMs) {
|
|
194
|
+
const diff = nextAttemptMs - Date.now();
|
|
195
|
+
if (diff <= 0)
|
|
196
|
+
return 'now';
|
|
197
|
+
const seconds = Math.floor(diff / 1000);
|
|
198
|
+
if (seconds < 60)
|
|
199
|
+
return `${seconds}s`;
|
|
200
|
+
const minutes = Math.floor(seconds / 60);
|
|
201
|
+
return `${minutes}m ${seconds % 60}s`;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Get strategy configuration
|
|
205
|
+
*/
|
|
206
|
+
getStrategy() {
|
|
207
|
+
return { ...this.strategy };
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Update strategy configuration
|
|
211
|
+
*/
|
|
212
|
+
setStrategy(strategy) {
|
|
213
|
+
this.strategy = { ...this.strategy, ...strategy };
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=reconnection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconnection.js","sourceRoot":"","sources":["../../src/mcp/reconnection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server Registry Integration (Phase 5)
|
|
3
|
+
*
|
|
4
|
+
* Enables discovery and installation of MCP servers from the GitHub MCP Registry
|
|
5
|
+
* Provides one-command install and browsing capabilities
|
|
6
|
+
*/
|
|
7
|
+
import type { MCPServerConfig } from '../schemas/settings-schemas.js';
|
|
8
|
+
export interface RegistryServer {
|
|
9
|
+
/** Server name/identifier */
|
|
10
|
+
name: string;
|
|
11
|
+
/** Human-readable display name */
|
|
12
|
+
displayName: string;
|
|
13
|
+
/** Server description */
|
|
14
|
+
description: string;
|
|
15
|
+
/** GitHub repository URL */
|
|
16
|
+
repository: string;
|
|
17
|
+
/** GitHub stars count */
|
|
18
|
+
stars: number;
|
|
19
|
+
/** Server category (design, deployment, database, etc.) */
|
|
20
|
+
category: string;
|
|
21
|
+
/** Transport type */
|
|
22
|
+
transport: 'stdio' | 'http' | 'sse';
|
|
23
|
+
/** NPM package name (for stdio servers) */
|
|
24
|
+
packageName?: string;
|
|
25
|
+
/** Install command */
|
|
26
|
+
installCommand: string;
|
|
27
|
+
/** Whether this is an official/verified server */
|
|
28
|
+
verified: boolean;
|
|
29
|
+
/** Author/organization */
|
|
30
|
+
author: string;
|
|
31
|
+
/** Latest version */
|
|
32
|
+
version?: string;
|
|
33
|
+
/** Homepage URL */
|
|
34
|
+
homepage?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface RegistrySearchOptions {
|
|
37
|
+
/** Search query */
|
|
38
|
+
query?: string;
|
|
39
|
+
/** Filter by category */
|
|
40
|
+
category?: string;
|
|
41
|
+
/** Filter by transport type */
|
|
42
|
+
transport?: 'stdio' | 'http' | 'sse';
|
|
43
|
+
/** Sort by (stars, name, updated) */
|
|
44
|
+
sortBy?: 'stars' | 'name' | 'updated';
|
|
45
|
+
/** Max results to return */
|
|
46
|
+
limit?: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Search the MCP server registry
|
|
50
|
+
*/
|
|
51
|
+
export declare function searchRegistry(options?: RegistrySearchOptions): Promise<RegistryServer[]>;
|
|
52
|
+
/**
|
|
53
|
+
* Get details for a specific server from the registry
|
|
54
|
+
*/
|
|
55
|
+
export declare function getRegistryServer(nameOrPackage: string): Promise<RegistryServer | null>;
|
|
56
|
+
/**
|
|
57
|
+
* Get popular/featured MCP servers
|
|
58
|
+
*/
|
|
59
|
+
export declare function getPopularServers(): Promise<RegistryServer[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Get servers by category
|
|
62
|
+
*/
|
|
63
|
+
export declare function getServersByCategory(category: string): Promise<RegistryServer[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Generate MCP server configuration from registry entry
|
|
66
|
+
*/
|
|
67
|
+
export declare function generateConfigFromRegistry(server: RegistryServer): MCPServerConfig;
|
|
68
|
+
/**
|
|
69
|
+
* Format registry server for display
|
|
70
|
+
*/
|
|
71
|
+
export declare function formatRegistryServer(server: RegistryServer, compact?: boolean): string;
|