@ooples/token-optimizer-mcp
Version:
Intelligent context window optimization for Claude Code - store content externally via caching and compression, freeing up your context window for what matters
646 lines ⢠22.1 kB
JavaScript
/**
* Smart Network Tool - Network Diagnostics and Monitoring
*
* Provides intelligent network analysis with:
* - Connectivity testing
* - Latency measurement
* - Port scanning
* - DNS resolution
* - Token-optimized output
*/
import { spawn } from 'child_process';
import { CacheEngine } from '../../core/cache-engine.js';
import { createHash } from 'crypto';
import { homedir } from 'os';
import { join } from 'path';
import * as dns from 'dns';
import * as net from 'net';
import { promisify } from 'util';
const dnsLookup = promisify(dns.lookup);
export class SmartNetwork {
cache;
cacheNamespace = 'smart_network';
constructor(cache, _projectRoot) {
this.cache = cache;
}
/**
* Run network diagnostics
*/
async run(options) {
const { operation, hosts = ['8.8.8.8', 'google.com'], ports = [80, 443], hostnames = ['google.com', 'github.com'], pingCount = 4, timeout = 5000, maxCacheAge = 300, } = options;
const startTime = Date.now();
// Generate cache key
const cacheKey = this.generateCacheKey(operation, hosts, ports, hostnames);
// Check cache first
const cached = this.getCachedResult(cacheKey, maxCacheAge);
if (cached) {
return this.formatCachedOutput(cached);
}
// Run network operation
const result = await this.runNetworkOperation({
operation,
hosts,
ports,
hostnames,
pingCount,
timeout,
});
const duration = Date.now() - startTime;
result.duration = duration;
// Cache the result
this.cacheResult(cacheKey, result);
// Generate diagnostics and recommendations
const diagnostics = this.generateDiagnostics(result);
const recommendations = this.generateRecommendations(result);
// Transform to smart output
return this.transformOutput(result, diagnostics, recommendations);
}
/**
* Run network operation
*/
async runNetworkOperation(options) {
const { operation, hosts, ports, hostnames, pingCount, timeout } = options;
const result = {
success: true,
connectivity: [],
duration: 0,
timestamp: Date.now(),
};
// Connectivity checks
if (operation === 'ping' || operation === 'all') {
result.connectivity = await this.pingHosts(hosts, pingCount, timeout);
result.latencyStats = this.calculateLatencyStats(result.connectivity);
}
// Port scanning
if (operation === 'port-scan' || operation === 'all') {
result.ports = await this.scanPorts(hosts, ports, timeout);
}
// DNS resolution
if (operation === 'dns' || operation === 'all') {
result.dns = await this.resolveDns(hostnames);
}
// Traceroute
if (operation === 'traceroute') {
// Traceroute is complex and platform-specific, simplified for now
result.connectivity = await this.pingHosts(hosts, 1, timeout);
}
return result;
}
/**
* Ping hosts
*/
async pingHosts(hosts, count, timeout) {
const results = [];
for (const host of hosts) {
const result = await this.pingHost(host, count, timeout);
results.push(result);
}
return results;
}
/**
* Ping a single host
*/
async pingHost(host, count, timeout) {
return new Promise((resolve) => {
let output = '';
// Platform-specific ping command
const isWindows = process.platform === 'win32';
const command = isWindows ? 'ping' : 'ping';
const args = isWindows
? ['-n', count.toString(), '-w', timeout.toString(), host]
: ['-c', count.toString(), '-W', (timeout / 1000).toString(), host];
const child = spawn(command, args, { shell: true });
child.stdout.on('data', (data) => {
output += data.toString();
});
child.on('close', (code) => {
if (code === 0) {
const latency = this.parsePingLatency(output);
resolve({
host,
reachable: true,
latency,
});
}
else {
resolve({
host,
reachable: false,
error: 'Host unreachable',
});
}
});
child.on('error', (err) => {
resolve({
host,
reachable: false,
error: err.message,
});
});
});
}
/**
* Parse ping latency from output
*/
parsePingLatency(output) {
// Windows: Average = XXXms
const windowsMatch = output.match(/Average\s*=\s*(\d+)ms/);
if (windowsMatch) {
return parseInt(windowsMatch[1], 10);
}
// Unix: rtt min/avg/max/mdev = X.X/Y.Y/Z.Z/W.W ms
const unixMatch = output.match(/rtt[^=]*=\s*[\d.]+\/([\d.]+)\/([\d.]+)\/([\d.]+)/);
if (unixMatch) {
return parseFloat(unixMatch[2]); // avg
}
return 0;
}
/**
* Scan ports on hosts
*/
async scanPorts(hosts, ports, timeout) {
const results = [];
for (const host of hosts) {
for (const port of ports) {
const result = await this.checkPort(host, port, timeout);
results.push(result);
}
}
return results;
}
/**
* Check if a port is open
*/
async checkPort(host, port, timeout) {
return new Promise((resolve) => {
const socket = new net.Socket();
const timer = setTimeout(() => {
socket.destroy();
resolve({
host,
port,
open: false,
});
}, timeout);
socket.connect(port, host, () => {
clearTimeout(timer);
socket.destroy();
resolve({
host,
port,
open: true,
service: this.getServiceName(port),
});
});
socket.on('error', () => {
clearTimeout(timer);
resolve({
host,
port,
open: false,
});
});
});
}
/**
* Get service name for common ports
*/
getServiceName(port) {
const services = {
20: 'FTP Data',
21: 'FTP Control',
22: 'SSH',
23: 'Telnet',
25: 'SMTP',
53: 'DNS',
80: 'HTTP',
110: 'POP3',
143: 'IMAP',
443: 'HTTPS',
465: 'SMTPS',
587: 'SMTP Submission',
993: 'IMAPS',
995: 'POP3S',
3306: 'MySQL',
5432: 'PostgreSQL',
6379: 'Redis',
8080: 'HTTP Alt',
8443: 'HTTPS Alt',
27017: 'MongoDB',
};
return services[port] || `Port ${port}`;
}
/**
* Resolve DNS for hostnames
*/
async resolveDns(hostnames) {
const results = [];
for (const hostname of hostnames) {
try {
const lookup = await dnsLookup(hostname);
results.push({
hostname,
addresses: [lookup.address],
});
}
catch (err) {
results.push({
hostname,
addresses: [],
error: err.message,
});
}
}
return results;
}
/**
* Calculate latency statistics
*/
calculateLatencyStats(connectivity) {
const latencies = connectivity
.filter((c) => c.latency !== undefined)
.map((c) => c.latency);
if (latencies.length === 0) {
return undefined;
}
const min = Math.min(...latencies);
const max = Math.max(...latencies);
const avg = latencies.reduce((sum, l) => sum + l, 0) / latencies.length;
return {
min: Math.round(min * 100) / 100,
max: Math.round(max * 100) / 100,
avg: Math.round(avg * 100) / 100,
};
}
/**
* Generate diagnostics
*/
generateDiagnostics(result) {
const diagnostics = [];
// Connectivity diagnostics
const unreachableHosts = result.connectivity.filter((c) => !c.reachable);
if (unreachableHosts.length > 0) {
diagnostics.push({
type: 'connectivity',
severity: unreachableHosts.length === result.connectivity.length
? 'critical'
: 'warning',
message: `${unreachableHosts.length} host(s) unreachable: ${unreachableHosts.map((h) => h.host).join(', ')}`,
});
}
// Performance diagnostics
if (result.latencyStats) {
if (result.latencyStats.avg > 200) {
diagnostics.push({
type: 'performance',
severity: result.latencyStats.avg > 500 ? 'warning' : 'info',
message: `High average latency: ${result.latencyStats.avg}ms`,
});
}
}
// DNS diagnostics
if (result.dns) {
const failedDns = result.dns.filter((d) => d.error);
if (failedDns.length > 0) {
diagnostics.push({
type: 'dns',
severity: 'warning',
message: `DNS resolution failed for: ${failedDns.map((d) => d.hostname).join(', ')}`,
});
}
}
return diagnostics;
}
/**
* Generate recommendations
*/
generateRecommendations(result) {
const recommendations = [];
// Check if all hosts are unreachable
const allUnreachable = result.connectivity.every((c) => !c.reachable);
if (allUnreachable && result.connectivity.length > 0) {
recommendations.push({
type: 'connectivity',
message: 'All hosts unreachable. Check firewall, VPN, or internet connection.',
impact: 'high',
});
}
// High latency recommendations
if (result.latencyStats && result.latencyStats.avg > 200) {
recommendations.push({
type: 'performance',
message: 'High network latency detected. Consider using a CDN or checking network quality.',
impact: 'medium',
});
}
// Port security recommendations
if (result.ports) {
const openPorts = result.ports.filter((p) => p.open);
const sensitivePorts = openPorts.filter((p) => [23, 21, 3306, 5432, 27017].includes(p.port));
if (sensitivePorts.length > 0) {
recommendations.push({
type: 'configuration',
message: `Sensitive ports open: ${sensitivePorts.map((p) => p.service).join(', ')}. Ensure proper security measures.`,
impact: 'high',
});
}
}
return recommendations;
}
/**
* Generate cache key
*/
generateCacheKey(operation, hosts, ports, hostnames) {
const keyParts = [
operation,
hosts.join(','),
ports.join(','),
hostnames.join(','),
];
return createHash('md5').update(keyParts.join(':')).digest('hex');
}
/**
* Get cached result
*/
getCachedResult(key, maxAge) {
const cached = this.cache.get(this.cacheNamespace + ':' + key);
if (!cached)
return null;
try {
const result = JSON.parse(cached);
const age = (Date.now() - result.cachedAt) / 1000;
if (age <= maxAge) {
return result;
}
}
catch (err) {
return null;
}
return null;
}
/**
* Cache result
*/
cacheResult(key, result) {
const cacheData = { ...result, cachedAt: Date.now() };
const dataToCache = JSON.stringify(cacheData);
const originalSize = this.estimateOriginalOutputSize(result);
const compactSize = dataToCache.length;
this.cache.set(this.cacheNamespace + ':' + key, dataToCache, originalSize, compactSize);
}
/**
* Transform to smart output
*/
transformOutput(result, diagnostics, recommendations, fromCache = false) {
const connectivity = result.connectivity.map((c) => ({
host: c.host,
reachable: c.reachable,
latency: c.latency,
status: c.reachable
? 'online'
: c.error?.includes('timeout')
? 'timeout'
: 'offline',
}));
const ports = result.ports?.map((p) => ({
host: p.host,
port: p.port,
open: p.open,
service: p.service,
}));
const dns = result.dns?.map((d) => ({
hostname: d.hostname,
addresses: d.addresses,
resolved: !d.error,
}));
let latencyStats = result.latencyStats
? {
...result.latencyStats,
distribution: this.getLatencyDistribution(result.latencyStats),
}
: undefined;
const originalSize = this.estimateOriginalOutputSize(result);
const compactSize = this.estimateCompactSize({ connectivity, ports, dns });
const reachableCount = connectivity.filter((c) => c.reachable).length;
return {
summary: {
success: result.success,
operation: 'network diagnostics',
hostsChecked: connectivity.length,
reachableHosts: reachableCount,
duration: result.duration,
fromCache,
},
connectivity,
ports,
dns,
latencyStats,
diagnostics,
recommendations,
metrics: {
originalTokens: Math.ceil(originalSize / 4),
compactedTokens: Math.ceil(compactSize / 4),
reductionPercentage: Math.round(((originalSize - compactSize) / originalSize) * 100),
},
};
}
/**
* Get latency distribution description
*/
getLatencyDistribution(stats) {
if (stats.avg < 50)
return 'Excellent';
if (stats.avg < 100)
return 'Good';
if (stats.avg < 200)
return 'Fair';
if (stats.avg < 500)
return 'Poor';
return 'Very Poor';
}
/**
* Format cached output
*/
formatCachedOutput(result) {
return this.transformOutput(result, [], [], true);
}
/**
* Estimate original output size
*/
estimateOriginalOutputSize(result) {
// Verbose ping/traceroute output
let size = 1000;
size += result.connectivity.length * 200;
size += (result.ports?.length || 0) * 100;
size += (result.dns?.length || 0) * 150;
return size;
}
/**
* Estimate compact output size
*/
estimateCompactSize(output) {
return JSON.stringify(output).length;
}
/**
* Close cache connection
*/
close() {
this.cache.close();
}
}
/**
* Factory function for dependency injection
*/
export function getSmartNetwork(cache, projectRoot) {
return new SmartNetwork(cache, projectRoot);
}
/**
* CLI-friendly function for running smart network diagnostics
*/
export async function runSmartNetwork(options) {
const cache = new CacheEngine(join(homedir(), '.hypercontext', 'cache'), 100);
const smartNetwork = getSmartNetwork(cache, options.projectRoot);
try {
const result = await smartNetwork.run(options);
let output = `\nš Smart Network Diagnostics ${result.summary.fromCache ? '(cached)' : ''}\n`;
output += `${'='.repeat(50)}\n\n`;
// Summary
output += `Summary:\n`;
output += ` Operation: ${result.summary.operation}\n`;
output += ` Hosts Checked: ${result.summary.hostsChecked}\n`;
output += ` Reachable: ${result.summary.reachableHosts}/${result.summary.hostsChecked}\n`;
output += ` Duration: ${(result.summary.duration / 1000).toFixed(2)}s\n\n`;
// Connectivity
if (result.connectivity.length > 0) {
output += `Connectivity:\n`;
for (const conn of result.connectivity) {
const icon = conn.status === 'online'
? 'ā'
: conn.status === 'timeout'
? 'ā±'
: 'ā';
output += ` ${icon} ${conn.host}: ${conn.status}`;
if (conn.latency) {
output += ` (${conn.latency}ms)`;
}
output += '\n';
}
output += '\n';
}
// Latency stats
if (result.latencyStats) {
output += `Latency Statistics:\n`;
output += ` Min: ${result.latencyStats.min}ms\n`;
output += ` Avg: ${result.latencyStats.avg}ms\n`;
output += ` Max: ${result.latencyStats.max}ms\n`;
output += ` Quality: ${result.latencyStats.distribution}\n\n`;
}
// Ports
if (result.ports && result.ports.length > 0) {
output += `Port Scan Results:\n`;
for (const port of result.ports) {
const icon = port.open ? 'š¢' : 'š“';
output += ` ${icon} ${port.host}:${port.port} (${port.service || 'Unknown'}) - ${port.open ? 'Open' : 'Closed'}\n`;
}
output += '\n';
}
// DNS
if (result.dns && result.dns.length > 0) {
output += `DNS Resolution:\n`;
for (const dns of result.dns) {
const icon = dns.resolved ? 'ā' : 'ā';
output += ` ${icon} ${dns.hostname}`;
if (dns.resolved) {
output += `: ${dns.addresses.join(', ')}`;
}
else {
output += ': Failed to resolve';
}
output += '\n';
}
output += '\n';
}
// Diagnostics
if (result.diagnostics.length > 0) {
output += `Diagnostics:\n`;
for (const diag of result.diagnostics) {
const icon = diag.severity === 'critical'
? 'š“'
: diag.severity === 'warning'
? 'ā ļø'
: 'ā¹ļø';
output += ` ${icon} [${diag.type}] ${diag.message}\n`;
}
output += '\n';
}
// Recommendations
if (result.recommendations.length > 0) {
output += `Recommendations:\n`;
for (const rec of result.recommendations) {
const icon = rec.impact === 'high' ? 'š“' : rec.impact === 'medium' ? 'š”' : 'š¢';
output += ` ${icon} [${rec.type}] ${rec.message}\n`;
}
output += '\n';
}
// Metrics
output += `Token Reduction:\n`;
output += ` Original: ${result.metrics.originalTokens} tokens\n`;
output += ` Compacted: ${result.metrics.compactedTokens} tokens\n`;
output += ` Reduction: ${result.metrics.reductionPercentage}%\n`;
return output;
}
finally {
smartNetwork.close();
}
}
// MCP Tool definition
export const SMART_NETWORK_TOOL_DEFINITION = {
name: 'smart_network',
description: 'Network diagnostics and monitoring with connectivity testing, port scanning, DNS resolution, and anomaly detection',
inputSchema: {
type: 'object',
properties: {
operation: {
type: 'string',
enum: ['ping', 'port-scan', 'dns', 'traceroute', 'all'],
description: 'Network operation to perform',
},
hosts: {
type: 'array',
items: { type: 'string' },
description: 'Hosts to test (for ping/port-scan operations)',
},
ports: {
type: 'array',
items: { type: 'number' },
description: 'Ports to scan (for port-scan operation)',
},
hostnames: {
type: 'array',
items: { type: 'string' },
description: 'Hostnames for DNS resolution',
},
pingCount: {
type: 'number',
description: 'Number of ping attempts per host',
default: 4,
},
timeout: {
type: 'number',
description: 'Timeout in milliseconds',
default: 5000,
},
projectRoot: {
type: 'string',
description: 'Project root directory',
},
maxCacheAge: {
type: 'number',
description: 'Maximum cache age in seconds (default: 300)',
default: 300,
},
},
required: ['operation'],
},
};
//# sourceMappingURL=smart-network.js.map