Skip to content

Commit f73d317

Browse files
committed
wip
1 parent acd78ac commit f73d317

27 files changed

+196
-267
lines changed

README.md

Lines changed: 110 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
# DockerMCP
1+
# RubyLLM Docker Tools
22

3-
A Model Context Protocol (MCP) server that provides comprehensive Docker management capabilities through a standardized interface. This tool enables AI assistants and other MCP clients to interact with Docker containers, images, networks, and volumes programmatically.
3+
A comprehensive Ruby gem that provides Docker management capabilities through [RubyLLM](https://github.com/afstanton/ruby_llm) tools. This library enables AI assistants and chatbots to interact with Docker containers, images, networks, and volumes programmatically using natural language.
4+
5+
**Note:** This gem is a port of the [DockerMCP](https://github.com/afstanton/docker_mcp) gem, adapted to work directly with RubyLLM tools instead of requiring an external MCP server.
46

57
## ⚠️ Security Warning
68

@@ -16,105 +18,130 @@ A Model Context Protocol (MCP) server that provides comprehensive Docker managem
1618
- Ensure proper Docker daemon security configuration
1719
- Consider running with restricted Docker permissions
1820
- Monitor and audit all container operations
19-
- Be cautious when exposing this tool to external or untrusted MCP clients
21+
- Be cautious when exposing these tools in production environments
2022

2123
## Installation
2224

2325
Install the gem and add to the application's Gemfile by executing:
2426

2527
```bash
26-
bundle add docker_mcp
28+
bundle add ruby_llm-docker
2729
```
2830

2931
If bundler is not being used to manage dependencies, install the gem by executing:
3032

3133
```bash
32-
gem install docker_mcp
34+
gem install ruby_llm-docker
3335
```
3436

3537
## Prerequisites
3638

3739
- Docker Engine installed and running
3840
- Ruby 3.2+
39-
- Docker permissions for the user running the MCP server
41+
- Docker permissions for the user running the application
42+
- RubyLLM gem
4043

4144
## Usage
4245

43-
### MCP Client Configuration
44-
45-
Add this to your MCP client configuration after installing the gem:
46-
47-
```json
48-
{
49-
"docker_mcp": {
50-
"command": "bash",
51-
"args": [
52-
"-l",
53-
"-c",
54-
"docker_mcp"
55-
]
56-
}
57-
}
46+
### Basic Setup
47+
48+
```ruby
49+
require 'ruby_llm/docker'
50+
51+
# Create a new chat instance
52+
chat = RubyLLM::Chat.new(
53+
api_key: 'your-openai-api-key',
54+
model: 'gpt-4'
55+
)
56+
57+
# Add all Docker tools to the chat
58+
RubyLLM::Docker.add_all_tools_to_chat(chat)
59+
60+
# Or add individual tools
61+
chat.tools << RubyLLM::Docker::ListContainers.new
62+
chat.tools << RubyLLM::Docker::RunContainer.new
63+
# ... etc
5864
```
5965

60-
### Example Usage
66+
### Interactive Command Line Tool
6167

62-
Once configured, you can use the tools through your MCP client:
68+
This gem includes a ready-to-use interactive command line tool:
6369

70+
```bash
71+
# Set your OpenAI API key
72+
export OPENAI_API_KEY='your-key-here'
73+
74+
# Run the interactive Docker chat
75+
ruby -r 'ruby_llm/docker' -e "
76+
require_relative 'examples/docker_chat.rb'
77+
DockerChat.new.start
78+
"
79+
```
80+
81+
Or use the included example script:
82+
83+
```bash
84+
ruby examples/docker_chat.rb
6485
```
86+
87+
### Example Usage
88+
89+
Once configured, you can interact with Docker using natural language:
90+
91+
```ruby
6592
# List all containers
66-
list_containers
93+
response = chat.ask("How many containers are currently running?")
6794

6895
# Create and run a new container
69-
run_container image="nginx:latest" name="my-web-server"
96+
response = chat.ask("Create a new nginx container named 'my-web-server' and expose port 8080")
7097

7198
# Execute commands in a container
72-
exec_container id="my-web-server" cmd="nginx -v"
99+
response = chat.ask("Check the nginx version in the my-web-server container")
73100

74101
# Copy files to a container
75-
copy_to_container id="my-web-server" source_path="/local/file.txt" destination_path="/var/www/html/"
102+
response = chat.ask("Copy my local config.txt file to /etc/nginx/ in the web server container")
76103

77104
# View container logs
78-
fetch_container_logs id="my-web-server"
105+
response = chat.ask("Show me the logs for the my-web-server container")
79106
```
80107

81-
## 🔨 Tools
108+
## 🔨 Available Tools
82109

83-
This MCP server provides 22 comprehensive Docker management tools organized by functionality:
110+
This gem provides 22 comprehensive Docker management tools organized by functionality:
84111

85112
### Container Management
86113

87-
- **`list_containers`** - List all Docker containers (running and stopped) with detailed information
88-
- **`create_container`** - Create a new container from an image without starting it
89-
- **`run_container`** - Create and immediately start a container from an image
90-
- **`start_container`** - Start an existing stopped container
91-
- **`stop_container`** - Stop a running container gracefully
92-
- **`remove_container`** - Delete a container (must be stopped first unless forced)
93-
- **`recreate_container`** - Stop, remove, and recreate a container with the same configuration
94-
- **`exec_container`** ⚠️ - Execute arbitrary commands inside a running container
95-
- **`fetch_container_logs`** - Retrieve stdout/stderr logs from a container
96-
- **`copy_to_container`** ⚠️ - Copy files or directories from host to container
114+
- **`ListContainers`** - List all Docker containers (running and stopped) with detailed information
115+
- **`CreateContainer`** - Create a new container from an image without starting it
116+
- **`RunContainer`** - Create and immediately start a container from an image
117+
- **`StartContainer`** - Start an existing stopped container
118+
- **`StopContainer`** - Stop a running container gracefully
119+
- **`RemoveContainer`** - Delete a container (must be stopped first unless forced)
120+
- **`RecreateContainer`** - Stop, remove, and recreate a container with the same configuration
121+
- **`ExecContainer`** ⚠️ - Execute arbitrary commands inside a running container
122+
- **`FetchContainerLogs`** - Retrieve stdout/stderr logs from a container
123+
- **`CopyToContainer`** ⚠️ - Copy files or directories from host to container
97124

98125
### Image Management
99126

100-
- **`list_images`** - List all Docker images available locally
101-
- **`pull_image`** - Download an image from a Docker registry
102-
- **`push_image`** - Upload an image to a Docker registry
103-
- **`build_image`** - Build a new image from a Dockerfile
104-
- **`tag_image`** - Create a new tag for an existing image
105-
- **`remove_image`** - Delete an image from local storage
127+
- **`ListImages`** - List all Docker images available locally
128+
- **`PullImage`** - Download an image from a Docker registry
129+
- **`PushImage`** - Upload an image to a Docker registry
130+
- **`BuildImage`** - Build a new image from a Dockerfile
131+
- **`TagImage`** - Create a new tag for an existing image
132+
- **`RemoveImage`** - Delete an image from local storage
106133

107134
### Network Management
108135

109-
- **`list_networks`** - List all Docker networks
110-
- **`create_network`** - Create a new Docker network
111-
- **`remove_network`** - Delete a Docker network
136+
- **`ListNetworks`** - List all Docker networks
137+
- **`CreateNetwork`** - Create a new Docker network
138+
- **`RemoveNetwork`** - Delete a Docker network
112139

113140
### Volume Management
114141

115-
- **`list_volumes`** - List all Docker volumes
116-
- **`create_volume`** - Create a new Docker volume for persistent data
117-
- **`remove_volume`** - Delete a Docker volume
142+
- **`ListVolumes`** - List all Docker volumes
143+
- **`CreateVolume`** - Create a new Docker volume for persistent data
144+
- **`RemoveVolume`** - Delete a Docker volume
118145

119146
### Tool Parameters
120147

@@ -123,54 +150,40 @@ Most tools accept standard Docker parameters:
123150
- **Image**: Specify images using `name:tag` format (e.g., `nginx:latest`, `ubuntu:22.04`)
124151
- **Ports**: Use Docker port mapping syntax (e.g., `"8080:80"`)
125152
- **Volumes**: Use Docker volume mount syntax (e.g., `"/host/path:/container/path"`)
126-
- **Environment**: Set environment variables as `KEY=VALUE` pairs
153+
- **Environment**: Set environment variables as comma-separated `KEY=VALUE` pairs (e.g., `"NODE_ENV=production,PORT=3000"`)
127154

128155
## Common Use Cases
129156

130157
### Development Environment Setup
131-
```bash
132-
# Pull development image
133-
pull_image from_image="node:18-alpine"
134-
135-
# Create development container with volume mounts
136-
run_container image="node:18-alpine" name="dev-env" \
137-
host_config='{"PortBindings":{"3000/tcp":[{"HostPort":"3000"}]},"Binds":["/local/project:/app"]}'
138-
139-
# Execute development commands
140-
exec_container id="dev-env" cmd="npm install"
141-
exec_container id="dev-env" cmd="npm start"
158+
```ruby
159+
# Ask the AI to set up a development environment
160+
response = chat.ask("Pull the node:18-alpine image and create a development container
161+
named 'dev-env' with port 3000 exposed and my current directory mounted as /app")
162+
163+
# Install dependencies and start the application
164+
response = chat.ask("Run 'npm install' in the dev-env container")
165+
response = chat.ask("Start the application with 'npm start' in the dev-env container")
142166
```
143167

144168
### Container Debugging
145-
```bash
146-
# Check container status
147-
list_containers
148-
149-
# View container logs
150-
fetch_container_logs id="problematic-container"
151-
152-
# Execute diagnostic commands
153-
exec_container id="problematic-container" cmd="ps aux"
154-
exec_container id="problematic-container" cmd="df -h"
155-
exec_container id="problematic-container" cmd="netstat -tlnp"
169+
```ruby
170+
# Check container status and debug issues
171+
response = chat.ask("Show me all containers and their current status")
172+
response = chat.ask("Get the logs for the problematic-container")
173+
response = chat.ask("Check the running processes in the problematic-container")
174+
response = chat.ask("Show disk usage in the problematic-container")
156175
```
157176

158177
### File Management
159-
```bash
160-
# Copy configuration files to container
161-
copy_to_container id="web-server" \
162-
source_path="/local/nginx.conf" \
163-
destination_path="/etc/nginx/"
164-
165-
# Copy application code
166-
copy_to_container id="app-container" \
167-
source_path="/local/src" \
168-
destination_path="/app/"
178+
```ruby
179+
# Copy files to containers using natural language
180+
response = chat.ask("Copy my local nginx.conf file to /etc/nginx/ in the web-server container")
181+
response = chat.ask("Copy the entire src directory to /app/ in the app-container")
169182
```
170183

171184
## Error Handling
172185

173-
The server provides detailed error messages for common issues:
186+
The tools provide detailed error messages for common issues:
174187

175188
- **Container Not Found**: When referencing non-existent containers
176189
- **Image Not Available**: When trying to use images that aren't pulled locally
@@ -189,17 +202,15 @@ docker info
189202

190203
# Verify Docker permissions
191204
docker ps
192-
193-
# Check MCP server logs for connection errors
194205
```
195206

196207
### Container Operation Failures
197-
- Ensure container IDs/names are correct (use `list_containers` to verify)
208+
- Ensure container IDs/names are correct (ask the AI to list containers)
198209
- Check if containers are in the expected state (running/stopped)
199-
- Verify image availability with `list_images`
210+
- Verify image availability (ask the AI to list available images)
200211

201212
### Permission Issues
202-
- Ensure the user running the MCP server has Docker permissions
213+
- Ensure the user running the application has Docker permissions
203214
- Consider adding user to the `docker` group: `sudo usermod -aG docker $USER`
204215
- Verify Docker socket permissions: `ls -la /var/run/docker.sock`
205216

@@ -239,8 +250,8 @@ bundle exec rake spec COVERAGE=true
239250
### Local Development Setup
240251
```bash
241252
# Clone the repository
242-
git clone https://github.com/afstanton/docker_mcp.git
243-
cd docker_mcp
253+
git clone https://github.com/afstanton/ruby_llm-docker.git
254+
cd ruby_llm-docker
244255

245256
# Install dependencies
246257
bin/setup
@@ -255,13 +266,14 @@ bundle exec rake build
255266
bundle exec rake install
256267
```
257268

258-
### Testing with MCP Client
269+
### Testing with RubyLLM
259270
```bash
260-
# Start the MCP server locally
261-
bundle exec exe/docker_mcp
271+
# Test the interactive chat tool
272+
export OPENAI_API_KEY='your-key-here'
273+
ruby examples/docker_chat.rb
262274

263-
# Configure your MCP client to use local development server
264-
# Use file path instead of installed gem command
275+
# Test tool loading without API calls
276+
ruby examples/test_chat.rb
265277
```
266278

267279
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).

examples/docker_chat.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
#!/usr/bin/env ruby
22
# frozen_string_literal: true
33

4-
# Docker Chat - Interactive command line tool
5-
# A comprehensive chat interface with all Docker tools available
4+
# Docker Chat - Interactive command line tool for RubyLLM
5+
# A comprehensive chat interface with all Docker management tools available
6+
# through natural language interaction powered by OpenAI and RubyLLM
7+
#
8+
# Prerequisites:
9+
# - Set OPENAI_API_KEY environment variable
10+
# - Docker daemon running and accessible
611
#
712
# Usage:
13+
# export OPENAI_API_KEY='your-key-here'
814
# ruby examples/docker_chat.rb
915
#
1016
# Commands:

examples/test_chat.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#!/usr/bin/env ruby
22
# frozen_string_literal: true
33

4-
# Test script for docker_chat.rb
5-
# This verifies the basic functionality without requiring OpenAI API
4+
# Test script for RubyLLM Docker Tools
5+
# This verifies that all Docker tools load correctly and the chat system works
6+
# without requiring an OpenAI API key or active Docker daemon
67

78
require_relative '../lib/ruby_llm/docker'
89

lib/ruby_llm/docker/build_image.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
module RubyLLM
44
module Docker
5-
# MCP tool for building Docker images from Dockerfile content.
5+
# RubyLLM tool for building Docker images from Dockerfile content.
66
#
77
# This tool provides the ability to build Docker images by providing Dockerfile
88
# content as a string. It supports optional tagging of the resulting image for
@@ -65,7 +65,7 @@ class BuildImage < RubyLLM::Tool
6565
# can be tagged with a custom name for easy reference.
6666
#
6767
# @param dockerfile [String] the complete Dockerfile content as a string
68-
# @param server_context [Object] MCP server context (unused but required)
68+
# @param server_context [Object] RubyLLM context (unused but required)
6969
# @param tag [String, nil] optional tag to apply to the built image
7070
#
7171
# @return [RubyLLM::Tool::Response] build results including image ID and tag info

lib/ruby_llm/docker/copy_to_container.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
module RubyLLM
44
module Docker
5-
# MCP tool for copying files and directories from host to Docker containers.
5+
# RubyLLM tool for copying files and directories from host to Docker containers.
66
#
77
# This tool provides the ability to copy files or entire directory trees from
88
# the host filesystem into running Docker containers. It uses Docker's archive
@@ -74,13 +74,13 @@ class CopyToContainer < RubyLLM::Tool
7474
# changed after the copy operation completes.
7575
#
7676
# The source path must exist on the host filesystem and be readable by the
77-
# process running the MCP server. The destination path must be a valid path
77+
# process running the application. The destination path must be a valid path
7878
# within the container.
7979
#
8080
# @param id [String] container ID or name to copy files into
8181
# @param source_path [String] path to file/directory on host filesystem
8282
# @param destination_path [String] destination path inside container
83-
# @param server_context [Object] MCP server context (unused but required)
83+
# @param server_context [Object] RubyLLM context (unused but required)
8484
# @param owner [String, nil] ownership specification (e.g., "user:group", "1000:1000")
8585
#
8686
# @return [RubyLLM::Tool::Response] success/failure message with operation details

0 commit comments

Comments
 (0)