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.
- checksums.yaml +4 -4
- data/LICENSE.txt +21 -0
- data/README.md +246 -10
- data/Rakefile +3 -3
- data/examples/.keep +0 -0
- data/exe/docker_mcp +8 -0
- data/lib/docker_mcp/build_image.rb +127 -0
- data/lib/docker_mcp/copy_to_container.rb +223 -0
- data/lib/docker_mcp/create_container.rb +171 -0
- data/lib/docker_mcp/create_network.rb +152 -0
- data/lib/docker_mcp/create_volume.rb +148 -0
- data/lib/docker_mcp/exec_container.rb +216 -0
- data/lib/docker_mcp/fetch_container_logs.rb +161 -0
- data/lib/docker_mcp/list_containers.rb +66 -0
- data/lib/docker_mcp/list_images.rb +80 -0
- data/lib/docker_mcp/list_networks.rb +84 -0
- data/lib/docker_mcp/list_volumes.rb +91 -0
- data/lib/docker_mcp/pull_image.rb +145 -0
- data/lib/docker_mcp/push_image.rb +179 -0
- data/lib/docker_mcp/recreate_container.rb +168 -0
- data/lib/docker_mcp/remove_container.rb +142 -0
- data/lib/docker_mcp/remove_image.rb +164 -0
- data/lib/docker_mcp/remove_network.rb +136 -0
- data/lib/docker_mcp/remove_volume.rb +146 -0
- data/lib/docker_mcp/run_container.rb +129 -0
- data/lib/docker_mcp/server.rb +108 -0
- data/lib/docker_mcp/start_container.rb +112 -0
- data/lib/docker_mcp/stop_container.rb +126 -0
- data/lib/docker_mcp/tag_image.rb +163 -0
- data/lib/docker_mcp/version.rb +11 -2
- data/lib/docker_mcp.rb +64 -3
- data/sig/docker_mcp.rbs +1 -1
- metadata +63 -6
@@ -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
|