Module: RubyLLM::Docker

Defined in:
lib/ruby_llm/docker.rb,
lib/ruby_llm/docker/version.rb,
lib/ruby_llm/docker/tag_image.rb,
lib/ruby_llm/docker/pull_image.rb,
lib/ruby_llm/docker/push_image.rb,
lib/ruby_llm/docker/build_image.rb,
lib/ruby_llm/docker/list_images.rb,
lib/ruby_llm/docker/list_volumes.rb,
lib/ruby_llm/docker/remove_image.rb,
lib/ruby_llm/docker/create_volume.rb,
lib/ruby_llm/docker/list_networks.rb,
lib/ruby_llm/docker/remove_volume.rb,
lib/ruby_llm/docker/run_container.rb,
lib/ruby_llm/docker/create_network.rb,
lib/ruby_llm/docker/exec_container.rb,
lib/ruby_llm/docker/remove_network.rb,
lib/ruby_llm/docker/stop_container.rb,
lib/ruby_llm/docker/list_containers.rb,
lib/ruby_llm/docker/start_container.rb,
lib/ruby_llm/docker/create_container.rb,
lib/ruby_llm/docker/remove_container.rb,
lib/ruby_llm/docker/copy_to_container.rb,
lib/ruby_llm/docker/recreate_container.rb,
lib/ruby_llm/docker/fetch_container_logs.rb

Overview

Docker tools module providing comprehensive Docker management capabilities for RubyLLM.

This module contains 22 Docker management tools organized into four categories:

  • Container Management (10 tools)

  • Image Management (6 tools)

  • Network Management (3 tools)

  • Volume Management (3 tools)

Examples:

Basic usage

chat = RubyLLM::Chat.new(api_key: 'your-key', model: 'gpt-4')
RubyLLM::Docker.add_all_tools_to_chat(chat)
response = chat.ask("How many containers are running?")

Defined Under Namespace

Classes: Error

Constant Summary collapse

VERSION =

Current version of the RubyLLM::Docker gem.

This constant follows semantic versioning (SemVer) principles:

  • MAJOR version for incompatible API changes

  • MINOR version for backwards-compatible functionality additions

  • PATCH version for backwards-compatible bug fixes

See Also:

Since:

  • 0.1.0

'0.3.0'
TAG_IMAGE_DEFINITION =

MCP tool for tagging Docker images.

This tool provides the ability to assign repository names and tags to Docker images. Tagging is essential for image organization, versioning, and distribution through Docker registries.

Features

  • Tag existing images with custom repository names

  • Support for version and environment tags

  • Force tagging to overwrite existing tags

  • Registry-compatible naming conventions

  • Automatic tag defaulting to “latest”

  • Comprehensive error handling and validation

Security Considerations

Image tagging involves several security considerations:

  • **Registry Authentication**: Tags may trigger registry operations

  • **Namespace Conflicts**: Overwriting tags can affect other deployments

  • **Image Identity**: Improper tagging can lead to deployment confusion

  • **Version Management**: Incorrect tags can compromise CI/CD pipelines

  • **Registry Pollution**: Excessive tagging can clutter registries

**Security Recommendations**:

  • Use consistent naming conventions

  • Implement tag governance policies

  • Verify image identity before tagging

  • Avoid overwriting production tags

  • Use semantic versioning for releases

  • Monitor tag usage and lifecycle

Parameters

  • id: Image ID or current name:tag to tag (required)

  • repo: Repository name (required, e.g., “username/imagename” or “registry/username/imagename”)

  • tag: Tag for the image (optional, default: “latest”)

  • force: Force tag even if it already exists (optional, default: true)

Example Usage

# Tag image with version
response = TagImage.call(
  server_context: context,
  id: "myapp:dev",
  repo: "myregistry/myapp",
  tag: "v1.2.3"
)

# Tag for production deployment
response = TagImage.call(
  server_context: context,
  id: "abc123def456",
  repo: "production/webapp",
  tag: "stable",
  force: false
)

# Tag with registry prefix
response = TagImage.call(
  server_context: context,
  id: "local-build:latest",
  repo: "registry.company.com/team/service",
  tag: "release-candidate"
)

See Also:

  • Docker::Image#tag

Since:

  • 0.1.0

ToolForge.define(:tag_image) do
  description 'Tag a Docker image'

  param :id,
        type: :string,
        description: 'Image ID or current name:tag to tag'

  param :repo,
        type: :string,
        description: 'Repository name (e.g., "username/imagename" or "registry/username/imagename")'

  param :tag,
        type: :string,
        description: 'Tag for the image (default: "latest")',
        required: false,
        default: 'latest'

  param :force,
        type: :boolean,
        description: 'Force tag even if it already exists (default: true)',
        required: false,
        default: true

  execute do |id:, repo:, tag: 'latest', force: true|
    image = ::Docker::Image.get(id)

    image.tag('repo' => repo, 'tag' => tag, 'force' => force)

    "Image tagged successfully as #{repo}:#{tag}"
  rescue ::Docker::Error::NotFoundError
    "Image #{id} not found"
  rescue StandardError => e
    "Error tagging image: #{e.message}"
  end
end
TagImage =
TAG_IMAGE_DEFINITION.to_ruby_llm_tool
PULL_IMAGE_DEFINITION =

MCP tool for pulling Docker images from registries.

This tool provides the ability to download Docker images from Docker registries (like Docker Hub) to the local system. It supports flexible tag specification and handles various image naming conventions.

Features

  • Pull images from any accessible Docker registry

  • Flexible tag specification (explicit or default)

  • Support for official and user repositories

  • Automatic latest tag handling

  • Comprehensive error handling

  • Progress tracking through Docker daemon

Security Considerations

Pulling images can introduce security risks:

  • **Malicious Images**: Images may contain malware or backdoors

  • **Vulnerable Software**: Images may have known security vulnerabilities

  • **Untrusted Sources**: Images from unknown publishers may be compromised

  • **Supply Chain Attacks**: Legitimate-looking images may be malicious

  • **Resource Consumption**: Large images can consume significant disk space

**Security Recommendations**:

  • Only pull images from trusted registries and publishers

  • Verify image signatures when available

  • Scan pulled images for vulnerabilities

  • Use specific tags rather than ‘latest’

  • Monitor registry access and authentication

  • Regularly update and patch images

Tag Handling

The tool handles tags intelligently:

  • If image includes tag (e.g., “nginx:1.21”), use as specified

  • If separate tag provided, append to image name

  • If no tag specified, default to “latest”

  • Supports all Docker tag conventions

Parameters

  • from_image: Image name to pull (required, e.g., “ubuntu” or “ubuntu:22.04”)

  • tag: Tag to pull (optional, defaults to “latest” if not specified in from_image)

Example Usage

# Pull latest version
response = PullImage.call(
  server_context: context,
  from_image: "nginx"
)

# Pull specific version
response = PullImage.call(
  server_context: context,
  from_image: "postgres",
  tag: "13.8"
)

See Also:

  • Docker::Image.create

Since:

  • 0.1.0

ToolForge.define(:pull_image) do
  description 'Pull a Docker image'

  param :from_image,
        type: :string,
        description: 'Image name to pull (e.g., "ubuntu" or "ubuntu:22.04")'

  param :tag,
        type: :string,
        description: 'Tag to pull (optional, defaults to "latest" if not specified in from_image)',
        required: false

  execute do |from_image:, tag: nil|
    # If tag is provided separately, append it to from_image
    # If from_image already has a tag (contains :), use as-is
    # Otherwise default to :latest
    image_with_tag = if tag
                       "#{from_image}:#{tag}"
                     elsif from_image.include?(':')
                       from_image
                     else
                       "#{from_image}:latest"
                     end

    image = ::Docker::Image.create('fromImage' => image_with_tag)

    "Image #{image_with_tag} pulled successfully. ID: #{image.id}"
  rescue ::Docker::Error::NotFoundError
    "Image #{image_with_tag} not found"
  rescue StandardError => e
    "Error pulling image: #{e.message}"
  end
