docker_mcp 0.0.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DockerMCP
4
+ # MCP tool for removing Docker networks.
5
+ #
6
+ # This tool provides the ability to permanently delete Docker networks from
7
+ # the system. It safely removes custom networks while protecting built-in
8
+ # system networks from accidental deletion.
9
+ #
10
+ # == Features
11
+ #
12
+ # - Remove custom Docker networks by ID or name
13
+ # - Protection against removing built-in networks
14
+ # - Comprehensive error handling
15
+ # - Dependency checking (prevents removal if containers are connected)
16
+ # - Safe cleanup of network resources
17
+ #
18
+ # == ⚠️ Service Disruption Warning ⚠️
19
+ #
20
+ # **NETWORK REMOVAL CAN DISRUPT SERVICES**
21
+ #
22
+ # Removing networks can cause immediate service disruption:
23
+ # - Connected containers lose network connectivity
24
+ # - Inter-container communication is broken
25
+ # - Services may become unreachable
26
+ # - Application functionality can be severely impacted
27
+ # - Network-dependent processes may fail
28
+ #
29
+ # == Protected Networks
30
+ #
31
+ # Docker protects certain built-in networks from removal:
32
+ # - **bridge**: Default bridge network
33
+ # - **host**: Host networking
34
+ # - **none**: No networking
35
+ # - **System networks**: Docker-managed networks
36
+ #
37
+ # == Security Considerations
38
+ #
39
+ # Network removal affects security boundaries:
40
+ # - Removes network isolation between containers
41
+ # - May expose containers to unintended networks
42
+ # - Could impact security segmentation strategies
43
+ # - Affects network-based access controls
44
+ #
45
+ # Security implications:
46
+ # - Ensure no critical containers depend on the network
47
+ # - Verify alternative connectivity exists if needed
48
+ # - Consider impact on security boundaries
49
+ # - Monitor for unauthorized network modifications
50
+ #
51
+ # Best practices:
52
+ # - Stop containers before removing their networks
53
+ # - Verify network dependencies before removal
54
+ # - Have rollback plans for critical networks
55
+ # - Document network removal procedures
56
+ # - Monitor network connectivity after removal
57
+ #
58
+ # == Example Usage
59
+ #
60
+ # # Remove custom network
61
+ # RemoveNetwork.call(
62
+ # server_context: context,
63
+ # id: "app-network"
64
+ # )
65
+ #
66
+ # # Remove by network ID
67
+ # RemoveNetwork.call(
68
+ # server_context: context,
69
+ # id: "abc123def456"
70
+ # )
71
+ #
72
+ # @see CreateNetwork
73
+ # @see ListNetworks
74
+ # @see Docker::Network#delete
75
+ # @since 0.1.0
76
+ class RemoveNetwork < MCP::Tool
77
+ description 'Remove a Docker network'
78
+
79
+ input_schema(
80
+ properties: {
81
+ id: {
82
+ type: 'string',
83
+ description: 'Network ID or name'
84
+ }
85
+ },
86
+ required: ['id']
87
+ )
88
+
89
+ # Remove a Docker network from the system.
90
+ #
91
+ # This method permanently deletes the specified network. The network
92
+ # must not have any containers connected to it, and built-in system
93
+ # networks cannot be removed.
94
+ #
95
+ # @param id [String] network ID or name to remove
96
+ # @param server_context [Object] MCP server context (unused but required)
97
+ #
98
+ # @return [MCP::Tool::Response] removal operation results
99
+ #
100
+ # @raise [Docker::Error::NotFoundError] if network doesn't exist
101
+ # @raise [StandardError] for removal failures or dependency conflicts
102
+ #
103
+ # @example Remove custom network
104
+ # response = RemoveNetwork.call(
105
+ # server_context: context,
106
+ # id: "frontend-network"
107
+ # )
108
+ #
109
+ # @example Remove by ID
110
+ # response = RemoveNetwork.call(
111
+ # server_context: context,
112
+ # id: "1a2b3c4d5e6f"
113
+ # )
114
+ #
115
+ # @see Docker::Network#delete
116
+ def self.call(id:, server_context:)
117
+ network = Docker::Network.get(id)
118
+ network.delete
119
+
120
+ MCP::Tool::Response.new([{
121
+ type: 'text',
122
+ text: "Network #{id} removed successfully"
123
+ }])
124
+ rescue Docker::Error::NotFoundError
125
+ MCP::Tool::Response.new([{
126
+ type: 'text',
127
+ text: "Network #{id} not found"
128
+ }])
129
+ rescue StandardError => e
130
+ MCP::Tool::Response.new([{
131
+ type: 'text',
132
+ text: "Error removing network: #{e.message}"
133
+ }])
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,146 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DockerMCP
4
+ # MCP tool for removing Docker volumes.
5
+ #
6
+ # This tool provides the ability to permanently delete Docker volumes from
7
+ # the system. This is a destructive operation that will permanently delete
8
+ # all data stored in the volume.
9
+ #
10
+ # == Features
11
+ #
12
+ # - Remove Docker volumes by name
13
+ # - Force removal option for volumes in use
14
+ # - Comprehensive error handling
15
+ # - Dependency checking (prevents removal if containers are using the volume)
16
+ # - Safe cleanup of storage resources
17
+ #
18
+ # == ⚠️ CRITICAL DATA LOSS WARNING ⚠️
19
+ #
20
+ # **DESTRUCTIVE OPERATION - PERMANENT DATA LOSS**
21
+ #
22
+ # This operation permanently and irreversibly deletes data:
23
+ # - **ALL DATA** in the volume is deleted forever
24
+ # - No recovery possible after deletion
25
+ # - Applications may lose critical data
26
+ # - Databases and persistent state are destroyed
27
+ # - Configuration files and user data are lost
28
+ # - Operation cannot be undone
29
+ #
30
+ # == Volume Dependencies
31
+ #
32
+ # Volumes may have active dependencies:
33
+ # - **Running Containers**: Containers currently using the volume
34
+ # - **Stopped Containers**: Containers that could be restarted
35
+ # - **Application Data**: Critical application state and databases
36
+ # - **User Data**: User-generated content and files
37
+ #
38
+ # == Security Considerations
39
+ #
40
+ # Volume removal has security implications:
41
+ # - Sensitive data is not securely wiped
42
+ # - Data may be recoverable from disk sectors
43
+ # - Shared volumes may affect multiple applications
44
+ # - Removal logs may reveal data existence
45
+ #
46
+ # Critical security measures:
47
+ # - **Backup critical data** before removal
48
+ # - Verify no containers depend on the volume
49
+ # - Consider secure data wiping for sensitive volumes
50
+ # - Audit volume removal operations
51
+ # - Monitor for unauthorized volume deletions
52
+ #
53
+ # == Force Removal Risks
54
+ #
55
+ # Force removal bypasses safety checks:
56
+ # - Removes volumes even if containers are using them
57
+ # - Can cause immediate application failures
58
+ # - May corrupt running applications
59
+ # - Data loss occurs immediately
60
+ #
61
+ # == Example Usage
62
+ #
63
+ # # Safe removal of unused volume
64
+ # RemoveVolume.call(
65
+ # server_context: context,
66
+ # name: "temp-data"
67
+ # )
68
+ #
69
+ # # Force removal of volume in use (DANGEROUS)
70
+ # RemoveVolume.call(
71
+ # server_context: context,
72
+ # name: "stuck-volume",
73
+ # force: true
74
+ # )
75
+ #
76
+ # @see CreateVolume
77
+ # @see ListVolumes
78
+ # @see Docker::Volume#remove
79
+ # @since 0.1.0
80
+ class RemoveVolume < MCP::Tool
81
+ description 'Remove a Docker volume'
82
+
83
+ input_schema(
84
+ properties: {
85
+ name: {
86
+ type: 'string',
87
+ description: 'Volume name'
88
+ },
89
+ force: {
90
+ type: 'boolean',
91
+ description: 'Force removal of the volume (default: false)'
92
+ }
93
+ },
94
+ required: ['name']
95
+ )
96
+
97
+ # Remove a Docker volume permanently from the system.
98
+ #
99
+ # This method permanently deletes the specified volume and all data
100
+ # contained within it. By default, it performs safety checks to prevent
101
+ # removal of volumes with active container dependencies.
102
+ #
103
+ # @param name [String] name of the volume to remove
104
+ # @param server_context [Object] MCP server context (unused but required)
105
+ # @param force [Boolean] whether to force removal despite dependencies (default: false)
106
+ #
107
+ # @return [MCP::Tool::Response] removal operation results
108
+ #
109
+ # @raise [Docker::Error::NotFoundError] if volume doesn't exist
110
+ # @raise [StandardError] for removal failures or dependency conflicts
111
+ #
112
+ # @example Remove unused volume
113
+ # response = RemoveVolume.call(
114
+ # server_context: context,
115
+ # name: "old-cache-data"
116
+ # )
117
+ #
118
+ # @example Force remove problematic volume
119
+ # response = RemoveVolume.call(
120
+ # server_context: context,
121
+ # name: "corrupted-volume",
122
+ # force: true
123
+ # )
124
+ #
125
+ # @see Docker::Volume#remove
126
+ def self.call(name:, server_context:, force: false)
127
+ volume = Docker::Volume.get(name)
128
+ volume.remove(force: force)
129
+
130
+ MCP::Tool::Response.new([{
131
+ type: 'text',
132
+ text: "Volume #{name} removed successfully"
133
+ }])
134
+ rescue Docker::Error::NotFoundError
135
+ MCP::Tool::Response.new([{
136
+ type: 'text',
137
+ text: "Volume #{name} not found"
138
+ }])
139
+ rescue StandardError => e
140
+ MCP::Tool::Response.new([{
141
+ type: 'text',
142
+ text: "Error removing volume: #{e.message}"
143
+ }])
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DockerMCP
4
+ # MCP tool for running Docker containers (create and start in one operation).
5
+ #
6
+ # This tool provides a convenient way to create and immediately start Docker
7
+ # containers from images. It combines the functionality of container creation
8
+ # and startup into a single operation, which is the most common use case for
9
+ # Docker containers.
10
+ #
11
+ # == Features
12
+ #
13
+ # - Create and start containers in one operation
14
+ # - Full support for container configuration options
15
+ # - Port mapping and network configuration
16
+ # - Volume mounting capabilities
17
+ # - Environment variable configuration
18
+ # - Custom command execution
19
+ # - Comprehensive error handling
20
+ #
21
+ # == Security Considerations
22
+ #
23
+ # - Containers inherit Docker daemon privileges
24
+ # - Port mappings expose services to host network
25
+ # - Volume mounts provide filesystem access
26
+ # - Environment variables may contain sensitive data
27
+ # - Custom commands can execute arbitrary code
28
+ #
29
+ # Use appropriate security measures:
30
+ # - Run containers with minimal required privileges
31
+ # - Limit port exposure to necessary services only
32
+ # - Use read-only volumes where possible
33
+ # - Avoid mounting sensitive host directories
34
+ # - Validate environment variables for secrets
35
+ #
36
+ # == Example Usage
37
+ #
38
+ # # Simple container run
39
+ # RunContainer.call(
40
+ # server_context: context,
41
+ # image: "nginx:latest",
42
+ # name: "web-server"
43
+ # )
44
+ #
45
+ # # Advanced configuration with ports and volumes
46
+ # RunContainer.call(
47
+ # server_context: context,
48
+ # image: "postgres:13",
49
+ # name: "database",
50
+ # env: ["POSTGRES_PASSWORD=secret"],
51
+ # host_config: {
52
+ # "PortBindings" => {"5432/tcp" => [{"HostPort" => "5432"}]},
53
+ # "Binds" => ["/host/data:/var/lib/postgresql/data"]
54
+ # }
55
+ # )
56
+ #
57
+ # @see CreateContainer
58
+ # @see StartContainer
59
+ # @see Docker::Container.create
60
+ # @since 0.1.0
61
+ class RunContainer < MCP::Tool
62
+ description 'Run a Docker container (create and start)'
63
+
64
+ input_schema(
65
+ properties: {
66
+ image: {
67
+ type: 'string',
68
+ description: 'Image name to use (e.g., "ubuntu:22.04")'
69
+ },
70
+ name: {
71
+ type: 'string',
72
+ description: 'Container name (optional)'
73
+ },
74
+ cmd: {
75
+ type: 'array',
76
+ items: { type: 'string' },
77
+ description: 'Command to run (optional)'
78
+ },
79
+ env: {
80
+ type: 'array',
81
+ items: { type: 'string' },
82
+ description: 'Environment variables as KEY=VALUE (optional)'
83
+ },
84
+ exposed_ports: {
85
+ type: 'object',
86
+ description: 'Exposed ports as {"port/protocol": {}} (optional)'
87
+ },
88
+ host_config: {
89
+ type: 'object',
90
+ description: 'Host configuration including port bindings, volumes, etc. (optional)'
91
+ }
92
+ },
93
+ required: ['image']
94
+ )
95
+
96
+ def self.call(image:, server_context:, name: nil, cmd: nil, env: nil, exposed_ports: nil, host_config: nil)
97
+ config = { 'Image' => image }
98
+ config['name'] = name if name
99
+ config['Cmd'] = cmd if cmd
100
+ config['Env'] = env if env
101
+ config['ExposedPorts'] = exposed_ports if exposed_ports
102
+ config['HostConfig'] = host_config if host_config
103
+
104
+ container = Docker::Container.create(config)
105
+ container.start
106
+ container_name = container.info['Names']&.first&.delete_prefix('/')
107
+
108
+ MCP::Tool::Response.new([{
109
+ type: 'text',
110
+ text: "Container started successfully. ID: #{container.id}, Name: #{container_name}"
111
+ }])
112
+ rescue Docker::Error::NotFoundError
113
+ MCP::Tool::Response.new([{
114
+ type: 'text',
115
+ text: "Image #{image} not found"
116
+ }])
117
+ rescue Docker::Error::ConflictError
118
+ MCP::Tool::Response.new([{
119
+ type: 'text',
120
+ text: "Container with name #{name} already exists"
121
+ }])
122
+ rescue StandardError => e
123
+ MCP::Tool::Response.new([{
124
+ type: 'text',
125
+ text: "Error running container: #{e.message}"
126
+ }])
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DockerMCP
4
+ # MCP Server implementation for Docker management tools.
5
+ #
6
+ # The Server class initializes and configures a Model Context Protocol server
7
+ # with all available Docker management tools. It serves as the main entry point
8
+ # for Docker operations through the MCP interface.
9
+ #
10
+ # The server provides 22 comprehensive tools organized into four categories:
11
+ # - Container Management: 10 tools for container lifecycle operations
12
+ # - Image Management: 6 tools for Docker image operations
13
+ # - Network Management: 3 tools for Docker network operations
14
+ # - Volume Management: 3 tools for Docker volume operations
15
+ #
16
+ # == Security Considerations
17
+ #
18
+ # This server includes potentially dangerous tools that can:
19
+ # - Execute arbitrary commands in containers (ExecContainer)
20
+ # - Copy files between host and containers (CopyToContainer)
21
+ # - Create, modify, and delete Docker resources
22
+ #
23
+ # Ensure proper security measures when exposing this server to external clients.
24
+ #
25
+ # == Example Usage
26
+ #
27
+ # # Initialize the server
28
+ # server = DockerMCP::Server.new
29
+ #
30
+ # # Access the underlying MCP server
31
+ # mcp_server = server.server
32
+ #
33
+ # # The server automatically registers all available tools
34
+ #
35
+ # @see MCP::Server
36
+ # @since 0.1.0
37
+ class Server
38
+ # The underlying MCP::Server instance.
39
+ #
40
+ # @return [MCP::Server] the configured MCP server with all Docker tools
41
+ attr_reader :server
42
+
43
+ # Initialize a new DockerMCP server with all available tools.
44
+ #
45
+ # Creates and configures an MCP::Server instance with all 22 Docker
46
+ # management tools. The tools are automatically loaded and registered
47
+ # with the server.
48
+ #
49
+ # Tools are registered in alphabetical order for consistency:
50
+ # - BuildImage: Build Docker images from Dockerfiles
51
+ # - CopyToContainer: Copy files/directories from host to container
52
+ # - CreateContainer: Create new containers from images
53
+ # - CreateNetwork: Create Docker networks
54
+ # - CreateVolume: Create Docker volumes
55
+ # - ExecContainer: Execute commands inside containers
56
+ # - FetchContainerLogs: Retrieve container logs
57
+ # - ListContainers: List all containers
58
+ # - ListImages: List all images
59
+ # - ListNetworks: List all networks
60
+ # - ListVolumes: List all volumes
61
+ # - PullImage: Pull images from registries
62
+ # - PushImage: Push images to registries
63
+ # - RecreateContainer: Recreate containers with same config
64
+ # - RemoveContainer: Delete containers
65
+ # - RemoveImage: Delete images
66
+ # - RemoveNetwork: Delete networks
67
+ # - RemoveVolume: Delete volumes
68
+ # - RunContainer: Create and start containers
69
+ # - StartContainer: Start existing containers
70
+ # - StopContainer: Stop running containers
71
+ # - TagImage: Tag images with new names
72
+ #
73
+ # @example Initialize server
74
+ # server = DockerMCP::Server.new
75
+ # puts server.server.tools.length # => 22
76
+ #
77
+ # @see MCP::Server#new
78
+ def initialize
79
+ @server = MCP::Server.new(
80
+ name: 'docker_mcp',
81
+ tools: [
82
+ BuildImage,
83
+ CopyToContainer,
84
+ CreateContainer,
85
+ CreateNetwork,
86
+ CreateVolume,
87
+ ExecContainer,
88
+ FetchContainerLogs,
89
+ ListContainers,
90
+ ListImages,
91
+ ListNetworks,
92
+ ListVolumes,
93
+ PullImage,
94
+ PushImage,
95
+ RecreateContainer,
96
+ RemoveContainer,
97
+ RemoveImage,
98
+ RemoveNetwork,
99
+ RemoveVolume,
100
+ RunContainer,
101
+ StartContainer,
102
+ StopContainer,
103
+ TagImage
104
+ ]
105
+ )
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DockerMCP
4
+ # MCP tool for starting existing Docker containers.
5
+ #
6
+ # This tool provides the ability to start Docker containers that have been
7
+ # created but are currently stopped. It's the counterpart to StopContainer
8
+ # and is commonly used after CreateContainer or when restarting stopped
9
+ # containers.
10
+ #
11
+ # == Features
12
+ #
13
+ # - Start stopped containers by ID or name
14
+ # - Simple and reliable container lifecycle management
15
+ # - Comprehensive error handling
16
+ # - Works with containers in any stopped state
17
+ #
18
+ # == Security Considerations
19
+ #
20
+ # Starting containers can have security implications:
21
+ # - Containers resume with their original configuration
22
+ # - Services become accessible on mapped ports
23
+ # - Processes resume execution with previous privileges
24
+ # - Network connections are re-established
25
+ #
26
+ # Ensure containers are properly configured before starting:
27
+ # - Review port mappings and network exposure
28
+ # - Verify volume mounts and file permissions
29
+ # - Check environment variables for sensitive data
30
+ # - Validate container image integrity
31
+ #
32
+ # == Example Usage
33
+ #
34
+ # # Start container by name
35
+ # StartContainer.call(
36
+ # server_context: context,
37
+ # id: "web-server"
38
+ # )
39
+ #
40
+ # # Start container by ID
41
+ # StartContainer.call(
42
+ # server_context: context,
43
+ # id: "a1b2c3d4e5f6"
44
+ # )
45
+ #
46
+ # @see CreateContainer
47
+ # @see StopContainer
48
+ # @see RunContainer
49
+ # @see Docker::Container#start
50
+ # @since 0.1.0
51
+ class StartContainer < MCP::Tool
52
+ description 'Start a Docker container'
53
+
54
+ input_schema(
55
+ properties: {
56
+ id: {
57
+ type: 'string',
58
+ description: 'Container ID or name'
59
+ }
60
+ },
61
+ required: ['id']
62
+ )
63
+
64
+ # Start an existing Docker container.
65
+ #
66
+ # This method starts a container that is currently in a stopped state.
67
+ # The container must already exist and be in a startable state. If the
68
+ # container is already running, Docker will typically ignore the start
69
+ # command without error.
70
+ #
71
+ # @param id [String] container ID (full or short) or container name
72
+ # @param server_context [Object] MCP server context (unused but required)
73
+ #
74
+ # @return [MCP::Tool::Response] start operation results
75
+ #
76
+ # @raise [Docker::Error::NotFoundError] if container doesn't exist
77
+ # @raise [StandardError] for other start failures
78
+ #
79
+ # @example Start by container name
80
+ # response = StartContainer.call(
81
+ # server_context: context,
82
+ # id: "my-app-container"
83
+ # )
84
+ #
85
+ # @example Start by container ID
86
+ # response = StartContainer.call(
87
+ # server_context: context,
88
+ # id: "abc123def456"
89
+ # )
90
+ #
91
+ # @see Docker::Container#start
92
+ def self.call(id:, server_context:)
93
+ container = Docker::Container.get(id)
94
+ container.start
95
+
96
+ MCP::Tool::Response.new([{
97
+ type: 'text',
98
+ text: "Container #{id} started successfully"
99
+ }])
100
+ rescue Docker::Error::NotFoundError
101
+ MCP::Tool::Response.new([{
102
+ type: 'text',
103
+ text: "Container #{id} not found"
104
+ }])
105
+ rescue StandardError => e
106
+ MCP::Tool::Response.new([{
107
+ type: 'text',
108
+ text: "Error starting container: #{e.message}"
109
+ }])
110
+ end
111
+ end
112
+ end