claude-computer-use-mcp
Version:
MCP server providing browser automation capabilities to Claude Code
164 lines • 5.82 kB
JavaScript
import * as http from 'http';
import { monitoring } from './monitoring.js';
export class EnterpriseManager {
config;
browserController;
healthServer;
metricsServer;
startTime;
requestCount = 0;
errorCount = 0;
lastCpuUsage = process.cpuUsage();
constructor(config, browserController) {
this.config = config;
this.browserController = browserController;
this.startTime = Date.now();
if (config.enableHealthChecks) {
this.startHealthServer();
}
if (config.enableMetrics) {
// this.startMetricsServer(); // TODO: Implement metrics server
}
// Start periodic health checks
setInterval(() => this.performHealthCheck(), 30000); // Every 30 seconds
}
async startHealthServer() {
this.healthServer = http.createServer(async (req, res) => {
const url = new URL(req.url, `http://${req.headers.host}`);
// CORS headers
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
if (req.method === 'OPTIONS') {
res.writeHead(200);
res.end();
return;
}
try {
if (url.pathname === '/health') {
const health = await this.getHealthStatus();
res.setHeader('Content-Type', 'application/json');
res.writeHead(health.status === 'healthy' ? 200 : 503);
res.end(JSON.stringify(health, null, 2));
}
else if (url.pathname === '/health/ready') {
// Readiness probe
const ready = await this.isReady();
res.writeHead(ready ? 200 : 503);
res.end(ready ? 'Ready' : 'Not Ready');
}
else if (url.pathname === '/health/live') {
// Liveness probe
const live = await this.isLive();
res.writeHead(live ? 200 : 503);
res.end(live ? 'Live' : 'Not Live');
}
else {
res.writeHead(404);
res.end('Not Found');
}
}
catch (error) {
res.writeHead(500);
res.end(`Internal Server Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
});
this.healthServer.listen(this.config.healthCheckPort, () => {
console.log(`Health check server listening on port ${this.config.healthCheckPort}`);
});
}
async getHealthStatus() {
const checks = {};
let overallStatus = 'healthy';
// Check browser controller
try {
const sessions = await this.browserController.listSessions();
checks.browser_controller = {
status: 'pass',
message: `${sessions.length} active sessions`
};
}
catch (error) {
checks.browser_controller = {
status: 'fail',
message: error instanceof Error ? error.message : 'Unknown error'
};
overallStatus = 'unhealthy';
}
// Check memory usage
const memUsage = process.memoryUsage();
const memUsageMB = memUsage.heapUsed / 1024 / 1024;
if (memUsageMB > 1000) { // Over 1GB
checks.memory = {
status: 'warn',
message: `High memory usage: ${memUsageMB.toFixed(2)}MB`
};
if (overallStatus === 'healthy')
overallStatus = 'degraded';
}
else {
checks.memory = {
status: 'pass',
message: `Memory usage: ${memUsageMB.toFixed(2)}MB`
};
}
return {
status: overallStatus,
timestamp: Date.now(),
uptime: Date.now() - this.startTime,
version: '1.2.0',
checks,
metadata: {
activeSessions: (await this.browserController.listSessions()).length,
totalRequests: this.requestCount,
memoryUsage: process.memoryUsage(),
cpuUsage: this.getCpuUsage()
}
};
}
async isReady() {
try {
await this.browserController.listSessions();
return true;
}
catch (error) {
return false;
}
}
async isLive() {
return true;
}
getCpuUsage() {
const currentUsage = process.cpuUsage(this.lastCpuUsage);
this.lastCpuUsage = process.cpuUsage();
const totalTime = currentUsage.user + currentUsage.system;
return (totalTime / 1000000) * 100;
}
async performHealthCheck() {
const health = await this.getHealthStatus();
monitoring.auditLog({
level: health.status === 'healthy' ? 'info' : 'warn',
action: 'health_check',
details: {
status: health.status,
activeSessions: health.metadata.activeSessions,
memoryUsageMB: (health.metadata.memoryUsage.heapUsed / 1024 / 1024).toFixed(2)
}
});
}
incrementRequestCount() {
this.requestCount++;
}
incrementErrorCount() {
this.errorCount++;
}
async cleanup() {
if (this.healthServer) {
this.healthServer.close();
}
if (this.metricsServer) {
this.metricsServer.close();
}
}
}
//# sourceMappingURL=enterprise.js.map