end
PullImage =
PULL_IMAGE_DEFINITION.to_ruby_llm_tool
PUSH_IMAGE_DEFINITION =

MCP tool for pushing Docker images to registries.

This tool provides the ability to upload Docker images to Docker registries such as Docker Hub, private registries, or cloud-based container registries. It supports various push configurations and authentication scenarios.

Features

  • Push images to any Docker registry

  • Support for tagged and untagged pushes

  • Registry authentication integration

  • Comprehensive error handling and validation

  • Multi-registry support

  • Progress tracking and status reporting

  • Registry namespace validation

Security Considerations

Pushing images involves significant security risks:

  • **Credential Exposure**: Registry credentials may be exposed

  • **Image Integrity**: Pushed images become publicly accessible

  • **Supply Chain Risk**: Malicious images can be distributed

  • **Registry Security**: Vulnerable registries can be compromised

  • **Network Exposure**: Push operations traverse networks

  • **Access Control**: Improper permissions can lead to unauthorized access

**Security Recommendations**:

  • Use secure registry authentication

  • Scan images for vulnerabilities before pushing

  • Implement image signing and verification

  • Use private registries for sensitive images

  • Monitor registry access and usage

  • Implement proper RBAC for registry operations

  • Validate image content before distribution

Parameters

  • name: Image name or ID to push (required)

  • tag: Tag to push (optional, pushes all tags if not specified)

  • repo_tag: Full repo:tag to push (optional, e.g., “registry/repo:tag”)

Example Usage

# Push to Docker Hub
response = PushImage.call(
  server_context: context,
  name: "username/myapp",
  tag: "v1.0.0"
)

# Push to private registry
response = PushImage.call(
  server_context: context,
  name: "myapp",
  repo_tag: "registry.company.com/team/myapp:latest"
)

# Push all tags
response = PushImage.call(
  server_context: context,
  name: "username/myapp"
)

See Also:

Since:

  • 0.1.0

ToolForge.define(:push_image) do
  description 'Push a Docker image'

  param :name,
        type: :string,
        description: 'Image name or ID to push'

  param :tag,
        type: :string,
        description: 'Tag to push (optional, pushes all tags if not specified)',
        required: false

  param :repo_tag,
        type: :string,
        description: 'Full repo:tag to push (e.g., "registry/repo:tag") (optional)',
        required: false

  execute do |name:, tag: nil, repo_tag: nil|
    # Construct the full image identifier
    image_identifier = tag ? "#{name}:#{tag}" : name

    # Validate that the image name includes a registry/username
    unless name.include?('/') || repo_tag&.include?('/')
      next 'Error: Image name must include registry/username ' \
           "(e.g., 'username/#{name}'). Local images cannot be " \
           'pushed without a registry prefix.'
    end

    # Verify the image exists
    begin
      ::Docker::Image.get(image_identifier)
    rescue ::Docker::Error::NotFoundError
      next "Image #{image_identifier} not found"
    end

    # Use the Docker CLI to push the image
    push_target = repo_tag || image_identifier
    _, stderr, status = Open3.capture3('docker', 'push', push_target)

    if status.success?
      "Image #{push_target} pushed successfully"
    else
      error_msg = stderr.strip
      error_msg = 'Failed to push image' if error_msg.empty?
      "Error pushing image: #{error_msg}"
    end
  rescue StandardError => e
    "Error pushing image: #{e.message}"
  end
end
PushImage =
PUSH_IMAGE_DEFINITION.to_ruby_llm_tool
BUILD_IMAGE_DEFINITION =

MCP tool for building Docker images.

This tool provides the ability to build Docker images from Dockerfile content. It creates custom images by executing Dockerfile instructions and supports comprehensive build configuration including tagging and build arguments.

Features

  • Build images from Dockerfile content strings

  • Support for custom image tagging

  • Comprehensive build output and error reporting

  • Handles all standard Dockerfile instructions

  • Build context management

  • Progress tracking and logging

Security Considerations

Image building involves significant security risks:

  • **Code Execution**: Dockerfile RUN commands execute arbitrary code

  • **Network Access**: Build process can access networks and repositories

  • **File System Access**: Can read local files and directories

  • **Credential Exposure**: May expose build-time secrets and credentials

  • **Supply Chain Risk**: Downloaded packages may contain malware

  • **Resource Consumption**: Builds can consume significant CPU, memory, and storage

**Security Recommendations**:

  • Review all Dockerfile content before building

  • Use trusted base images only

  • Avoid embedding secrets in image layers

  • Implement build isolation and sandboxing

  • Monitor build resource consumption

  • Scan built images for vulnerabilities

  • Use multi-stage builds to minimize attack surface

Parameters

  • dockerfile: Dockerfile content as a string (required)

  • tag: Tag for the built image (optional, e.g., “myimage:latest”)

Example Usage

# Build simple image
dockerfile_content = "FROM alpine:latest\nRUN apk add --no-cache curl\nCMD [\"curl\", \"--version\"]\n"

response = BuildImage.call(
  server_context: context,
  dockerfile: dockerfile_content,
  tag: "my-curl:latest"
)

# Build web server image
dockerfile_content = "FROM nginx:alpine\nCOPY nginx.conf /etc/nginx/nginx.conf\nEXPOSE 80\nCMD [\"nginx\", \"-g\", \"daemon off;\"]\n"

response = BuildImage.call(
  server_context: context,
  dockerfile: dockerfile_content,
  tag: "custom-nginx:v1.0"
)

See Also:

  • Docker::Image.build_from_dir

Since:

  • 0.1.0

ToolForge.define(:build_image) do
  description 'Build a Docker image'

  param :dockerfile,
        type: :string,
        description: 'Dockerfile content as a string'

  param :tag,
        type: :string,
        description: 'Tag for the built image (e.g., "myimage:latest")',
        required: false

  execute do |dockerfile:, tag: nil|
    # Build the image
    image = ::Docker::Image.build(dockerfile)

    # If a tag was specified, tag the image
    if tag
      # Split tag into repo and tag parts
      repo, image_tag = tag.split(':', 2)
      image_tag ||= 'latest'
      image.tag('repo' => repo, 'tag' => image_tag, 'force' => true)
    end

    response_text = "Image built successfully. ID: #{image.id}"
    response_text += ", Tag: #{tag}" if tag
    response_text
  rescue StandardError => e
    "Error building image: #{e.message}"
  end
end
BuildImage =
BUILD_IMAGE_DEFINITION.to_ruby_llm_tool
LIST_IMAGES_DEFINITION =

MCP tool for listing Docker images.

This tool provides comprehensive information about all Docker images stored on the local system. It returns detailed metadata including image sizes, creation dates, tags, and usage statistics.

Features

  • Lists all locally stored Docker images

  • Provides detailed image metadata and statistics

  • Shows image sizes and storage usage

  • Displays repository tags and digests

  • Includes creation timestamps and labels

  • Reports container usage counts

Security Considerations

This tool provides information that could be useful for:

  • **System Analysis**: Reveals installed software and versions

  • **Vulnerability Assessment**: Shows potential attack surfaces

  • **Resource Planning**: Exposes storage usage patterns

Monitor access to this tool in production environments.

Return Format

Returns an array of image objects with comprehensive metadata:

  • Repository tags and digests

  • Image sizes and virtual sizes

  • Creation timestamps

  • Container usage counts

  • Labels and annotations

  • Parent-child relationships

Example Usage

