README.mdā¢14.7 kB
# Docker MCP Server
A Model Context Protocol (MCP) server that runs entirely inside a Docker container, providing secure command execution and file operations through HTTP with bearer token authentication.
## š Features
- **Containerized MCP Server**: Runs entirely inside Docker with no host dependencies
- **HTTP Transport**: Network-based communication with bearer token authentication
- **Secure Command Execution**: Run shell commands in isolated container environment
- **File Operations**: Read, write, edit, and search files within container workspace
- **Process Management**: Track long-running processes with unique IDs
- **Interactive Input**: Send input to running processes
- **Smart Timeouts**: Intelligent process timeout handling based on output activity
## šļø Architecture
The MCP server runs inside a Docker container and communicates with clients over HTTP:
```
MCP Client (via HTTP) ā Docker Container (Port 3000)
ā
MCP Server (Node.js)
ā
Workspace (/app/workspace)
ā
Host ./tmp directory (mounted)
```
### Core Components
- **Containerized MCP Server** - TypeScript server using `@modelcontextprotocol/sdk` with `StreamableHTTPServerTransport`
- **HTTP API** - Network-based communication on port 3000
- **Bearer Token Auth** - Secure authentication for all requests
- **Docker Container** - Debian-based with Node.js, Playwright, and development tools
- **Workspace Mount** - Host `./tmp` directory mounted to `/app/workspace`
- **Process Tracking** - Background process management with unique IDs
### Key Differences from Traditional MCP Servers
- **No Host Installation**: Server runs entirely in container
- **Network Access**: HTTP-based instead of stdio transport
- **Authentication Required**: Bearer token for all requests
- **Self-Contained**: All dependencies bundled in container image
- **Direct Execution**: No docker exec overhead
## š Prerequisites
- [Docker](https://www.docker.com/get-started) installed and running
- [Docker Compose](https://docs.docker.com/compose/install/) for container management
- [Node.js](https://nodejs.org/) (v18 or higher) for local development only
## š Quick Start
### 1. Clone and Setup
```bash
git clone <your-repository-url>
cd docker-mcp
```
### 2. Start the Server
```bash
# Quick start: reset environment and start server
./reset-docker.sh
# Or manually:
npm run docker:build # Build container with server code
npm run docker:up # Start container
npm run docker:logs # View logs and get auth token
```
### 3. Get Connection Info
The server logs display the authentication token and connection details:
```bash
npm run docker:logs
```
Look for output like:
```
============================================================
Docker MCP Server Starting
============================================================
Port: 3000
Auth Token: abc123-def456-ghi789
============================================================
```
### 4. Test Connection
```bash
# Test with curl
curl -H "Authorization: Bearer YOUR_TOKEN_HERE" \
http://localhost:3000
# View server logs
npm run docker:logs
```
## š§ Development Commands
### Docker Operations
```bash
# Build the container image with server code
npm run docker:build
# Start the containerized MCP server
npm run docker:up
# Stop the container
npm run docker:down
# View server logs (includes auth token)
npm run docker:logs
# Rebuild and restart (after code changes)
npm run docker:restart
# Open bash shell in container
npm run docker:shell
# Complete reset (clean workspace and rebuild)
./reset-docker.sh
```
### Local Development
```bash
# Build TypeScript (for development/testing only)
npm run build
# Install/update dependencies
npm install
```
## āļø MCP Client Configuration
### Configuration Format
MCP clients need to connect via HTTP with bearer token authentication:
```json
{
"url": "http://localhost:3000",
"headers": {
"Authorization": "Bearer YOUR_TOKEN_FROM_LOGS"
}
}
```
**Important:**
- Get the auth token from container logs: `npm run docker:logs`
- Token is auto-generated on each container start
- Token must be included in the `Authorization` header with `Bearer ` prefix
### Claude Desktop Configuration
Add to your Claude Desktop configuration file:
**Location:**
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%/Claude/claude_desktop_config.json`
**Configuration:**
```json
{
"mcpServers": {
"docker-mcp": {
"url": "http://localhost:3000",
"headers": {
"Authorization": "Bearer YOUR_TOKEN_FROM_LOGS"
}
}
}
}
```
**Note:** Replace `YOUR_TOKEN_FROM_LOGS` with the actual token from `npm run docker:logs`
### Getting Your Authentication Token
1. Start the server: `npm run docker:up`
2. View logs: `npm run docker:logs`
3. Copy the token from the output
4. Update your client configuration with the token
5. Restart your MCP client
### Verification
After configuration:
1. Restart your MCP client (e.g., Claude Desktop)
2. Check that the Docker MCP server shows as connected
3. Verify access to all available tools
## š ļø Available MCP Tools
### š Command Execution
#### `execute_command`
**Execute shell commands inside the container**
Execute any shell command within the container environment with intelligent process tracking.
**Parameters:**
- `command` (string) - The shell command to execute
- `rationale` (string) - Explanation of why this command is being executed
- `maxWaitTime` (number, optional) - Maximum seconds to wait before returning (default: 20)
**Features:**
- Automatic backgrounding for long-running processes
- Smart timeout based on output activity
- Process ID returned for monitoring
- Real-time output capture
#### `check_process`
**Monitor background processes by ID**
Check the status and output of background processes started by `execute_command`.
**Parameters:**
- `processId` (string) - The process ID returned by a long-running command
- `rationale` (string) - Explanation of why you need to check this process
**Returns:**
- Process status (running/completed)
- Current output (stdout/stderr)
- Exit code (if completed)
- Runtime duration
#### `send_input`
**Send input to running background processes**
Send input data to interactive processes waiting for user input.
**Parameters:**
- `processId` (string) - The process ID of the running process
- `input` (string) - The input to send to the process
- `rationale` (string) - Explanation of why you need to send input
- `autoNewline` (boolean, optional) - Auto-add newline (default: true)
### š File Operations
All file operations work within `/app/workspace` which is mounted from host `./tmp`.
#### `file_read`
**Read files from container filesystem**
Read file contents with support for large files through pagination.
**Parameters:**
- `filePath` (string) - Path relative to `/app/workspace`
- `rationale` (string) - Explanation of why you need to read this file
- `offset` (number, optional) - Starting line number (default: 0)
- `limit` (number, optional) - Maximum lines to read (default: 2000)
#### `file_write`
**Create or overwrite files**
Write content to files with automatic directory creation.
**Parameters:**
- `filePath` (string) - Path relative to `/app/workspace`
- `content` (string) - The content to write
- `rationale` (string) - Explanation of why you need to write this file
**Important:** Use `file_read` first to understand current state.
#### `file_edit`
**Perform exact string replacements**
Edit files using precise string matching with backup protection.
**Parameters:**
- `filePath` (string) - Path relative to `/app/workspace`
- `oldString` (string) - The exact text to replace
- `newString` (string) - The replacement text
- `rationale` (string) - Explanation of why you need to edit this file
- `replaceAll` (boolean, optional) - Replace all occurrences (default: false)
**Important:** Use `file_read` first to get the exact text to match.
#### `file_ls`
**List directory contents**
List files and directories with intelligent filtering.
**Parameters:**
- `path` (string, optional) - Directory path (default: current directory)
- `rationale` (string) - Explanation of why you need to list this directory
- `ignore` (array, optional) - Glob patterns to ignore
#### `file_grep`
**Search file contents**
Search for patterns in files using grep with regex support.
**Parameters:**
- `pattern` (string) - Search pattern (supports regex)
- `rationale` (string) - Explanation of why you need to search
- `path` (string, optional) - Directory to search (default: current)
- `include` (string, optional) - File pattern filter (e.g., '*.js')
- `caseInsensitive` (boolean, optional) - Case insensitive (default: false)
- `maxResults` (number, optional) - Result limit (default: 100)
## š Process Management
Commands run with intelligent timeout handling:
- **Default timeout**: 20 seconds of inactivity before backgrounding
- **Maximum timeout**: 10 minutes absolute limit
- **Process tracking**: Background processes get unique IDs for monitoring
- **Smart waiting**: Based on output activity, not fixed intervals
### Example Process Flow
```javascript
// Long-running command gets backgrounded automatically
const result1 = execute_command({
command: "npm install",
rationale: "Installing dependencies"
});
// Returns process ID if backgrounded
// Check status later
const result2 = check_process({
processId: result1.processId,
rationale: "Checking installation progress"
});
// Send input to interactive processes
send_input({
processId: result1.processId,
input: "y",
rationale: "Confirming prompt"
});
```
## š Security Considerations
### Authentication
- **Bearer Token Required**: All requests must include valid bearer token
- **Auto-Generated Token**: New token generated on each container start
- **Token Rotation**: Restart container to generate new token
- **CORS Enabled**: Allows cross-origin requests (consider restricting in production)
### Container Isolation
- **Network Isolation**: Container exposed only on port 3000
- **Workspace Mount**: Only `./tmp` directory accessible from host
- **User Permissions**: Commands run with container-level permissions
- **No Host Access**: Server cannot access host filesystem outside mount
### Recommended Security Practices
1. **Token Management**: Keep authentication tokens secure and private
2. **Network Restrictions**: Use firewall rules to limit access to port 3000
3. **Workspace Isolation**: Regularly audit `./tmp` directory contents
4. **Resource Limits**: Add CPU and memory constraints in docker-compose.yml
5. **Access Logs**: Monitor container logs for suspicious activity
## šØ Troubleshooting
### Server Won't Start
```bash
# Check Docker is running
docker info
# View container logs for errors
npm run docker:logs
# Verify port 3000 is available
lsof -i :3000 # macOS/Linux
netstat -ano | findstr :3000 # Windows
# Complete reset
npm run docker:down
./reset-docker.sh
```
### Can't Connect to Server
```bash
# Verify container is running
docker ps | grep mcp-container
# Check server logs for auth token
npm run docker:logs
# Ensure correct URL
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:3000
# Restart container
npm run docker:restart
```
### Code Changes Not Reflected
```bash
# Remember: server code is built into container image
# After changing TypeScript code, you MUST rebuild:
npm run docker:restart
# Or manually:
npm run docker:down
npm run docker:build
npm run docker:up
```
### Authentication Failed
```bash
# Get current auth token from logs
npm run docker:logs
# Verify token format in client config
# Must be: "Bearer YOUR_TOKEN" (with "Bearer " prefix)
# Token changes on restart - update client config
```
### Permission Errors in Workspace
```bash
# Ensure tmp directory exists and is writable
mkdir -p tmp
chmod 755 tmp
# Reset workspace
rm -rf tmp && mkdir tmp
```
### Process Timeout Issues
- Increase `maxWaitTime` parameter in `execute_command`
- Use `check_process` to monitor long-running operations
- Break complex operations into smaller steps
- Check container resources: `docker stats mcp-container`
## š¤ Contributing
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes in `src/`
4. Test with `npm run docker:restart`
5. Commit your changes (`git commit -m 'Add amazing feature'`)
6. Push to the branch (`git push origin feature/amazing-feature`)
7. Open a Pull Request
### Development Guidelines
- Follow TypeScript best practices
- Add comprehensive error handling
- Include rationale parameters for all tool operations
- Test with both quick and long-running commands
- Document any new MCP tools or capabilities
- Test authentication and security features
## š¦ Deployment
### Local Deployment
```bash
# Production deployment
docker-compose up -d
# View production logs
docker-compose logs -f mcp-container
# Auto-restart on failure
# (already configured with restart: unless-stopped)
```
### Custom Configuration
```yaml
# docker-compose.yml
services:
mcp-container:
environment:
- NODE_ENV=production
- AUTH_TOKEN=your-custom-token # Optional: set custom token
ports:
- "3000:3000" # Change port mapping if needed
volumes:
- ./custom-workspace:/app/workspace
```
### Environment Variables
- `NODE_ENV`: Set to `production` for production deployment
- Port: Configure via CLI flag `--port 3000`
- Token: Set via CLI flag `--token your-token` (auto-generated if not set)
## š License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## šāāļø Support
- š **Bug Reports**: Open an issue with detailed reproduction steps
- š” **Feature Requests**: Open an issue with your use case
- š **Documentation**: Check `CLAUDE.md` for AI assistant specific guidance
- š¬ **Questions**: Open a discussion for general questions
## š Additional Resources
- [Model Context Protocol Documentation](https://modelcontextprotocol.io/)
- [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)
- [Docker Documentation](https://docs.docker.com/)
---
**Built for the Model Context Protocol ecosystem** š¤
**Features:**
- ā
HTTP Transport with Bearer Token Auth
- ā
Containerized Architecture
- ā
Process Management
- ā
File Operations
- ā
Network Accessible
- ā
Production Ready