firewalla-mcp-server
Version:
Model Context Protocol (MCP) server for Firewalla MSP API - Provides real-time network monitoring, security analysis, and firewall management through 28 specialized tools compatible with any MCP client
218 lines (213 loc) • 8.79 kB
JavaScript
import { logger } from '../monitoring/logger';
import { metrics } from '../monitoring/metrics';
import { getCurrentTimestamp } from '../utils/timestamp.js';
export class DebugTools {
constructor(firewalla, healthCheck) {
this.firewalla = firewalla;
this.healthCheck = healthCheck;
this.startTime = Date.now();
}
async getDebugInfo() {
const memUsage = process.memoryUsage();
const cacheStats = this.firewalla.getCacheStats();
const allMetrics = metrics.snapshot();
const health = await this.healthCheck.performHealthCheck();
return {
timestamp: getCurrentTimestamp(),
version: '1.0.0',
environment: process.env.NODE_ENV ?? 'development',
uptime: Math.floor((Date.now() - this.startTime) / 1000),
memory: {
used: Math.round(memUsage.heapUsed / 1024 / 1024),
total: Math.round(memUsage.heapTotal / 1024 / 1024),
usage_percent: Math.round((memUsage.heapUsed / memUsage.heapTotal) * 100),
},
cache: {
size: cacheStats.size,
keys: cacheStats.keys.slice(0, 10), // Show first 10 keys
},
metrics: {
total_metrics: Object.keys(allMetrics.counters).length +
Object.keys(allMetrics.timings).length,
counters: allMetrics.counters,
timings: Object.fromEntries(Object.entries(allMetrics.timings)
.sort(([, a], [, b]) => {
// Sort by count (most frequently called operations are most relevant)
return b.count - a.count;
})
.slice(0, 5)),
},
health,
};
}
async testFirewallaConnection() {
const startTime = Date.now();
try {
const summary = await this.firewalla.getFirewallSummary();
const responseTime = Date.now() - startTime;
return {
success: true,
response_time: responseTime,
data: {
status: summary.status,
uptime: summary.uptime,
cpu_usage: summary.cpu_usage,
memory_usage: summary.memory_usage,
active_connections: summary.active_connections || 0,
blocked_attempts: summary.blocked_attempts || 0,
last_updated: summary.last_updated || new Date().toISOString(),
},
};
}
catch (error) {
const responseTime = Date.now() - startTime;
return {
success: false,
response_time: responseTime,
error: error instanceof Error ? error.message : 'Unknown error',
};
}
}
async simulateLoad(requests = 10, delay = 100) {
logger.info('Starting load simulation', { requests, delay });
const results = [];
const promises = Array.from({ length: requests }, async (_, index) => {
if (delay > 0) {
await new Promise(resolve => setTimeout(resolve, index * delay));
}
const startTime = Date.now();
try {
await this.firewalla.getFirewallSummary();
const responseTime = Date.now() - startTime;
results.push({ success: true, responseTime });
}
catch (error) {
const responseTime = Date.now() - startTime;
results.push({ success: false, responseTime });
logger.error('Load simulation request failed', error);
}
});
await Promise.all(promises);
const successful = results.filter(r => r.success);
const failed = results.filter(r => !r.success);
const responseTimes = results.map(r => r.responseTime);
const summary = {
total_requests: requests,
successful_requests: successful.length,
failed_requests: failed.length,
average_response_time: responseTimes.reduce((a, b) => a + b, 0) / responseTimes.length,
min_response_time: Math.min(...responseTimes),
max_response_time: Math.max(...responseTimes),
};
logger.info('Load simulation completed', summary);
return summary;
}
clearCache() {
const stats = this.firewalla.getCacheStats();
const clearedEntries = stats.size;
this.firewalla.clearCache();
logger.info('Cache cleared', { cleared_entries: clearedEntries });
return { cleared_entries: clearedEntries };
}
clearMetrics() {
const allMetrics = metrics.snapshot();
const clearedMetrics = Object.keys(allMetrics.counters).length +
Object.keys(allMetrics.timings).length;
metrics.clear();
logger.info('Metrics cleared', { cleared_metrics: clearedMetrics });
return { cleared_metrics: clearedMetrics };
}
async validateConfiguration() {
const issues = [];
// Check environment variables
const requiredVars = ['FIREWALLA_MSP_TOKEN', 'FIREWALLA_BOX_ID'];
for (const varName of requiredVars) {
if (process.env[varName] === undefined ||
process.env[varName] === null ||
process.env[varName] === '') {
issues.push({
level: 'error',
message: `Missing required environment variable: ${varName}`,
});
}
}
// Check API connectivity
try {
await this.testFirewallaConnection();
}
catch (error) {
issues.push({
level: 'error',
message: `Cannot connect to Firewalla API: ${error instanceof Error ? error.message : 'Unknown error'}`,
});
}
// Check memory usage
const memUsage = process.memoryUsage();
const heapUsageMB = memUsage.heapUsed / 1024 / 1024;
if (heapUsageMB > 512) {
issues.push({
level: 'warning',
message: `High memory usage: ${Math.round(heapUsageMB)}MB`,
});
}
// Check cache size
const cacheStats = this.firewalla.getCacheStats();
if (cacheStats.size > 1000) {
issues.push({
level: 'warning',
message: `Large cache size: ${cacheStats.size} entries`,
});
}
return {
valid: issues.filter(i => i.level === 'error').length === 0,
issues,
};
}
generateSystemReport() {
const memUsage = process.memoryUsage();
const cacheStats = this.firewalla.getCacheStats();
const uptime = Math.floor((Date.now() - this.startTime) / 1000);
return `
Firewalla MCP Server System Report
Generated: ${getCurrentTimestamp()}
Environment Information:
- Node.js Version: ${process.version}
- Platform: ${process.platform}
- Architecture: ${process.arch}
- Environment: ${process.env.NODE_ENV ?? 'development'}
- Uptime: ${uptime} seconds
Memory Usage:
- Heap Used: ${Math.round(memUsage.heapUsed / 1024 / 1024)} MB
- Heap Total: ${Math.round(memUsage.heapTotal / 1024 / 1024)} MB
- External: ${Math.round(memUsage.external / 1024 / 1024)} MB
- RSS: ${Math.round(memUsage.rss / 1024 / 1024)} MB
Cache Information:
- Cache Size: ${cacheStats.size} entries
- Sample Keys: ${cacheStats.keys.slice(0, 5).join(', ')}
Configuration:
- MSP Token: ${process.env.FIREWALLA_MSP_TOKEN !== undefined && process.env.FIREWALLA_MSP_TOKEN !== null && process.env.FIREWALLA_MSP_TOKEN !== '' ? 'Set' : 'Missing'}
- Box ID: ${process.env.FIREWALLA_BOX_ID !== undefined && process.env.FIREWALLA_BOX_ID !== null && process.env.FIREWALLA_BOX_ID !== '' ? 'Set' : 'Missing'}
- Base URL: ${process.env.FIREWALLA_MSP_BASE_URL ?? 'Default'}
- Log Level: ${process.env.LOG_LEVEL ?? 'Default'}
Recent Activity:
- Use 'npm run mcp:debug' for detailed logging
- Check logs directory for historical data
`.trim();
}
enableVerboseLogging() {
logger.info('Enabling verbose logging mode');
// This would typically update the logger configuration
process.env.DEBUG = 'mcp:*';
process.env.LOG_LEVEL = 'debug';
}
disableVerboseLogging() {
logger.info('Disabling verbose logging mode');
delete process.env.DEBUG;
process.env.LOG_LEVEL = 'info';
}
}
// Export a function to create debug tools
export function createDebugTools(firewalla, healthCheck) {
return new DebugTools(firewalla, healthCheck);
}
//# sourceMappingURL=tools.js.map