Skip to main content
Glama

MalwareAnalyzerMCP

terminalManager.js4.8 kB
/** * Terminal Manager for MalwareAnalyzerMCP * Manages terminal processes, executes commands, and reads output * * @author: abdessamad el amrani , */ import { spawn } from 'child_process'; const DEF_TIMEOUT = 40000; export class TerminalManager { constructor() { // Map of active terminal sessions by PID this.sessions = new Map(); // Map of completed sessions by PID this.completedSessions = new Map(); } /** * Execute a terminal command with optional timeout * @param {string} command - The command to execute * @param {number} timeoutMs - Timeout * @returns {Promise<object>} Result with pid, output, and blocked status */ async shellCommand(command, timeoutMs = DEF_TIMEOUT) { const process = spawn(command, [], { shell: true }); let output = ''; // Ensure process.pid is defined before proceeding if (!process.pid) { return { pid: -1, // Use -1 to indicate an error state output: 'Error: Failed to get process ID. The command could not be executed.', isBlocked: false }; } // Create a session object to track this process const session = { pid: process.pid, process, lastOutput: '', isBlocked: false, startTime: new Date() }; this.sessions.set(process.pid, session); return new Promise((resolve) => { // Handle standard output process.stdout.on('data', (data) => { const text = data.toString(); output += text; session.lastOutput += text; }); // Handle error output process.stderr.on('data', (data) => { const text = data.toString(); output += text; session.lastOutput += text; }); // Set timeout to mark process as blocked if it exceeds timeoutMs setTimeout(() => { session.isBlocked = true; resolve({ pid: process.pid, output, isBlocked: true }); }, timeoutMs); // Handle process completion process.on('exit', (code) => { if (process.pid) { // Store completed session before removing active session this.completedSessions.set(process.pid, { pid: process.pid, output: output + session.lastOutput, // Combine all output exitCode: code, startTime: session.startTime, endTime: new Date() }); // Keep only last 50 completed sessions if (this.completedSessions.size > 50) { const oldestKey = Array.from(this.completedSessions.keys())[0]; this.completedSessions.delete(oldestKey); } this.sessions.delete(process.pid); } resolve({ pid: process.pid, output, isBlocked: false }); }); }); } /** * Read output from a running or completed process * @param {number} pid - Process ID to read output from * @returns {object} Result with output string or null */ readOutput(pid) { // First check active sessions const session = this.sessions.get(pid); if (session) { const output = session.lastOutput; session.lastOutput = ''; // Clear the buffer after reading return { output }; } // Then check completed sessions const completedSession = this.completedSessions.get(pid); if (completedSession) { // Format completion message with exit code and runtime const runtime = (completedSession.endTime.getTime() - completedSession.startTime.getTime()) / 1000; const outputStr = `Process completed with exit code ${completedSession.exitCode}\nRuntime: ${runtime.toFixed(2)}s\nFinal output:\n${completedSession.output}`; // Remove from completed sessions as we've delivered the final output this.completedSessions.delete(pid); return { output: outputStr }; } // Return null if PID not found return { output: null }; } /** * Get status of terminal manager * @returns {object} Count of active and completed sessions */ getStatus() { return { activeSessions: this.sessions.size, completedSessions: this.completedSessions.size }; } /** * Shut down the terminal manager and terminate all processes */ shutdown() { // Terminate all active sessions for (const session of this.sessions.values()) { try { session.process.kill('SIGINT'); setTimeout(() => { session.process.kill('SIGKILL'); }, 500); } catch (error) { console.error(`Failed to terminate process ${session.pid}:`, error); } } this.sessions.clear(); this.completedSessions.clear(); } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/abdessamad-elamrani/MalwareAnalyzerMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server