UNPKG

it-tools-mcp

Version:

Full MCP 2025-06-18 compliant server with 121+ IT tools, logging, ping, progress tracking, cancellation, and sampling utilities

127 lines (126 loc) 5.1 kB
import { z } from "zod"; import yaml from "js-yaml"; export function registerDockerRunToCompose(server) { server.registerTool("convert_docker_run_to_compose", { description: "Convert docker run commands to Docker Compose format", inputSchema: { commands: z.string().describe("Docker run commands to convert (one per line)"), }, // VS Code compliance annotations annotations: { title: "Convert Docker Run To Compose", description: "Convert docker run commands to Docker Compose format", readOnlyHint: false } }, async ({ commands }) => { if (!commands?.trim()) { return { content: [ { type: "text", text: "Please provide docker run commands to convert", }, ], }; } try { const lines = commands.split('\n').filter(line => line.trim()); const services = {}; for (const line of lines) { const trimmedLine = line.trim(); if (!trimmedLine.startsWith('docker run')) { continue; } // Parse docker run command const args = trimmedLine.split(/\s+/); let serviceName = 'app'; const service = {}; for (let i = 0; i < args.length; i++) { const arg = args[i]; switch (arg) { case '--name': serviceName = args[++i]; break; case '-p': const portMapping = args[++i]; if (!service.ports) service.ports = []; service.ports.push(portMapping); break; case '-v': const volumeMapping = args[++i]; if (!service.volumes) service.volumes = []; service.volumes.push(volumeMapping); break; case '-e': const envVar = args[++i]; if (!service.environment) service.environment = []; service.environment.push(envVar); break; case '--restart': service.restart = args[++i]; break; case '--network': const networkName = args[++i]; if (!service.networks) service.networks = []; service.networks.push(networkName); break; case '-w': service.working_dir = args[++i]; break; case '--user': service.user = args[++i]; break; case '-d': // Detached mode is default in compose break; default: // Check if this is the image name (no dashes and not a flag value) if (!arg.startsWith('-') && i > 1 && !args[i - 1].startsWith('-')) { if (!service.image && (arg.includes('/') || arg.includes(':') || !arg.includes(' '))) { service.image = arg; } } break; } } // If no image found, try to extract from the end if (!service.image) { const lastArgs = args.slice(-3); for (const arg of lastArgs) { if (!arg.startsWith('-') && (arg.includes('/') || arg.includes(':'))) { service.image = arg; break; } } } services[serviceName] = service; } const compose = { version: '3.8', services }; return { content: [ { type: "text", text: yaml.dump(compose), }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error converting docker run to Docker Compose: ${error.message}`, }, ], }; } }); }