Skip to main content
Glama

Execute Docker Command

execute_docker_command

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

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

  • src/index.ts:1158-1195 (registration)
    Registration of the 'execute_docker_command' MCP tool, including schema and inline handler function.
    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
          };
        }
      }
    );
  • Handler function for execute_docker_command tool: parses input with parseDockerCommand, executes via executeDockerCommand, and formats response.
      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
          };
        }
      }
    );
  • Input schema definition for the execute_docker_command tool using Zod.
    {
      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")
      }
  • Core helper function executeDockerCommand that runs shell commands using Node's child_process.exec (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}`);
      }
    }
  • parseDockerCommand helper: Converts natural language descriptions (e.g., 'list running containers') to exact Docker CLI commands via regex pattern matching.
    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}`;
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions executing commands but doesn't describe safety aspects (e.g., whether it can run destructive commands, requires specific permissions, has rate limits, or returns structured output). For a tool that likely interacts with Docker, this lack of behavioral context is a significant gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that directly states the tool's function without unnecessary words. It is appropriately sized and front-loaded, making it easy to parse quickly. Every word earns its place by conveying the core capability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of Docker operations and the lack of annotations and output schema, the description is incomplete. It doesn't explain what happens after execution (e.g., success/failure handling, output format), nor does it address potential risks or dependencies. For a tool with no structured safety hints, more context is needed to guide safe and effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage, with the single parameter 'command' documented as 'Natural language command or direct Docker command to execute'. The description adds no additional meaning beyond this, such as examples or constraints on command types. With high schema coverage, the baseline score of 3 is appropriate as the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the tool 'Execute Docker commands using natural language or direct commands', which provides a general purpose but lacks specificity. It mentions both natural language and direct commands but doesn't clarify what types of Docker commands are supported or how it differs from sibling tools like manage_containers or docker_compose. The purpose is vague rather than specific.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. With many sibling tools available (e.g., create_container, manage_containers, docker_compose), the description doesn't specify scenarios where execute_docker_command is preferred, nor does it mention prerequisites or exclusions. This leaves the agent without clear usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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