# docker-mcp
A Model Context Protocol (MCP) server for Docker integration. Give your AI assistant eyes and hands on your containers.
**Status:** Planning
**Author:** Claude (claude@arktechnwa.com) + Meldrey
**License:** MIT
**Organization:** [ArktechNWA](https://github.com/ArktechNWA)
---
## Why?
Your AI assistant can write Dockerfiles, but it can't see if your containers are running. It can suggest fixes, but can't tail the logs to see the actual error. It's blind to your container ecosystem.
docker-mcp connects Claude to your Docker daemon — safely, with granular permissions.
---
## Philosophy
1. **Safety by default** — Read-only container inspection
2. **User controls exposure** — Whitelist containers, permission levels
3. **Never hang** — Docker commands can hang, we timeout
4. **Structured output** — JSON for machines, summaries for AI
5. **Fallback AI** — Haiku for log analysis and troubleshooting
---
## Features
### Perception (Read)
- List containers (running, stopped, all)
- Container inspection (config, state, network)
- Container logs (with streaming)
- Image listing and inspection
- Network and volume listing
- Resource usage stats
### Action (Write)
- Start/stop/restart containers
- Execute commands in containers
- Create/remove containers
- Pull images
- Compose operations
### Analysis (AI-Assisted)
- "Why did this container crash?"
- Log pattern analysis
- Resource usage anomalies
---
## Permission Model
### Permission Levels
| Level | Description | Default |
|-------|-------------|---------|
| `read` | List, inspect, logs, stats | **ON** |
| `lifecycle` | Start, stop, restart, pause, unpause | OFF |
| `exec` | Execute commands in containers | OFF |
| `create` | Create/remove containers | OFF |
| `images` | Pull, build, remove images | OFF |
| `volumes` | Create/remove volumes | OFF |
| `networks` | Create/remove networks | OFF |
| `system` | System prune, info | OFF |
### Container Filtering
```json
{
"permissions": {
"read": true,
"lifecycle": false,
"exec": false,
"create": false,
"whitelist_containers": [
"myapp-*",
"nginx",
"redis"
],
"blacklist_containers": [
"*-db",
"vault",
"secrets-*"
],
"whitelist_images": [
"myorg/*",
"nginx:*"
]
}
}
```
**Rules:**
- Blacklist always wins
- Pattern matching with `*` wildcards
- Applies to container names and image names
### Exec Safety
```json
{
"exec_safety": {
"blocked_commands": [
"rm -rf",
"dd if=",
"mkfs",
"> /dev/"
],
"max_output": 10000,
"timeout": "30s"
}
}
```
### Bypass Mode
```bash
docker-mcp --bypass-permissions
```
Full Docker access. You own the consequences.
---
## Authentication
Docker socket access:
```json
{
"docker": {
"socket": "/var/run/docker.sock",
"host": null
}
}
```
Or TCP:
```json
{
"docker": {
"host": "tcp://localhost:2375",
"tls": {
"ca": "/path/to/ca.pem",
"cert": "/path/to/cert.pem",
"key": "/path/to/key.pem"
}
}
}
```
---
## Tools
### Containers
#### `docker_ps`
List containers.
```typescript
docker_ps({
all?: boolean, // include stopped (default: false)
filter?: {
name?: string,
status?: "running" | "exited" | "paused",
label?: string
},
limit?: number
})
```
Returns:
```json
{
"containers": [
{
"id": "abc123",
"name": "myapp-web",
"image": "myorg/myapp:latest",
"status": "running",
"status_icon": "✓",
"uptime": "3d 12h",
"ports": ["0.0.0.0:8080->80/tcp"],
"health": "healthy"
}
],
"summary": "5 running, 2 stopped containers"
}
```
#### `docker_inspect`
Get detailed container information.
```typescript
docker_inspect({
container: string, // name or ID
section?: "config" | "state" | "network" | "mounts" | "all"
})
```
#### `docker_logs`
Get container logs.
```typescript
docker_logs({
container: string,
tail?: number, // last N lines (default: 100)
since?: string, // timestamp or relative: "-1h"
until?: string,
grep?: string, // filter lines
follow?: boolean // stream (default: false)
})
```
#### `docker_stats`
Get resource usage.
```typescript
docker_stats({
container?: string, // specific container (omit for all)
no_stream?: boolean // single snapshot (default: true)
})
```
Returns:
```json
{
"stats": [
{
"container": "myapp-web",
"cpu": "2.5%",
"memory": "256M / 512M",
"memory_percent": "50%",
"network_rx": "1.2GB",
"network_tx": "450MB",
"disk_read": "100MB",
"disk_write": "50MB"
}
]
}
```
### Lifecycle
#### `docker_start`
Start container(s). Requires `lifecycle` permission.
```typescript
docker_start({
containers: string | string[]
})
```
#### `docker_stop`
Stop container(s). Requires `lifecycle` permission.
```typescript
docker_stop({
containers: string | string[],
timeout?: number // seconds before SIGKILL
})
```
#### `docker_restart`
Restart container(s). Requires `lifecycle` permission.
```typescript
docker_restart({
containers: string | string[],
timeout?: number
})
```
#### `docker_pause` / `docker_unpause`
Pause/unpause container(s). Requires `lifecycle` permission.
### Exec
#### `docker_exec`
Execute command in container. Requires `exec` permission.
```typescript
docker_exec({
container: string,
command: string | string[],
workdir?: string,
user?: string,
env?: Record<string, string>
})
```
Returns:
```json
{
"container": "myapp-web",
"command": ["ls", "-la", "/app"],
"exit_code": 0,
"stdout": "total 24\ndrwxr-xr-x...",
"stderr": ""
}
```
### Images
#### `docker_images`
List images.
```typescript
docker_images({
filter?: {
reference?: string, // image name pattern
dangling?: boolean
}
})
```
#### `docker_pull`
Pull image. Requires `images` permission.
```typescript
docker_pull({
image: string, // image:tag
platform?: string
})
```
### Compose
#### `docker_compose_ps`
List compose services.
```typescript
docker_compose_ps({
project?: string, // compose project name
file?: string // compose file path
})
```
#### `docker_compose_up`
Start compose services. Requires `create` + `lifecycle` permissions.
```typescript
docker_compose_up({
project?: string,
file?: string,
services?: string[],
detach?: boolean,
build?: boolean
})
```
#### `docker_compose_down`
Stop compose services. Requires `lifecycle` permission.
```typescript
docker_compose_down({
project?: string,
file?: string,
volumes?: boolean, // remove volumes
remove_orphans?: boolean
})
```
#### `docker_compose_logs`
Get compose logs.
```typescript
docker_compose_logs({
project?: string,
file?: string,
services?: string[],
tail?: number,
follow?: boolean
})
```
### Analysis
#### `docker_diagnose`
AI-powered container diagnosis.
```typescript
docker_diagnose({
container: string,
use_ai?: boolean
})
```
Returns:
```json
{
"container": "myapp-web",
"status": "exited",
"exit_code": 137,
"last_logs": "[... error lines ...]",
"synthesis": {
"analysis": "Container was OOM killed (exit code 137). Memory limit is 512MB but the app tried to allocate 800MB during startup.",
"suggested_fix": "Increase memory limit to 1GB or optimize app memory usage",
"confidence": "high"
}
}
```
---
## NEVERHANG Architecture
Docker commands can hang. `docker logs -f` never returns. `docker exec` in a stuck container hangs forever.
### Timeouts
- Read operations: 30s
- Lifecycle operations: 60s
- Exec operations: 30s (configurable)
- Compose operations: 120s
### Streaming
- Logs stream in chunks
- Stats stream updates
- Client can cancel anytime
### Process Management
- Track spawned docker commands
- Kill hung processes
- Clean up partial operations
### Circuit Breaker
- 3 failures in 60s → 5 minute cooldown
- Docker daemon health checks
- Socket connectivity monitoring
```json
{
"neverhang": {
"read_timeout": 30000,
"lifecycle_timeout": 60000,
"exec_timeout": 30000,
"compose_timeout": 120000,
"circuit_breaker": {
"failures": 3,
"window": 60000,
"cooldown": 300000
}
}
}
```
---
## Fallback AI
Optional Haiku for log analysis.
```json
{
"fallback": {
"enabled": true,
"model": "claude-haiku-4-5",
"api_key_env": "DOCKER_MCP_FALLBACK_KEY",
"max_log_lines": 200,
"max_tokens": 500
}
}
```
**When used:**
- `docker_diagnose` with `use_ai: true`
- Crash analysis
- Resource anomaly detection
---
## Configuration
`~/.config/docker-mcp/config.json`:
```json
{
"docker": {
"socket": "/var/run/docker.sock"
},
"permissions": {
"read": true,
"lifecycle": false,
"exec": false,
"create": false,
"images": false,
"whitelist_containers": [],
"blacklist_containers": ["*-db", "vault"]
},
"neverhang": {
"read_timeout": 30000,
"exec_timeout": 30000
},
"fallback": {
"enabled": false
}
}
```
### Claude Code Integration
```json
{
"mcpServers": {
"docker": {
"command": "docker-mcp",
"args": ["--config", "/path/to/config.json"]
}
}
}
```
---
## Installation
```bash
npm install -g @arktechnwa/docker-mcp
```
---
## Requirements
- Node.js 18+
- Docker daemon (socket or TCP access)
- Docker Compose (for compose features)
- Optional: Anthropic API key for fallback AI
---
## Security Considerations
1. **Socket access = root** — Docker socket grants root-equivalent access
2. **Use container filtering** — Blacklist sensitive containers
3. **Exec command filtering** — Block dangerous patterns
4. **Read-only default** — Only enable write permissions explicitly
5. **No secret exposure** — Environment variables filtered from output
---
## Credits
Created by Claude (claude@arktechnwa.com) in collaboration with Meldrey.
Part of the [ArktechNWA MCP Toolshed](https://github.com/ArktechNWA).