images = ListImages.call(server_context: context)
images.each do |image|
  puts "#{image['RepoTags']}: #{image['Size']} bytes"
end

See Also:

  • Docker::Image.all

Since:

  • 0.1.0

ToolForge.define(:list_images) do
  description 'List Docker images'

  execute do
    ::Docker::Image.all.map(&:info)
  end
end
ListImages =
LIST_IMAGES_DEFINITION.to_ruby_llm_tool
LIST_VOLUMES_DEFINITION =

MCP tool for listing Docker volumes.

This tool provides comprehensive information about all Docker volumes configured on the system. It returns detailed volume metadata including mount points, drivers, usage statistics, and associated containers.

Features

  • Lists all Docker volumes (named and anonymous)

  • Provides detailed volume metadata

  • Shows mount points and storage locations

  • Displays driver information and options

  • Includes creation timestamps and labels

  • Reports volume scope and capabilities

Security Considerations

Volume information can reveal sensitive details about:

  • **Data Storage**: Persistent data locations and structures

  • **File System Access**: Mount points and storage paths

  • **Container Dependencies**: Volume usage patterns

  • **Data Persistence**: Backup and recovery points

Monitor access to this tool and implement appropriate controls.

Return Format

Returns an array of volume objects with comprehensive metadata:

  • Volume names and mount points

  • Driver types and configurations

  • Creation timestamps

  • Labels and options

  • Scope information

  • Storage usage details

Example Usage

volumes = ListVolumes.call(server_context: context)
volumes.each do |volume|
  puts "#{volume['Name']}: #{volume['Mountpoint']}"
end

See Also:

  • Docker::Volume.all

Since:

  • 0.1.0

ToolForge.define(:list_volumes) do
  description 'List Docker volumes'

  execute do
    ::Docker::Volume.all.map(&:info)
  end
end
ListVolumes =
LIST_VOLUMES_DEFINITION.to_ruby_llm_tool
REMOVE_IMAGE_DEFINITION =

MCP tool for removing Docker images.

This tool provides the ability to delete Docker images from the local Docker daemon. It supports various removal options including forced removal and parent image cleanup management.

Features

  • Remove images by ID, name, or tag

  • Force removal of images in use

  • Control untagged parent image cleanup

  • Comprehensive error handling

  • Validation of image existence

  • Safe removal with dependency checking

Security Considerations

Image removal involves important considerations:

  • **Data Loss**: Removed images cannot be recovered locally

  • **Service Disruption**: Removing images used by running containers

  • **Storage Cleanup**: Improper cleanup can leave orphaned layers

  • **Registry Impact**: Local removal doesn’t affect registry copies

  • **Dependency Conflicts**: Force removal can break container dependencies

**Security Recommendations**:

  • Verify image is not in use before removal

  • Use force option only when necessary

  • Consider impact on running containers

  • Backup important images before removal

  • Monitor disk space after removal operations

  • Implement image lifecycle policies

Parameters

  • id: Image ID, name, or name:tag (required)

  • force: Force removal of the image (optional, default: false)

  • noprune: Do not delete untagged parents (optional, default: false)

Example Usage

# Remove specific image
response = RemoveImage.call(
  server_context: context,
  id: "myapp:old-version"
)

# Force remove image in use
response = RemoveImage.call(
  server_context: context,
  id: "abc123def456",
  force: true
)

# Remove without cleaning parent images
response = RemoveImage.call(
  server_context: context,
  id: "test-image:latest",
  noprune: true
)

See Also:

  • Docker::Image#remove

Since:

  • 0.1.0

ToolForge.define(:remove_image) do
  description 'Remove a Docker image'

  param :id,
        type: :string,
        description: 'Image ID, name, or name:tag'

  param :force,
        type: :boolean,
        description: 'Force removal of the image (default: false)',
        required: false,
        default: false

  param :noprune,
        type: :boolean,
        description: 'Do not delete untagged parents (default: false)',
        required: false,
        default: false

  execute do |id:, force: false, noprune: false|
    image = ::Docker::Image.get(id)
    image.remove(force: force, noprune: noprune)

    "Image #{id} removed successfully"
  rescue ::Docker::Error::NotFoundError
    "Image #{id} not found"
  rescue StandardError => e
    "Error removing image: #{e.message}"
  end
end
RemoveImage =
REMOVE_IMAGE_DEFINITION.to_ruby_llm_tool
CREATE_VOLUME_DEFINITION =

MCP tool for creating Docker volumes.

This tool provides the ability to create Docker volumes for persistent data storage. Volumes are essential for maintaining data across container lifecycles and enabling data sharing between containers.

Features

  • Create named Docker volumes

  • Support for multiple volume drivers

  • Persistent data storage management

  • Volume driver configuration

  • Comprehensive error handling

  • Volume lifecycle management

Security Considerations

Volume creation involves important security considerations:

  • **Data Persistence**: Volumes store data beyond container lifecycle

  • **Access Control**: Volume permissions affect data security

  • **Data Isolation**: Improper volumes can compromise data separation

  • **Storage Security**: Volume drivers may have security implications

  • **Resource Usage**: Volumes consume disk space and system resources

  • **Data Leakage**: Shared volumes can expose sensitive data

**Security Recommendations**:

  • Use appropriate volume drivers for security requirements

  • Implement proper access controls and permissions

  • Monitor volume usage and capacity

  • Regular backup of critical volume data

  • Audit volume access patterns

  • Use encryption for sensitive data volumes

  • Implement volume lifecycle policies

Parameters

  • name: Name of the volume (required)

  • driver: Driver to use (optional, default: “local”)

Volume Drivers

  • local: Default driver for local filesystem storage

  • nfs: Network File System driver for shared storage

  • cifs: Common Internet File System driver

  • rexray: REX-Ray driver for cloud storage integration

  • convoy: Convoy driver for snapshot management

Example Usage

# Create basic local volume
response = CreateVolume.call(
  server_context: context,
  name: "app-data"
)

# Create volume with specific driver
response = CreateVolume.call(
  server_context: context,
  name: "shared-storage",
  driver: "nfs"
)

# Create database volume
response = CreateVolume.call(
  server_context: context,
  name: "postgres-data",
  driver: "local"
)

See Also:

  • Docker::Volume.create

Since:

  • 0.1.0

ToolForge.define(:create_volume) do
  description 'Create a Docker volume'

  param :name,
        type: :string,
        description: 'Name of the volume'

  param :driver,
        type: :string,
        description: 'Driver to use (default: local)',
        required: false,
        default: 'local'

  execute do |name:, driver: 'local'|
    options = {
      'Name' => name,
      'Driver' => driver
    }

    ::Docker::Volume.create(name, options)

    "Volume #{name} created successfully"
  rescue ::Docker::Error::ConflictError
    "Volume #{name} already exists"
  rescue StandardError => e
    "Error creating volume: #{e.message}"
  end
end
CreateVolume =
CREATE_VOLUME_DEFINITION.to_ruby_llm_tool
LIST_NETWORKS_DEFINITION =

MCP tool for listing Docker networks.

This tool provides comprehensive information about all Docker networks configured on the system. It returns detailed network configuration including IPAM settings, connected containers, and network drivers.

Features

  • Lists all Docker networks (built-in and custom)

  • Provides detailed network configuration

  • Shows IPAM (IP Address Management) settings

  • Displays connected containers

  • Includes driver information and options

  • Reports network scope and capabilities

Security Considerations

Network information can be sensitive as it reveals:

  • **Network Topology**: Internal network architecture

  • **IP Addressing**: Subnet configurations and ranges

  • **Container Connectivity**: Service interconnections

  • **Network Isolation**: Security boundary configurations

Restrict access to this tool in production environments.

Return Format

