get_services_status
Check the operational status of systemd, Docker, and PM2 services on a remote server to monitor system health and identify potential issues.
Instructions
Récupère le statut de tous les services connus (systemd, Docker, PM2) sur un serveur.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| alias | Yes | Alias du serveur cible. |
Implementation Reference
- server.js:275-300 (handler)The main handler function for the 'get_services_status' tool. It queues an SSH job to execute commands that check running systemd services, Docker containers (docker ps), and PM2 processes (pm2 list), waits for the job to complete, parses the output using ssh.parseServicesStatus, and returns the structured services status as JSON.async (params) => { try { const cmd = "systemctl --type=service --state=running --no-pager ; echo '---DOCKER---' ; docker ps --format '{{.Names}}: {{.Status}}' ; echo '---PM2---' ; pm2 list"; const job = queue.addJob({ type: 'ssh', alias: params.alias, cmd: cmd }); ssh.executeCommand(job.id); const result = await waitForJobCompletion(job.id, config.syncTimeout); if (!result || result.status !== 'completed') { throw new Error(result ? result.error : `Timeout de la commande de monitoring pour ${params.alias}`); } const parsedOutput = ssh.parseServicesStatus(result.output); return { content: [{ type: "text", text: JSON.stringify(parsedOutput, null, 2) }] }; } catch (e) { const errorPayload = { toolName: "get_services_status", errorCode: "MONITORING_ERROR", errorMessage: e.message }; return { content: [{ type: "text", text: JSON.stringify(errorPayload, null, 2) }], isError: true }; } }
- server.js:266-301 (registration)Registration of the 'get_services_status' tool with the MCP server, specifying the tool name, metadata (title, description), input schema, and handler function.server.registerTool( "get_services_status", { title: "Obtenir le statut des services d'un VPS", description: "Récupère le statut de tous les services connus (systemd, Docker, PM2) sur un serveur.", inputSchema: z.object({ alias: z.string().describe("Alias du serveur cible.") }) }, async (params) => { try { const cmd = "systemctl --type=service --state=running --no-pager ; echo '---DOCKER---' ; docker ps --format '{{.Names}}: {{.Status}}' ; echo '---PM2---' ; pm2 list"; const job = queue.addJob({ type: 'ssh', alias: params.alias, cmd: cmd }); ssh.executeCommand(job.id); const result = await waitForJobCompletion(job.id, config.syncTimeout); if (!result || result.status !== 'completed') { throw new Error(result ? result.error : `Timeout de la commande de monitoring pour ${params.alias}`); } const parsedOutput = ssh.parseServicesStatus(result.output); return { content: [{ type: "text", text: JSON.stringify(parsedOutput, null, 2) }] }; } catch (e) { const errorPayload = { toolName: "get_services_status", errorCode: "MONITORING_ERROR", errorMessage: e.message }; return { content: [{ type: "text", text: JSON.stringify(errorPayload, null, 2) }], isError: true }; } } );
- server.js:271-273 (schema)Zod input schema for the tool, requiring a single 'alias' parameter for the target server.inputSchema: z.object({ alias: z.string().describe("Alias du serveur cible.") })
- ssh.js:413-467 (helper)Helper function that parses the raw output from the SSH services status command, splitting into sections for systemd, Docker, and PM2, and extracting service names and statuses into structured arrays.function parseServicesStatus(output) { const services = { systemd: [], docker: [], pm2: [] }; try { const sections = output.split(/---DOCKER---|---PM2---/); const systemdRaw = sections[0] || ''; const dockerRaw = sections[1] || ''; const pm2Raw = sections[2] || ''; // Parse systemd if (systemdRaw) { const lines = systemdRaw.trim().split('\n'); lines.forEach(line => { const match = line.match(/^(\S+)\s+loaded\s+active\s+running/); if (match && match[1]) { services.systemd.push({ name: match[1], status: 'running' }); } }); } // Parse Docker if (dockerRaw) { const lines = dockerRaw.trim().split('\n').filter(Boolean); lines.forEach(line => { const parts = line.split(': '); if (parts.length >= 2) { services.docker.push({ name: parts[0].trim(), status: parts.slice(1).join(': ').trim() }); } }); } // Parse PM2 if (pm2Raw) { const lines = pm2Raw.trim().split('\n'); const tableStartIndex = lines.findIndex(line => line.includes('│ id │')); if (tableStartIndex !== -1) { const tableBody = lines.slice(tableStartIndex + 2, -1); // Skip header, separator, and footer tableBody.forEach(line => { const columns = line.split('│').map(s => s.trim()).filter(Boolean); if (columns.length >= 4) { // id, name, namespace, status services.pm2.push({ id: columns[0], name: columns[1], status: columns[3] }); } }); } } } catch (e) { return { raw_output: output, parsing_error: e.message }; } return services; }