Skip to main content
Glama

execute_docker_command

Execute Docker commands through natural language or direct input to manage containers, images, system operations, and Docker Compose functionality.

Instructions

Execute Docker commands using natural language or direct commands

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
commandYesNatural language command or direct Docker command to execute

Implementation Reference

  • The handler function for the 'execute_docker_command' tool. Parses the input command using natural language processing via parseDockerCommand, executes the Docker CLI command using executeDockerCommand, and returns formatted output or error.
    async ({ command }) => { try { // Parse natural language to Docker command const dockerCommand = parseDockerCommand(command); // Execute the Docker command const result = await executeDockerCommand(dockerCommand); return { content: [ { type: "text", text: `Executed: ${dockerCommand}\n\nOutput:\n${result.stdout}${result.stderr ? `\nErrors:\n${result.stderr}` : ""}` } ] }; } catch (error) { return { content: [ { type: "text", text: `Error executing Docker command: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } );
  • The input schema definition for the tool, specifying the 'command' parameter using Zod validation.
    { title: "Execute Docker Command", description: "Execute Docker commands using natural language or direct commands", inputSchema: { command: z.string().describe("Natural language command or direct Docker command to execute") } },
  • src/index.ts:1158-1195 (registration)
    Registration of the 'execute_docker_command' tool on the MCP server, including schema and handler reference.
    server.registerTool( "execute_docker_command", { title: "Execute Docker Command", description: "Execute Docker commands using natural language or direct commands", inputSchema: { command: z.string().describe("Natural language command or direct Docker command to execute") } }, async ({ command }) => { try { // Parse natural language to Docker command const dockerCommand = parseDockerCommand(command); // Execute the Docker command const result = await executeDockerCommand(dockerCommand); return { content: [ { type: "text", text: `Executed: ${dockerCommand}\n\nOutput:\n${result.stdout}${result.stderr ? `\nErrors:\n${result.stderr}` : ""}` } ] }; } catch (error) { return { content: [ { type: "text", text: `Error executing Docker command: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } );
  • Core helper function that executes Docker commands using Node.js child_process.execAsync (promisified). Used by the tool handler and throughout the codebase.
    async function executeDockerCommand(command: string): Promise<{ stdout: string; stderr: string }> { try { const result = await execAsync(command); return result; } catch (error: any) { throw new Error(`Docker command failed: ${error.message}`); } }
  • Helper function that translates natural language descriptions into equivalent Docker CLI commands. Critical for the tool's natural language interface. Contains extensive regex-based parsing for various Docker operations.
    function parseDockerCommand(naturalLanguage: string): string { const input = naturalLanguage.toLowerCase().trim(); // === CONTAINER OPERATIONS === // List containers with various formats if (input.match(/(list|show|display|get)\s+(all\s+)?(containers?|running|stopped)/)) { if (input.includes("all") || input.includes("stopped")) { return "docker ps -a"; } if (input.includes("running")) { return "docker ps"; } return "docker ps -a"; } if (input.match(/(what|which)\s+containers?\s+are\s+(running|active)/)) { return "docker ps"; } // Container lifecycle operations if (input.match(/(start|run|launch)\s+(container\s+)?([a-zA-Z0-9_-]+)/)) { const match = input.match(/(start|run|launch)\s+(?:container\s+)?([a-zA-Z0-9_-]+)/); if (match) { return `docker start ${match[2]}`; } } if (input.match(/(stop|halt|kill)\s+(container\s+)?([a-zA-Z0-9_-]+)/)) { const match = input.match(/(stop|halt|kill)\s+(?:container\s+)?([a-zA-Z0-9_-]+)/); if (match) { const action = match[1] === "kill" ? "kill" : "stop"; return `docker ${action} ${match[3]}`; } } if (input.match(/(restart|reboot)\s+(container\s+)?([a-zA-Z0-9_-]+)/)) { const match = input.match(/(restart|reboot)\s+(?:container\s+)?([a-zA-Z0-9_-]+)/); if (match) { return `docker restart ${match[3]}`; } } if (input.match(/(remove|delete|rm)\s+(container\s+)?([a-zA-Z0-9_-]+)/)) { const match = input.match(/(remove|delete|rm)\s+(?:container\s+)?([a-zA-Z0-9_-]+)/); if (match) { return `docker rm ${match[3]}`; } } // Container inspection and logs if (input.match(/(inspect|examine|details?)\s+(container\s+)?([a-zA-Z0-9_-]+)/)) { const match = input.match(/(inspect|examine|details?)\s+(?:container\s+)?([a-zA-Z0-9_-]+)/); if (match) { return `docker inspect ${match[3]}`; } } if (input.match(/(logs?|output)\s+(from\s+)?(container\s+)?([a-zA-Z0-9_-]+)/)) { const match = input.match(/(logs?|output)\s+(?:from\s+)?(?:container\s+)?([a-zA-Z0-9_-]+)/); if (match) { const follow = input.includes("follow") || input.includes("tail") ? " -f" : ""; const lines = input.match(/(\d+)\s+lines?/) ? ` --tail ${input.match(/(\d+)\s+lines?/)![1]}` : ""; return `docker logs${follow}${lines} ${match[2]}`; } } if (input.match(/(exec|execute|run)\s+(in|into)\s+(container\s+)?([a-zA-Z0-9_-]+)/)) { const match = input.match(/(exec|execute|run)\s+(?:in|into)\s+(?:container\s+)?([a-zA-Z0-9_-]+)/); if (match) { const command = input.includes("bash") ? "bash" : input.includes("sh") ? "sh" : "bash"; return `docker exec -it ${match[2]} ${command}`; } } // === IMAGE OPERATIONS === // List images if (input.match(/(list|show|display|get)\s+(all\s+)?(images?|repos?|repositories)/)) { if (input.includes("dangling")) { return "docker images -f dangling=true"; } return "docker images"; } // Pull images if (input.match(/(pull|download|fetch)\s+(image\s+)?([a-zA-Z0-9/_.-]+)(:([a-zA-Z0-9._-]+))?/)) { const match = input.match(/(pull|download|fetch)\s+(?:image\s+)?([a-zA-Z0-9/_.-]+)(?::([a-zA-Z0-9._-]+))?/); if (match) { const image = match[2]; const tag = match[3] || (input.includes("latest") ? "latest" : ""); return `docker pull ${image}${tag ? `:${tag}` : ""}`; } } // Push images if (input.match(/(push|upload)\s+(image\s+)?([a-zA-Z0-9/_.-]+)(:([a-zA-Z0-9._-]+))?/)) { const match = input.match(/(push|upload)\s+(?:image\s+)?([a-zA-Z0-9/_.-]+)(?::([a-zA-Z0-9._-]+))?/); if (match) { const image = match[2]; const tag = match[3] || ""; return `docker push ${image}${tag ? `:${tag}` : ""}`; } } // Build images if (input.match(/(build|create)\s+(image\s+)?([a-zA-Z0-9/_.-]+)/)) { const match = input.match(/(build|create)\s+(?:image\s+)?([a-zA-Z0-9/_.-]+)/); if (match) { const dockerfile = input.includes("dockerfile") ? ` -f ${input.match(/dockerfile[:\s]+([^\s]+)/)?.[1] || "Dockerfile"}` : ""; const context = input.match(/(?:from|in)\s+([^\s]+)/) ? ` ${input.match(/(?:from|in)\s+([^\s]+)/)![1]}` : " ."; return `docker build${dockerfile} -t ${match[3]}${context}`; } } // Remove images if (input.match(/(remove|delete|rm)\s+(image\s+)?([a-zA-Z0-9/_.-]+)/)) { const match = input.match(/(remove|delete|rm)\s+(?:image\s+)?([a-zA-Z0-9/_.-]+)/); if (match) { const force = input.includes("force") ? " -f" : ""; return `docker rmi${force} ${match[3]}`; } } // Tag images if (input.match(/(tag|label)\s+(image\s+)?([a-zA-Z0-9/_.-]+)\s+(as\s+)?([a-zA-Z0-9/_.-]+)/)) { const match = input.match(/(tag|label)\s+(?:image\s+)?([a-zA-Z0-9/_.-]+)\s+(?:as\s+)?([a-zA-Z0-9/_.-]+)/); if (match) { return `docker tag ${match[2]} ${match[3]}`; } } // === VOLUME OPERATIONS === if (input.match(/(list|show|display)\s+(all\s+)?(volumes?|storage)/)) { if (input.includes("dangling")) { return "docker volume ls -f dangling=true"; } return "docker volume ls"; } if (input.match(/(create|make)\s+(volume\s+)?([a-zA-Z0-9_-]+)/)) { const match = input.match(/(create|make)\s+(?:volume\s+)?([a-zA-Z0-9_-]+)/); if (match) { return `docker volume create ${match[2]}`; } } if (input.match(/(remove|delete)\s+(volume\s+)?([a-zA-Z0-9_-]+)/)) { const match = input.match(/(remove|delete)\s+(?:volume\s+)?([a-zA-Z0-9_-]+)/); if (match) { return `docker volume rm ${match[3]}`; } } if (input.match(/(inspect|examine)\s+(volume\s+)?([a-zA-Z0-9_-]+)/)) { const match = input.match(/(inspect|examine)\s+(?:volume\s+)?([a-zA-Z0-9_-]+)/); if (match) { return `docker volume inspect ${match[3]}`; } } // === NETWORK OPERATIONS === if (input.match(/(list|show|display)\s+(all\s+)?(networks?|networking)/)) { return "docker network ls"; } if (input.match(/(create|make)\s+(network\s+)?([a-zA-Z0-9_-]+)/)) { const match = input.match(/(create|make)\s+(?:network\s+)?([a-zA-Z0-9_-]+)/); if (match) { const driver = input.includes("bridge") ? " --driver bridge" : input.includes("overlay") ? " --driver overlay" : ""; return `docker network create${driver} ${match[2]}`; } } if (input.match(/(remove|delete)\s+(network\s+)?([a-zA-Z0-9_-]+)/)) { const match = input.match(/(remove|delete)\s+(?:network\s+)?([a-zA-Z0-9_-]+)/); if (match) { return `docker network rm ${match[3]}`; } } if (input.match(/(connect|attach)\s+([a-zA-Z0-9_-]+)\s+(to\s+)?([a-zA-Z0-9_-]+)/)) { const match = input.match(/(connect|attach)\s+([a-zA-Z0-9_-]+)\s+(?:to\s+)?([a-zA-Z0-9_-]+)/); if (match) { return `docker network connect ${match[3]} ${match[2]}`; } } if (input.match(/(disconnect|detach)\s+([a-zA-Z0-9_-]+)\s+(from\s+)?([a-zA-Z0-9_-]+)/)) { const match = input.match(/(disconnect|detach)\s+([a-zA-Z0-9_-]+)\s+(?:from\s+)?([a-zA-Z0-9_-]+)/); if (match) { return `docker network disconnect ${match[4]} ${match[2]}`; } } // === SYSTEM OPERATIONS === if (input.match(/(system\s+)?(info|information|details)/)) { return "docker system info"; } if (input.match(/(version|ver)/)) { return "docker --version && docker-compose --version"; } if (input.match(/(stats|statistics|status|monitor)/)) { const noStream = !input.includes("follow") && !input.includes("continuous"); return `docker stats${noStream ? " --no-stream" : ""}`; } if (input.match(/(disk\s+usage|space|storage\s+usage)/)) { const verbose = input.includes("verbose") || input.includes("detailed") ? " -v" : ""; return `docker system df${verbose}`; } if (input.match(/(clean\s*up?|prune|cleanup)/)) { if (input.includes("all") || input.includes("everything")) { return "docker system prune -a -f"; } if (input.includes("volumes")) { return "docker system prune --volumes -f"; } return "docker system prune -f"; } // === DOCKER COMPOSE OPERATIONS === if (input.match(/(compose\s+)?(up|start|launch)/)) { const detached = !input.includes("foreground") && !input.includes("attached"); const build = input.includes("build") || input.includes("rebuild"); const service = input.match(/service\s+([a-zA-Z0-9_-]+)/) ? ` ${input.match(/service\s+([a-zA-Z0-9_-]+)/)![1]}` : ""; return `docker-compose up${detached ? " -d" : ""}${build ? " --build" : ""}${service}`; } if (input.match(/(compose\s+)?(down|stop|halt)/)) { const volumes = input.includes("volumes") || input.includes("data") ? " --volumes" : ""; const images = input.includes("images") ? " --rmi all" : ""; return `docker-compose down${volumes}${images}`; } if (input.match(/(compose\s+)?(logs|output)/)) { const follow = input.includes("follow") || input.includes("tail") ? " -f" : ""; const service = input.match(/(?:from\s+|service\s+)([a-zA-Z0-9_-]+)/) ? ` ${input.match(/(?:from\s+|service\s+)([a-zA-Z0-9_-]+)/)![1]}` : ""; return `docker-compose logs${follow}${service}`; } if (input.match(/(compose\s+)?(ps|status|services)/)) { return "docker-compose ps"; } if (input.match(/(compose\s+)?(restart|reboot)/)) { const service = input.match(/service\s+([a-zA-Z0-9_-]+)/) ? ` ${input.match(/service\s+([a-zA-Z0-9_-]+)/)![1]}` : ""; return `docker-compose restart${service}`; } if (input.match(/(compose\s+)?(build|rebuild)/)) { const service = input.match(/service\s+([a-zA-Z0-9_-]+)/) ? ` ${input.match(/service\s+([a-zA-Z0-9_-]+)/)![1]}` : ""; const noCache = input.includes("fresh") || input.includes("clean") ? " --no-cache" : ""; return `docker-compose build${noCache}${service}`; } // === ADVANCED OPERATIONS === // Search Docker Hub if (input.match(/(search|find)\s+(for\s+)?([a-zA-Z0-9/_.-]+)/)) { const match = input.match(/(search|find)\s+(?:for\s+)?([a-zA-Z0-9/_.-]+)/); if (match) { return `docker search ${match[2]}`; } } // Copy files if (input.match(/(copy|cp)\s+([^\s]+)\s+(from|to)\s+([a-zA-Z0-9_-]+)/)) { const match = input.match(/(copy|cp)\s+([^\s]+)\s+(from|to)\s+([a-zA-Z0-9_-]+)/); if (match) { const [, , path, direction, container] = match; if (direction === "from") { return `docker cp ${container}:${path} .`; } else { return `docker cp ${path} ${container}:/tmp/`; } } } // Port mapping info if (input.match(/(port|ports)\s+(of\s+|for\s+)?([a-zA-Z0-9_-]+)/)) { const match = input.match(/(port|ports)\s+(?:of\s+|for\s+)?([a-zA-Z0-9_-]+)/); if (match) { return `docker port ${match[2]}`; } } // Process list in container if (input.match(/(processes?|ps|top)\s+(in|inside)\s+([a-zA-Z0-9_-]+)/)) { const match = input.match(/(processes?|ps|top)\s+(?:in|inside)\s+([a-zA-Z0-9_-]+)/); if (match) { return `docker top ${match[3]}`; } } // === REGISTRY OPERATIONS === if (input.match(/login\s+(to\s+)?([a-zA-Z0-9._-]+)?/)) { const match = input.match(/login\s+(?:to\s+)?([a-zA-Z0-9._-]+)?/); const registry = match?.[1] || ""; return `docker login${registry ? ` ${registry}` : ""}`; } if (input.match(/logout\s+(from\s+)?([a-zA-Z0-9._-]+)?/)) { const match = input.match(/logout\s+(?:from\s+)?([a-zA-Z0-9._-]+)?/); const registry = match?.[1] || ""; return `docker logout${registry ? ` ${registry}` : ""}`; } // === FALLBACK === // If no pattern matches but it starts with docker, pass through if (input.startsWith("docker")) { return input; } // General help if (input.match(/(help|usage|commands)/)) { return "docker --help"; } // Default to treating as direct docker command return `docker ${input}`; }

Latest Blog Posts

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/TauqeerAhmad5201/docker-mcp-extension'

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