Returns an array of network objects with comprehensive metadata:

  • Network names and IDs

  • Driver types and configurations

  • IPAM settings and subnet information

  • Connected container details

  • Network options and labels

  • Scope and capability flags

Example Usage

networks = ListNetworks.call(server_context: context)
networks.each do |network|
  puts "#{network['Name']}: #{network['Driver']}"
end

See Also:

  • Docker::Network.all

Since:

  • 0.1.0

ToolForge.define(:list_networks) do
  description 'List Docker networks'

  execute do
    ::Docker::Network.all.map(&:info)
  end
end
ListNetworks =
LIST_NETWORKS_DEFINITION.to_ruby_llm_tool
REMOVE_VOLUME_DEFINITION =

MCP tool for removing Docker volumes.

This tool provides the ability to delete Docker volumes when they are no longer needed. Volume removal is critical for preventing storage leaks and maintaining clean Docker environments.

Features

  • Remove volumes by name

  • Force removal of volumes in use

  • Validation of volume existence

  • Comprehensive error handling

  • Safe volume cleanup procedures

  • Prevention of accidental data loss

Security Considerations

Volume removal involves critical data considerations:

  • **Data Loss**: Removed volumes and their data are permanently deleted

  • **Service Disruption**: Removing volumes can break running containers

  • **Data Recovery**: Volume data cannot be recovered after removal

  • **Container Dependencies**: Applications may fail without expected volumes

  • **Storage Cleanup**: Improper removal can leave orphaned data

  • **Backup Requirements**: Critical data should be backed up before removal

**Security Recommendations**:

  • Always backup critical data before volume removal

  • Verify no containers are using the volume

  • Use force option only when absolutely necessary

  • Document volume removal in change management

  • Implement volume lifecycle and retention policies

  • Monitor storage usage after volume removal

  • Consider data migration instead of removal

Parameters

  • name: Volume name (required)

  • force: Force removal of the volume (optional, default: false)

Example Usage

# Remove unused volume
response = RemoveVolume.call(
  server_context: context,
  name: "old-app-data"
)

# Force remove volume in use
response = RemoveVolume.call(
  server_context: context,
  name: "stuck-volume",
  force: true
)

# Clean up test volumes
response = RemoveVolume.call(
  server_context: context,
  name: "test-data-volume"
)

See Also:

  • Docker::Volume#remove

Since:

  • 0.1.0

ToolForge.define(:remove_volume) do
  description 'Remove a Docker volume'

  param :name,
        type: :string,
        description: 'Volume name'

  param :force,
        type: :boolean,
        description: 'Force removal of the volume (default: false)',
        required: false,
        default: false

  execute do |name:, force: false|
    volume = ::Docker::Volume.get(name)
    volume.remove(force: force)

    "Volume #{name} removed successfully"
  rescue ::Docker::Error::NotFoundError
    "Volume #{name} not found"
  rescue StandardError => e
    "Error removing volume: #{e.message}"
  end
end
RemoveVolume =
REMOVE_VOLUME_DEFINITION.to_ruby_llm_tool
RUN_CONTAINER_DEFINITION =

MCP tool for running Docker containers.

This tool creates and immediately starts a Docker container from a specified image in a single operation. It combines the functionality of create_container and start_container for convenience when immediate execution is desired.

Features

  • Creates and starts containers in one operation

  • Supports all container configuration options

  • Configures command execution and environment variables

  • Sets up port exposure and network configuration

  • Applies advanced host configurations and volume mounts

  • Handles container naming and labeling

Security Considerations

Running containers involves significant security considerations:

  • **Immediate Execution**: Starts processes immediately upon creation

  • **Resource Consumption**: Consumes CPU, memory, and storage resources

  • **Network Exposure**: Creates active network endpoints

  • **File System Access**: Potentially accesses host directories

  • **Process Isolation**: Runs processes with configured privileges

Implement strict access controls and resource monitoring.

Parameters

  • image: Docker image to use (required)

  • name: Custom container name (optional)

  • cmd: Command to execute as space-separated string (optional)

  • env: Environment variables as comma-separated KEY=VALUE pairs (optional)

  • exposed_ports: Port exposure configuration as JSON object (optional)

  • host_config: Advanced host configuration as JSON object (optional)

Example Usage

# Simple container execution
response = RunContainer.call(
  server_context: context,
  image: "alpine:latest",
  cmd: "echo 'Hello World'"
)

# Web server with port binding
response = RunContainer.call(
  server_context: context,
  image: "nginx:latest",
  name: "web-server",
  exposed_ports: {"80/tcp" => {}},
  host_config: {
    "PortBindings" => {"80/tcp" => [{"HostPort" => "8080"}]}
  }
)

See Also:

  • Docker::Container.create

Since:

  • 0.1.0

ToolForge.define(:run_container) do
  description 'Run a Docker container (create and start)'

  param :image,
        type: :string,
        description: 'Image name to use (e.g., "ubuntu:22.04")'

  param :name,
        type: :string,
        description: 'Container name (optional)',
        required: false

  param :cmd,
        type: :string,
        description: 'Command to run as space-separated string (optional, e.g., "npm start" or "python app.py")',
        required: false

  param :env,
        type: :string,
        description: 'Environment variables as comma-separated KEY=VALUE pairs (optional)',
        required: false

  param :exposed_ports,
        type: :object,
        description: 'Exposed ports as {"port/protocol": {}} (optional)',
        required: false

  param :host_config,
        type: :object,
        description: 'Host configuration including port bindings, volumes, etc. (optional)',
        required: false

  execute do |image:, name: nil, cmd: nil, env: nil, exposed_ports: nil, host_config: nil|
    config = { 'Image' => image }
    config['name'] = name if name

    # Parse cmd string into array if provided
    config['Cmd'] = Shellwords.split(cmd) if cmd && !cmd.strip.empty?

    # Parse env string into array if provided
    config['Env'] = env.split(',').map(&:strip) if env && !env.strip.empty?

    config['ExposedPorts'] = exposed_ports if exposed_ports
    config['HostConfig'] = host_config if host_config

    container = ::Docker::Container.create(config)
    container.start
    container_name = container.info['Names']&.first&.delete_prefix('/')

    "Container started successfully. ID: #{container.id}, Name: #{container_name}"
  rescue ::Docker::Error::NotFoundError
    "Image #{image} not found"
  rescue ::Docker::Error::ConflictError
    "Container with name #{name} already exists"
  rescue StandardError => e
    "Error running container: #{e.message}"
  end
end
RunContainer =
RUN_CONTAINER_DEFINITION.to_ruby_llm_tool
CREATE_NETWORK_DEFINITION =

MCP tool for creating Docker networks.

This tool provides the ability to create custom Docker networks for container communication and isolation. Networks enable secure and controlled communication between containers and external systems.

Features

  • Create custom Docker networks

  • Support for multiple network drivers (bridge, overlay, host, etc.)

  • Duplicate name checking and validation

  • Network configuration and options

  • Comprehensive error handling

  • Network isolation and security controls

Security Considerations

Network creation involves important security considerations:

  • **Network Isolation**: Improper networks can compromise container isolation

  • **Traffic Control**: Networks affect inter-container communication

  • **External Access**: Bridge networks may expose containers externally

  • **Resource Usage**: Networks consume system resources

  • **DNS Resolution**: Custom networks affect service discovery

  • **Firewall Bypass**: Networks can bypass host firewall rules

**Security Recommendations**:

  • Use appropriate network drivers for use case

  • Implement network segmentation strategies

  • Monitor network traffic and usage

  • Avoid exposing internal networks externally

  • Use network policies for access control

  • Regular audit of network configurations

Parameters

  • name: Name of the network (required)

  • driver: Driver to use (optional, default: “bridge”)

  • check_duplicate: Check for networks with duplicate names (optional, default: true)

