README.md•7.63 kB
# MCP Docker Server
A Python-based MCP (Model Context Protocol) server that provides secure Docker command execution for language models or other clients running in isolated environments like containers.
## Overview
This MCP server runs on a host system and provides access to its Docker daemon via the MCP protocol. It implements security filtering and command validation to ensure safe operation, only allowing `docker` and `docker-compose` commands to be executed.
## Features
- **Docker Command Execution**: Executes `docker` and `docker-compose` commands on the host.
- **Docker Compose Support**: Handles both legacy `docker-compose` and modern `docker compose` syntax.
- **Security Validation**: An explicit allowlist restricts executable commands to `docker` and `docker-compose` only.
- **Async I/O**: Built with `asyncio` for non-blocking command execution.
- **Multiple Transports**: Supports `stdio`, `sse`, and `streamable-http` MCP transports.
- **Rich Toolset**: Provides specific tools for common operations like listing containers, images, and checking system info.
- **Error Handling**: Returns detailed error messages for failed commands.
## Architecture
```
┌─────────────────┐ MCP Protocol ┌──────────────┐
│ Client │ ─────────────────► │ MCP Server │
│ (e.g. Container)│ │ (Host) │
│ │ ◄───────────────── │ │
│ - Calls Tools │ Command Results │ - Docker CLI │
└─────────────────┘ │ - Security │
└──────────────┘
│
▼
┌──────────────┐
│ Docker Daemon│
│ (Host) │
└──────────────┘
```
## Installation
1. **Python**: Requires Python 3.12 or newer.
2. **Docker**: Docker must be installed and the daemon must be running on the host system.
3. **Dependencies**: Install the required Python packages using `uv` or `pip` from `pyproject.toml`.
```bash
# Using uv
uv pip install -r requirements.txt
# Or directly from the pyproject.toml
uv pip install .
```
## Usage
### Starting the Server
The server can be started with different MCP transports.
```bash
# Start with the default stdio transport
uv run main.py
# Start with the Streamable HTTP transport
uv run main.py streamable-http
# Start with the SSE (Server-Sent Events) transport
uv run main.py sse
```
### Environment Variables
Configure the server's network binding with these environment variables.
- `FASTMCP_HOST`: Server bind address (default: `0.0.0.0` for container access).
- `FASTMCP_PORT`: Server port (default: `3000`).
You can create a `.env` file to manage these variables:
```
FASTMCP_HOST=0.0.0.0
FASTMCP_PORT=3000
```
Then run the server with:
```bash
# Example with a custom .env file
uv run --env-file=.env main.py streamable-http
```
## MCP Protocol
The server uses the `mcp` library to expose tools. The available transports are `stdio`, `sse`, and `streamable-http`.
### Available Methods (Tools)
The following tools are exposed by the server:
- `execute_docker_command(command: str, working_directory: str = None) -> str`
- **Description**: Executes a general Docker or Docker Compose command. The command is validated against an allowlist.
- **Example**: `session.call_tool("execute_docker_command", {"command": "docker ps -a"})`
- `docker_system_info() -> str`
- **Description**: Retrieves Docker version and system disk usage information.
- **Example**: `session.call_tool("docker_system_info", {})`
- `list_containers(all: bool = False) -> str`
- **Description**: Lists Docker containers.
- **Args**: `all` (boolean) - If true, shows all containers (including stopped ones). Defaults to `False`.
- **Example**: `session.call_tool("list_containers", {"all": True})`
- `list_images(all: bool = False) -> str`
- **Description**: Lists Docker images.
- **Args**: `all` (boolean) - If true, shows all images (including intermediate ones). Defaults to `False`.
- **Example**: `session.call_tool("list_images", {})`
- `docker_compose_status(working_directory: str = None) -> str`
- **Description**: Gets the status of services defined in a `docker-compose.yml` file.
- **Args**: `working_directory` (string) - The path to the directory containing the compose file.
- **Example**: `session.call_tool("docker_compose_status", {"working_directory": "/path/to/project"})`
## Security Features
### Command Validation
The server uses an allowlist-based approach for security. The `is_allowed_command` method in `main.py` ensures that only commands beginning with `docker` or `docker-compose` (including `docker compose`) are processed. All other commands are rejected.
### Error Handling
If a command fails to execute, the server captures `stdout`, `stderr`, and the exit code, returning a detailed error message to the client. The `execute_command` function contains a `try...except` block to handle exceptions during subprocess execution.
## Troubleshooting
### Common Issues
1. **Docker Not Available**:
- Ensure Docker is installed: `docker --version`
- Check that the Docker daemon is running: `docker info`
- Verify your user has permissions to access the Docker socket.
2. **Port Already in Use**:
- If you see an error like `address already in use`, the port (default `3000`) is occupied.
- Change the port using the `FASTMCP_PORT` environment variable.
- Find the process using the port: `lsof -i :3000` or `netstat -tulnp | grep 3000`.
3. **Permission Denied (Docker Socket)**:
- If you get a "permission denied" error when running Docker commands, add your user to the `docker` group: `sudo usermod -aG docker $USER`.
- You will need to start a new shell session for this change to take effect.
4. **Connection Refused**:
- Verify the MCP server is running and listening on the correct host and port.
- Check for firewall rules that might be blocking the connection.
- Ensure your client configuration matches the server's `FASTMCP_HOST` and `FASTMCP_PORT`.
## Development
### Project Structure
```
/workspace/mcp_docker/
├── .python-version
├── main.py # Main server implementation
├── pyproject.toml # Project metadata and dependencies
├── README.md # This documentation
└── test/
└── test_client.py # Example client for testing
```
### Testing
Run the example test client to connect to a running server, list its tools, and execute a sample command.
```bash
# Make sure the server is running in another terminal
# Then run the client
uv run test/test_client.py
```
## License
This project is open-source and available for modification and distribution.
## Support
For issues and questions:
1. Check the Troubleshooting section.
2. Verify your Docker installation and permissions.
3. Review the server logs for error details.
4. Test connectivity with simple commands first (e.g., `docker_system_info`).