Network Drivers

  • bridge: Default driver for single-host networking

  • overlay: Multi-host networking for Docker Swarm

  • host: Uses host’s network stack directly

  • none: Disables networking for containers

  • macvlan: Assigns MAC addresses to containers

Example Usage

# Create basic bridge network
response = CreateNetwork.call(
  server_context: context,
  name: "app-network"
)

# Create overlay network for swarm
response = CreateNetwork.call(
  server_context: context,
  name: "swarm-network",
  driver: "overlay"
)

# Create network allowing duplicates
response = CreateNetwork.call(
  server_context: context,
  name: "test-network",
  driver: "bridge",
  check_duplicate: false
)

See Also:

  • Docker::Network.create

Since:

  • 0.1.0

ToolForge.define(:create_network) do
  description 'Create a Docker network'

  param :name,
        type: :string,
        description: 'Name of the network'

  param :driver,
        type: :string,
        description: 'Driver to use (default: bridge)',
        required: false,
        default: 'bridge'

  param :check_duplicate,
        type: :boolean,
        description: 'Check for networks with duplicate names (default: true)',
        required: false,
        default: true

  execute do |name:, driver: 'bridge', check_duplicate: true|
    options = {
      'Name' => name,
      'Driver' => driver,
      'CheckDuplicate' => check_duplicate
    }

    network = ::Docker::Network.create(name, options)

    "Network #{name} created successfully. ID: #{network.id}"
  rescue ::Docker::Error::ConflictError
    "Network #{name} already exists"
  rescue StandardError => e
    "Error creating network: #{e.message}"
  end
end
CreateNetwork =
CREATE_NETWORK_DEFINITION.to_ruby_llm_tool
EXEC_CONTAINER_DEFINITION =

MCP tool for executing commands inside Docker containers.

This tool provides the ability to execute arbitrary commands inside running Docker containers. It supports interactive and non-interactive execution, environment variable injection, working directory specification, and user context switching within the container.

Features

  • Execute arbitrary commands in running containers

  • Support for command arguments and shell parsing

  • Environment variable injection

  • Working directory specification

  • User context switching (run as specific user)

  • Standard input, output, and error handling

  • Configurable execution timeouts

Security Considerations

**CRITICAL WARNING**: This tool provides arbitrary command execution capabilities with significant security implications:

  • **Code Execution**: Can run any command available in the container

  • **File System Access**: Can read, write, and modify container files

  • **Network Access**: Can initiate network connections from container

  • **Process Manipulation**: Can start, stop, and signal processes

  • **Data Exposure**: Can access sensitive data within the container

  • **Privilege Escalation**: May exploit container or kernel vulnerabilities

  • **Resource Consumption**: Can consume container and host resources

**Security Recommendations**:

  • Implement strict access controls and authentication

  • Use dedicated execution containers with minimal privileges

  • Monitor and log all command executions

  • Apply resource limits and timeouts

  • Validate and sanitize all command inputs

  • Consider using read-only file systems where possible

  • Implement network segmentation for container environments

Parameters

  • id: Container ID or name (required)

  • cmd: Command to execute (shell-parsed into arguments) (required)

  • working_dir: Working directory for command execution (optional)

  • user: User to run the command as (optional, e.g., “1000” or “username”)

  • env: Environment variables as comma-separated KEY=VALUE pairs (optional)

  • stdin: Input to send to command via stdin (optional)

  • timeout: Timeout in seconds (optional, default: 60)

Example Usage

# Basic command execution
response = ExecContainer.call(
  server_context: context,
  id: "web-container",
  cmd: "nginx -t"
)

# Advanced execution with environment
response = ExecContainer.call(
  server_context: context,
  id: "app-container",
  cmd: "bundle exec rails console",
  working_dir: "/app",
  user: "rails",
  env: "RAILS_ENV=production,DEBUG=true",
  timeout: 300
)

See Also:

  • Docker::Container#exec

Since:

  • 0.1.0

ToolForge.define(:exec_container) do
  description 'Execute a command inside a running Docker container. ' \
              'WARNING: This provides arbitrary command execution within the container. ' \
              'Ensure proper security measures are in place.'

  param :id,
        type: :string,
        description: 'Container ID or name'

  param :cmd,
        type: :string,
        description: 'Command to execute (e.g., "ls -la /app" or "python script.py")'

  param :working_dir,
        type: :string,
        description: 'Working directory for the command (optional)',
        required: false

  param :user,
        type: :string,
        description: 'User to run the command as (optional, e.g., "1000" or "username")',
        required: false

  param :env,
        type: :string,
        description: 'Environment variables as comma-separated KEY=VALUE pairs (optional)',
        required: false

  param :stdin,
        type: :string,
        description: 'Input to send to the command via stdin (optional)',
        required: false

  param :timeout,
        type: :integer,
        description: 'Timeout in seconds (optional, default: 60)',
        required: false,
        default: 60

  execute do |id:, cmd:, working_dir: nil, user: nil, env: nil, stdin: nil, timeout: 60|
    container = ::Docker::Container.get(id)

    # Parse command string into array
    cmd_array = Shellwords.split(cmd)

    # Parse environment variables from comma-separated string to array
    env.split(',').map(&:strip) if env && !env.empty?

    # Execute the command
    stdout_data = []
    stderr_data = []
    exit_code = nil

    begin
      # Use container.exec which returns [stdout, stderr, exit_code]
      result = if stdin
                 container.exec(cmd_array, stdin: StringIO.new(stdin), wait: timeout)
               else
                 container.exec(cmd_array, wait: timeout)
               end

      stdout_data = result[0]
      stderr_data = result[1]
      exit_code = result[2]
    rescue ::Docker::Error::TimeoutError
      return "Command execution timed out after #{timeout} seconds"
    end

    # Format response
    response_text = "Command executed in container #{id}\n"
    response_text += "Exit code: #{exit_code}\n\n"

    if stdout_data && !stdout_data.empty?
      stdout_str = stdout_data.join
      response_text += "STDOUT:\n#{stdout_str}\n" unless stdout_str.strip.empty?
    end

    if stderr_data && !stderr_data.empty?
      stderr_str = stderr_data.join
      response_text += "\nSTDERR:\n#{stderr_str}\n" unless stderr_str.strip.empty?
    end

    response_text.strip
  rescue ::Docker::Error::NotFoundError
    "Container #{id} not found"
  rescue StandardError => e
    "Error executing command: #{e.message}"
  end
end
ExecContainer =
EXEC_CONTAINER_DEFINITION.to_ruby_llm_tool
REMOVE_NETWORK_DEFINITION =

MCP tool for removing Docker networks.

This tool provides the ability to delete Docker networks when they are no longer needed. Network removal helps maintain clean network configurations and prevents resource leaks.

Features

  • Remove networks by ID or name

  • Validation of network existence

  • Comprehensive error handling

  • Prevention of removing networks in use

  • Safe cleanup of network resources

  • Network dependency checking

Security Considerations

Network removal involves important considerations:

  • **Service Disruption**: Removing active networks disconnects containers

  • **Data Isolation**: Network removal can affect container communication

  • **Resource Cleanup**: Improper removal can leave network artifacts

  • **Container Dependencies**: Containers may fail without expected networks

  • **Network Policies**: Removal affects security and access policies

**Security Recommendations**:

  • Verify no containers are connected before removal

  • Check for dependent services and applications

  • Document network removal in change logs

  • Implement network lifecycle management

  • Monitor for orphaned network resources

  • Use network removal as part of cleanup procedures

Parameters

  • id: Network ID or name (required)

Example Usage

# Remove network by name
response = RemoveNetwork.call(
  server_context: context,
  id: "app-network"
)

# Remove network by ID
response = RemoveNetwork.call(
  server_context: context,
  id: "abc123def456"
)

# Clean up test networks
response = RemoveNetwork.call(
  server_context: context,
  id: "test-isolated-network"
)

See Also:

  • Docker::Network#delete

Since:

  • 0.1.0

ToolForge.define(:remove_network) do
  description 'Remove a Docker network'

  param :id,
        type: :string,
        description: 'Network ID or name'

  execute do |id:|
    network = ::Docker::Network.get(id)
    network.delete

    "Network #{id} removed successfully"
  rescue ::Docker::Error::NotFoundError
    "Network #{id} not found"
  rescue StandardError => e
    "Error removing network: #{e.message}"
  end
end
RemoveNetwork =
REMOVE_NETWORK_DEFINITION.to_ruby_llm_tool
STOP_CONTAINER_DEFINITION =

MCP tool for stopping Docker containers.

This tool gracefully stops a running Docker container by sending a SIGTERM signal to the main process, allowing it to shut down cleanly. If the container doesn’t stop within the specified timeout, it will be forcefully killed with SIGKILL.

Features

  • Graceful container shutdown with SIGTERM

  • Configurable timeout for forced termination

  • Supports container identification by ID or name

  • Handles both running and already-stopped containers

  • Provides clear feedback on operation status

  • Preserves container and data integrity

Security Considerations

Stopping containers affects service availability:

  • **Service Disruption**: Terminates running services and processes

  • **Data Integrity**: May interrupt ongoing operations

  • **Resource Release**: Frees CPU, memory, and network resources

  • **State Preservation**: Maintains container state for future restart

Coordinate container stops with dependent services and users.

Parameters

  • id: Container ID or name (required)

    • Accepts full container IDs

    • Accepts short container IDs (first 12+ characters)

    • Accepts custom container names

  • timeout: Seconds to wait before killing container (optional, default: 10)

Example Usage

# Stop with default timeout
response = StopContainer.call(
  server_context: context,
  id: "web-server"
)

# Stop with custom timeout
response = StopContainer.call(
  server_context: context,
  id: "database",
  timeout: 30
)

See Also:

  • Docker::Container#stop

Since:

  • 0.1.0

ToolForge.define(:stop_container) do
  description 'Stop a Docker container'

  param :id,
        type: :string,
        description: 'Container ID or name'

  param :timeout,
        type: :integer,
        description: 'Seconds to wait before killing the container (default: 10)',
        required: false,
        default: 10

  execute do |id:, timeout: 10|
    container = ::Docker::Container.get(id)
    container.stop('timeout' => timeout)

    "Container #{id} stopped successfully"
  rescue ::Docker::Error::NotFoundError
    "Container #{id} not found"
  rescue StandardError => e
    "Error stopping container: #{e.message}"
  end
end
StopContainer =
STOP_CONTAINER_DEFINITION.to_ruby_llm_tool
LIST_CONTAINERS_DEFINITION =

MCP tool for listing Docker containers.

This tool provides comprehensive information about all Docker containers on the system, including both running and stopped containers. It returns detailed metadata for each container including names, images, status, network configuration, and resource usage.

Features

  • Lists all containers (running and stopped)

  • Provides detailed container metadata

  • Shows network configuration and port mappings

  • Displays resource usage and statistics

  • Includes mount point information

  • Shows container labels and annotations

Security Considerations

This tool provides system information that could be useful for:

  • **System Reconnaissance**: Reveals running services and configurations

  • **Network Discovery**: Shows internal network topology

  • **Resource Analysis**: Exposes system resource usage patterns

Use with appropriate access controls in production environments.

Return Format

Returns an array of container objects with comprehensive metadata:

  • Container names and IDs

  • Image information and tags

  • Current state and status

  • Network settings and port bindings

  • Mount points and volumes

  • Labels and environment details

Example Usage

containers = ListContainers.call(server_context: context)
containers.each do |container|
  puts "#{container['Names'].first}: #{container['State']}"
end

See Also:

  • Docker::Container.all

Since:

  • 0.1.0

ToolForge.define(:list_containers) do
  description 'List Docker containers'

  param :all,
        type: :boolean,
        description: 'Show all containers (default shows all containers including stopped ones)',
        required: false,
        default: true

  execute do |all: true|
    ::Docker::Container.all(all: all).map(&:info)
  end
end
ListContainers =
LIST_CONTAINERS_DEFINITION.to_ruby_llm_tool
START_CONTAINER_DEFINITION =

MCP tool for starting Docker containers.

This tool starts a previously created Docker container that is currently in a “created” or “stopped” state. It transitions the container to a “running” state and begins executing the configured command or entrypoint.

Features

  • Starts containers by ID or name

  • Supports both short and full container IDs

  • Works with custom container names

  • Provides clear success/failure feedback

  • Handles container state transitions

  • Preserves all container configuration

Security Considerations

Starting containers involves security implications:

  • **Process Execution**: Begins running container processes

  • **Resource Activation**: Activates CPU, memory, and I/O usage

  • **Network Activation**: Brings network interfaces online

  • **Service Exposure**: Makes configured services accessible

Ensure proper monitoring and access controls are in place.

Parameters

  • id: Container ID or name (required)

    • Accepts full container IDs

    • Accepts short container IDs (first 12+ characters)

    • Accepts custom container names

Example Usage

# Start by container name
response = StartContainer.call(
  server_context: context,
  id: "web-server"
)

# Start by container ID
response = StartContainer.call(
  server_context: context,
  id: "a1b2c3d4e5f6"
)

See Also:

  • Docker::Container#start

Since:

  • 0.1.0

ToolForge.define(:start_container) do
  description 'Start a Docker container'

  param :id,
        type: :string,
        description: 'Container ID or name'

  execute do |id:|
    container = ::Docker::Container.get(id)
    container.start

    "Container #{id} started successfully"
  rescue ::Docker::Error::NotFoundError
    "Container #{id} not found"
  rescue StandardError => e
    "Error starting container: #{e.message}"
  end
end
StartContainer =
START_CONTAINER_DEFINITION.to_ruby_llm_tool
CREATE_CONTAINER_DEFINITION =

MCP tool for creating Docker containers.

This tool creates a new Docker container from a specified image without starting it. The container is created in a “created” state and can be started later using the start_container tool. This two-step process allows for container configuration before execution.

Features

  • Creates containers from any available Docker image

  • Supports custom container naming

  • Configures command execution and environment variables

  • Sets up port exposure and network configuration

  • Applies advanced host configurations

  • Handles container labeling and metadata

Security Considerations

Container creation is a powerful operation that can:

  • **Resource Allocation**: Consume system resources and storage

  • **Network Access**: Create network endpoints and bindings

  • **File System Access**: Mount host directories and volumes

  • **Security Context**: Run with elevated privileges if configured

Implement proper access controls and resource limits.

Parameters

  • image: Docker image to use (required)

  • name: Custom container name (optional)

  • cmd: Command to execute as space-separated string (optional)

  • env: Environment variables as comma-separated KEY=VALUE pairs (optional)

  • exposed_ports: Port exposure configuration as JSON object (optional)

  • host_config: Advanced host configuration as JSON object (optional)

Example Usage

# Simple container creation
response = CreateContainer.call(
  server_context: context,
  image: "nginx:latest",
  name: "web-server"
)

# Advanced container with configuration
response = CreateContainer.call(
  server_context: context,
  image: "postgres:13",
  name: "database",
  env: "POSTGRES_PASSWORD=secret,POSTGRES_DB=myapp",
  exposed_ports: {"5432/tcp" => {}},
  host_config: {
    "PortBindings" => {"5432/tcp" => [{"HostPort" => "5432"}]},
    "Binds" => ["/host/data:/var/lib/postgresql/data:rw"]
  }
)

See Also:

  • Docker::Container.create

Since:

  • 0.1.0

ToolForge.define(:create_container) do
  description 'Create a Docker container'

  param :image,
        type: :string,
        description: 'Image name to use (e.g., "ubuntu:22.04")'

  param :name,
        type: :string,
        description: 'Container name (optional)',
        required: false

  param :cmd,
        type: :string,
        description: 'Command to run as space-separated string (optional, e.g., "npm start" or "python app.py")',
        required: false

  param :env,
        type: :string,
        description: 'Environment variables as comma-separated KEY=VALUE pairs (optional)',
        required: false

  param :exposed_ports,
        type: :object,
        description: 'Exposed ports as {"port/protocol": {}} (optional)',
        required: false

  param :host_config,
        type: :object,
        description: 'Host configuration including port bindings, volumes, etc. (optional)',
        required: false

  execute do |image:, name: nil, cmd: nil, env: nil, exposed_ports: nil, host_config: nil|
    config = { 'Image' => image }
    config['name'] = name if name

    # Parse cmd string into array if provided
    config['Cmd'] = Shellwords.split(cmd) if cmd && !cmd.strip.empty?

    # Parse env string into array if provided
    config['Env'] = env.split(',').map(&:strip) if env && !env.strip.empty?

    config['ExposedPorts'] = exposed_ports if exposed_ports
    config['HostConfig'] = host_config if host_config

    container = ::Docker::Container.create(config)
    container_name = container.info['Names']&.first&.delete_prefix('/')

    "Container created successfully. ID: #{container.id}, Name: #{container_name}"
  rescue ::Docker::Error::NotFoundError
    "Image #{image} not found"
  rescue ::Docker::Error::ConflictError
    "Container with name #{name} already exists"
  rescue StandardError => e
    "Error creating container: #{e.message}"
  end
end
CreateContainer =
CREATE_CONTAINER_DEFINITION.to_ruby_llm_tool
REMOVE_CONTAINER_DEFINITION =

MCP tool for removing Docker containers.

This tool permanently removes a Docker container from the system, including its file system, configuration, and metadata. This is a destructive operation that cannot be undone. The container must be stopped before removal unless force is specified.

Features

  • Permanent container removal from system

  • Supports forced removal of running containers

  • Optional removal of associated volumes

  • Handles container identification by ID or name

  • Provides comprehensive error handling

  • Frees all associated system resources

Security Considerations

Container removal is a destructive operation with implications:

  • **Data Loss**: Permanently destroys container file system

  • **Configuration Loss**: Removes container settings and metadata

  • **Service Disruption**: Eliminates containerized services

  • **Resource Recovery**: Frees storage, memory, and system resources

  • **Audit Trail**: May remove forensic evidence if needed

Implement proper backup and approval workflows for production systems.

Parameters

  • id: Container ID or name (required)

    • Accepts full container IDs

    • Accepts short container IDs (first 12+ characters)

    • Accepts custom container names

  • force: Force removal of running container (optional, default: false)

  • volumes: Remove associated volumes (optional, default: false)

Example Usage

# Remove stopped container
response = RemoveContainer.call(
  server_context: context,
  id: "old-web-server"
)

# Force remove running container with volumes
response = RemoveContainer.call(
  server_context: context,
  id: "problematic-container",
  force: true,
  volumes: true
)

See Also:

  • Docker::Container#remove

Since:

  • 0.1.0

ToolForge.define(:remove_container) do
  description 'Remove a Docker container'

  param :id,
        type: :string,
        description: 'Container ID or name'

  param :force,
        type: :boolean,
        description: 'Force removal of running container (default: false)',
        required: false,
        default: false

  param :volumes,
        type: :boolean,
        description: 'Remove associated volumes (default: false)',
        required: false,
        default: false

  execute do |id:, force: false, volumes: false|
    container = ::Docker::Container.get(id)
    container.delete(force: force, v: volumes)

    "Container #{id} removed successfully"
  rescue ::Docker::Error::NotFoundError
    "Container #{id} not found"
  rescue StandardError => e
    "Error removing container: #{e.message}"
  end
end
RemoveContainer =
REMOVE_CONTAINER_DEFINITION.to_ruby_llm_tool
COPY_TO_CONTAINER_DEFINITION =

MCP tool for copying files and directories to Docker containers.

This tool provides the ability to copy files and directories from the local host filesystem into running Docker containers. It supports both individual files and entire directory trees, with optional ownership modification within the container.

Features

  • Copy files and directories from host to container

  • Supports recursive directory copying

  • Preserves file permissions and metadata

  • Optional ownership modification after copy

  • Works with running containers

  • Comprehensive error handling and validation

Security Considerations

File copying operations have significant security implications:

  • **File System Access**: Reads local host file system content

  • **Container Modification**: Alters container file system state

  • **Data Injection**: Can introduce malicious files into containers

  • **Permission Escalation**: May affect container security context

  • **Resource Consumption**: Large copies can consume storage and I/O

  • **Path Traversal**: Improper paths could access unintended locations

**Security Recommendations**:

  • Validate and sanitize all file paths

  • Implement access controls for source file locations

  • Monitor file copy operations and sizes

  • Use read-only mounts where possible

  • Apply resource limits to prevent abuse

Parameters

  • id: Container ID or name (required)

  • source_path: Path to file/directory on local filesystem (required)

  • destination_path: Path inside container for copied content (required)

  • owner: Owner for copied files (optional, e.g., “1000:1000” or “username:group”)

Example Usage

# Copy single file
response = CopyToContainer.call(
  server_context: context,
  id: "web-server",
  source_path: "/local/config.conf",
  destination_path: "/etc/nginx/nginx.conf"
)

# Copy directory with ownership change
response = CopyToContainer.call(
  server_context: context,
  id: "app-container",
  source_path: "/local/app-data",
  destination_path: "/var/lib/app",
  owner: "app:app"
)

See Also:

  • Docker::Container#archive_in_stream

Since:

  • 0.1.0

ToolForge.define(:copy_to_container) do
  description 'Copy a file or directory from the local filesystem into a running Docker container. ' \
              'The source path is on the local machine, and the destination path is inside the container.'

  param :id,
        type: :string,
        description: 'Container ID or name'

  param :source_path,
        type: :string,
        description: 'Path to the file or directory on the local filesystem to copy'

  param :destination_path,
        type: :string,
        description: 'Path inside the container where the file/directory should be copied'

  param :owner,
        type: :string,
        description: 'Owner for the copied files (optional, e.g., "1000:1000" or "username:group")',
        required: false

  # Helper method for adding files/directories to tar
  class_helper :add_to_tar do |tar, path, archive_path|
    if File.directory?(path)
      # Add directory entry
      tar.mkdir(archive_path, File.stat(path).mode)

      # Add directory contents
      Dir.entries(path).each do |entry|
        next if ['.', '..'].include?(entry)

        full_path = File.join(path, entry)
        archive_entry_path = File.join(archive_path, entry)
        add_to_tar(tar, full_path, archive_entry_path)
      end
    else
      # Add file
      File.open(path, 'rb') do |file|
        tar.add_file_simple(archive_path, File.stat(path).mode, file.size) do |tar_file|
          IO.copy_stream(file, tar_file)
        end
      end
    end
  end

  execute do |id:, source_path:, destination_path:, owner: nil|
    container = ::Docker::Container.get(id)

    # Verify source path exists
    next "Source path not found: #{source_path}" unless File.exist?(source_path)

    # Create a tar archive of the source
    tar_io = StringIO.new
    tar_io.set_encoding('ASCII-8BIT')

    Gem::Package::TarWriter.new(tar_io) do |tar|
      add_to_tar(tar, source_path, File.basename(source_path))
    end

    tar_io.rewind

    # Copy to container
    container.archive_in_stream(destination_path) do
      tar_io.read
    end

    # Optionally change ownership
    if owner
      chown_path = File.join(destination_path, File.basename(source_path))
      container.exec(['chown', '-R', owner, chown_path])
    end

    file_type = File.directory?(source_path) ? 'directory' : 'file'
    response_text = "Successfully copied #{file_type} from #{source_path} to #{id}:#{destination_path}"
    response_text += "\nOwnership changed to #{owner}" if owner
    response_text
  rescue ::Docker::Error::NotFoundError
    "Container #{id} not found"
  rescue StandardError => e
    "Error copying to container: #{e.message}"
  end
end
CopyToContainer =
COPY_TO_CONTAINER_DEFINITION.to_ruby_llm_tool
RECREATE_CONTAINER_DEFINITION =

MCP tool for recreating Docker containers.

This tool provides a complete container recreation process that stops the existing container, removes it, and creates a new container with the same configuration. This is useful for applying image updates, clearing container state, or resolving container corruption issues.

Features

  • Complete container recreation with preserved configuration

  • Automatic stop, remove, and recreate sequence

  • Preserves original container configuration and settings

  • Configurable stop timeout for graceful shutdown

  • Handles both running and stopped containers

  • Maintains container networking and volume configurations

Security Considerations

Container recreation involves several security considerations:

  • **Service Downtime**: Temporary service interruption during recreation

  • **Data Loss**: Container file system changes are lost (volumes preserved)

  • **Resource Allocation**: New container may have different resource usage

  • **Network Reconfiguration**: IP addresses may change

  • **State Reset**: Application state within container is lost

Plan recreations carefully and coordinate with dependent services.

Parameters

  • id: Container ID or name to recreate (required)

  • timeout: Seconds to wait before killing container when stopping (optional, default: 10)

Process Flow

  1. Inspect existing container to capture configuration

  2. Stop the running container (if running)

  3. Remove the stopped container

  4. Create new container with captured configuration

  5. Return new container information

Example Usage

# Recreate with default timeout
response = RecreateContainer.call(
  server_context: context,
  id: "web-server"
)

# Recreate with extended timeout
response = RecreateContainer.call(
  server_context: context,
  id: "database",
  timeout: 30
)

See Also:

  • Docker::Container#stop
  • Docker::Container#remove
  • Docker::Container.create

Since:

  • 0.1.0

ToolForge.define(:recreate_container) do
  description 'Recreate a Docker container (stops, removes, and recreates with same configuration)'

  param :id,
        type: :string,
        description: 'Container ID or name to recreate'

  param :timeout,
        type: :integer,
        description: 'Seconds to wait before killing the container when stopping (default: 10)',
        required: false,
        default: 10

  execute do |id:, timeout: 10|
    # Get the existing container
    old_container = ::Docker::Container.get(id)
    config = old_container.json

    # Extract configuration we need to preserve
    image = config['Config']['Image']
    name = config['Name']&.delete_prefix('/')
    cmd = config['Config']['Cmd']
    env = config['Config']['Env']
    exposed_ports = config['Config']['ExposedPorts']
    host_config = config['HostConfig']

    # Stop and remove the old container
    old_container.stop('timeout' => timeout) if config['State']['Running']
    old_container.delete

    # Create new container with same config
    new_config = {
      'Image' => image,
      'Cmd' => cmd,
      'Env' => env,
      'ExposedPorts' => exposed_ports,
      'HostConfig' => host_config
    }
    new_config['name'] = name if name

    new_container = ::Docker::Container.create(new_config)

    # Start if the old one was running
    new_container.start if config['State']['Running']

    "Container #{id} recreated successfully. New ID: #{new_container.id}"
  rescue ::Docker::Error::NotFoundError
    "Container #{id} not found"
  rescue StandardError => e
    "Error recreating container: #{e.message}"
  end
end
RecreateContainer =
RECREATE_CONTAINER_DEFINITION.to_ruby_llm_tool
FETCH_CONTAINER_LOGS_DEFINITION =

MCP tool for fetching Docker container logs.

This tool retrieves log output from Docker containers, including both standard output and standard error streams. It supports filtering by stream type, limiting output length, timestamp inclusion, and retrieving logs from both running and stopped containers.

Features

  • Fetch logs from running and stopped containers

  • Separate or combined stdout and stderr streams

  • Configurable output length limiting (tail functionality)

  • Optional timestamp inclusion for log entries

  • Support for container identification by ID or name

  • Comprehensive error handling and status reporting

Security Considerations

Container logs may contain sensitive information:

  • **Application Data**: Database queries, API keys, user data

  • **System Information**: Internal paths, configuration details

  • **Error Details**: Stack traces revealing application internals

  • **Access Patterns**: User behavior and system usage information

  • **Debugging Information**: Temporary credentials or session data

Implement proper access controls and data sanitization for log access.

Parameters

  • id: Container ID or name (required)

  • stdout: Include stdout in logs (optional, default: true)

  • stderr: Include stderr in logs (optional, default: true)

  • timestamps: Show timestamps for log entries (optional, default: false)

  • tail: Number of lines to show from end of logs (optional, default: all)

Example Usage

# Fetch all logs
response = FetchContainerLogs.call(
  server_context: context,
  id: "web-server"
)

# Fetch recent errors with timestamps
response = FetchContainerLogs.call(
  server_context: context,
  id: "app-container",
  stdout: false,
  stderr: true,
  timestamps: true,
  tail: 100
)

See Also:

  • Docker::Container#logs

Since:

  • 0.1.0

ToolForge.define(:fetch_container_logs) do
  description 'Fetch Docker container logs'

  param :id,
        type: :string,
        description: 'Container ID or name'

  param :stdout,
        type: :boolean,
        description: 'Include stdout (default: true)',
        required: false,
        default: true

  param :stderr,
        type: :boolean,
        description: 'Include stderr (default: true)',
        required: false,
        default: true

  param :tail,
        type: :integer,
        description: 'Number of lines to show from the end of logs (default: all)',
        required: false

  param :timestamps,
        type: :boolean,
        description: 'Show timestamps (default: false)',
        required: false,
        default: false

  execute do |id:, stdout: true, stderr: true, tail: nil, timestamps: false|
    container = ::Docker::Container.get(id)

    options = {
      stdout: stdout,
      stderr: stderr,
      timestamps: timestamps
    }
    options[:tail] = tail if tail

    container.logs(options)
  rescue ::Docker::Error::NotFoundError
    "Container #{id} not found"
  rescue StandardError => e
    "Error fetching logs: #{e.message}"
  end
end
FetchContainerLogs =
FETCH_CONTAINER_LOGS_DEFINITION.to_ruby_llm_tool

Class Method Summary collapse

Class Method Details

.add_all_tools_to_chat(chat) ⇒ Object

Helper method to add all Docker tools to a RubyLLM chat instance



66
67
68
69
70
71
# File 'lib/ruby_llm/docker.rb', line 66

def self.add_all_tools_to_chat(chat)
  all_tools.each do |tool_class|
    chat.with_tool(tool_class)
  end
  chat
end

.all_toolsObject

Helper method to get all Docker tool classes



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/ruby_llm/docker.rb', line 31

def self.all_tools
  [
    # Container Management
    ListContainers,
    CreateContainer,
    RunContainer,
    StartContainer,
    StopContainer,
    RemoveContainer,
    RecreateContainer,
    ExecContainer,
    CopyToContainer,
    FetchContainerLogs,

    # Image Management
    ListImages,
    PullImage,
    BuildImage,
    TagImage,
    PushImage,
    RemoveImage,

    # Network Management
    ListNetworks,
    CreateNetwork,
    RemoveNetwork,

    # Volume Management
    ListVolumes,
    CreateVolume,
    RemoveVolume
  ]
end