Streamable Pod Shell MCP Server
by jinyoung
README.md
# π§ Streamable Pod Shell MCP Server
A FastMCP-based server that creates isolated Kubernetes Pod sessions with real-time streaming shell command execution.
## π Overview
This MCP server automatically creates a dedicated Kubernetes Pod for each session, providing:
- π **Isolated execution environment** per session
- π‘ **Real-time streaming** of stdout/stderr
- β±οΈ **Automatic TTL-based cleanup** to prevent Pod leaks
- π **Shell command execution** inside Pods
- π **File management** (create/delete/list)
- π’ **Node.js code execution** support
## ποΈ Architecture
```
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββββββ
β β β β β Kubernetes β
β MCP Client ββββββββββΆβ MCP Server ββββββββββΆβ Cluster β
β (Claude/AI) β β (FastMCP) β β β
ββββββββββββββββ ββββββββββββββββ β ββββββββββββββ β
β β session- β β
β β abc123 β β
β ββββββββββββββ β
β ββββββββββββββ β
β β session- β β
β β def456 β β
β ββββββββββββββ β
ββββββββββββββββββββ
```
## π Quick Start
### Prerequisites
- Python 3.10+
- Kubernetes cluster (kind, minikube, or production cluster)
- `kubectl` configured
- `uv` (for Python dependency management)
### Installation
1. **Clone the repository**
```bash
git clone <repository-url>
cd pod-mcp
```
2. **Install dependencies with uv**
```bash
uv pip install -e .
```
3. **Set up Kubernetes resources**
```bash
# Apply RBAC and namespace
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/serviceaccount.yaml
kubectl apply -f k8s/role.yaml
kubectl apply -f k8s/rolebinding.yaml
```
4. **Run the server locally**
```bash
python run_server.py
```
## π οΈ MCP Tools
### Session Management
#### `create_session`
Create a new isolated Pod session.
**Parameters:**
- `ttl` (int, optional): Time-to-live in seconds (default: 600)
- `image` (str, optional): Container image (default: `busybox:latest`)
- `session_id` (str, optional): Custom session ID (auto-generated if not provided)
**Example:**
```python
{
"ttl": 600,
"image": "node:18-alpine",
"session_id": "my-session"
}
```
#### `delete_session`
Delete a Pod session and clean up resources.
**Parameters:**
- `session_id` (str): Session ID to delete
#### `list_sessions`
List all active sessions with their details.
#### `extend_session`
Extend the TTL of an existing session.
**Parameters:**
- `session_id` (str): Session ID
- `extra_seconds` (int): Additional seconds to add (default: 300)
#### `get_session_status`
Get the status of a Pod session.
**Parameters:**
- `session_id` (str): Session ID
### File Operations
#### `list_files`
List files in a directory (streaming output).
**Parameters:**
- `session_id` (str): Session ID
- `path` (str, optional): Directory path (default: `/tmp`)
#### `create_file`
Create a file with content.
**Parameters:**
- `session_id` (str): Session ID
- `file_path` (str): Full path for the new file
- `content` (str): File content
#### `delete_file`
Delete a file from the Pod.
**Parameters:**
- `session_id` (str): Session ID
- `file_path` (str): Full path to the file
### Code Execution
#### `run_node`
Execute Node.js code (streaming output).
**Note:** Requires Node.js in the container image (e.g., `node:18-alpine`)
**Parameters:**
- `session_id` (str): Session ID
- `code` (str): JavaScript/Node.js code to execute
**Example:**
```javascript
console.log('Hello from Node.js!');
console.log(process.version);
```
#### `run_shell`
Execute arbitrary shell commands (streaming output).
**Parameters:**
- `session_id` (str): Session ID
- `command` (str): Shell command to execute
**Example:**
```bash
"echo 'Hello World' && date && pwd"
```
## π³ Docker Deployment
### Build Image
```bash
docker build -t streamable-pod-mcp:latest .
```
### Push to Registry
```bash
docker tag streamable-pod-mcp:latest your-registry/streamable-pod-mcp:latest
docker push your-registry/streamable-pod-mcp:latest
```
### Deploy to Kubernetes
```bash
# Update image in k8s/deployment.yaml
kubectl apply -f k8s/deployment.yaml
```
## β Helm Installation
### Install
```bash
helm install pod-mcp ./helm/streamable-pod-mcp \
--namespace pod-mcp \
--create-namespace
```
### Custom Values
```bash
helm install pod-mcp ./helm/streamable-pod-mcp \
--namespace pod-mcp \
--set image.repository=your-registry/streamable-pod-mcp \
--set image.tag=v0.1.0 \
--set mcpServer.podNamespace=default \
--set mcpServer.defaultTTL=1200
```
### Upgrade
```bash
helm upgrade pod-mcp ./helm/streamable-pod-mcp \
--namespace pod-mcp
```
### Uninstall
```bash
helm uninstall pod-mcp --namespace pod-mcp
```
## π§ͺ Testing with kind
### 1. Create kind Cluster
```bash
kind create cluster --name mcp-test
```
### 2. Load Docker Image
```bash
# Build image
docker build -t streamable-pod-mcp:latest .
# Load into kind
kind load docker-image streamable-pod-mcp:latest --name mcp-test
```
### 3. Deploy
```bash
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/serviceaccount.yaml
kubectl apply -f k8s/role.yaml
kubectl apply -f k8s/rolebinding.yaml
kubectl apply -f k8s/deployment.yaml
```
### 4. Port Forward
```bash
kubectl port-forward -n pod-mcp svc/pod-mcp-server 8000:8000
```
### 5. Test
```bash
# The server should now be accessible at localhost:8000
curl http://localhost:8000/health
```
## π Security Considerations
### RBAC Permissions
The server requires the following permissions:
- `pods`: `get`, `list`, `watch`, `create`, `delete`
- `pods/status`: `get`
- `pods/exec`: `create`
- `pods/log`: `get`
### Resource Limits
Each session Pod has default limits:
- CPU: 200m (limit), 100m (request)
- Memory: 256Mi (limit), 128Mi (request)
### Command Filtering
β οΈ **Warning:** The `run_shell` tool allows arbitrary command execution. Consider:
- Running in isolated namespaces
- Implementing command whitelisting
- Using NetworkPolicies to restrict Pod network access
- Monitoring and logging all commands
## π Monitoring
### View Server Logs
```bash
kubectl logs -n pod-mcp deployment/pod-mcp-server -f
```
### List Session Pods
```bash
kubectl get pods -l managed-by=streamable-pod-mcp
```
### Check TTL Watcher
The TTL watcher runs as a background thread and automatically deletes expired Pods. Check server logs for entries like:
```
TTL watcher started (check interval: 10s)
TTL expired for session abc123, deleting pod...
```
## π― Usage with Claude / Cursor
### Claude Desktop Configuration
Add to your Claude Desktop MCP settings:
```json
{
"mcpServers": {
"pod-shell": {
"url": "http://localhost:8000",
"transport": "http"
}
}
}
```
### Example Conversation
```
User: Create a new session with Node.js
Claude: I'll create a session with Node.js support.
[Calls create_session with image="node:18-alpine"]
Session created: session-abc123
User: Run some JavaScript code to check the Node version
Claude: [Calls run_node with code="console.log(process.version)"]
Output: v18.19.0
User: List files in /tmp
Claude: [Calls list_files with path="/tmp"]
total 0
drwxrwxrwt 2 root root 40 Nov 2 12:00 .
drwxr-xr-x 17 root root 4096 Nov 2 12:00 ..
```
## π§ Configuration
### Environment Variables
- `POD_NAMESPACE`: Kubernetes namespace for session pods (default: `default`)
- `IN_CLUSTER`: Whether running inside cluster (default: `false`)
### Server Configuration
Edit `run_server.py` to customize:
```python
initialize_server(
namespace="my-namespace", # Custom namespace
in_cluster=False, # Set True when deployed in-cluster
start_watcher=True, # Enable TTL watcher
)
```
## π Troubleshooting
### Pods Not Creating
1. Check RBAC permissions:
```bash
kubectl auth can-i create pods --namespace=default --as=system:serviceaccount:pod-mcp:pod-mcp-server
```
2. Check server logs:
```bash
kubectl logs -n pod-mcp deployment/pod-mcp-server
```
### Connection Refused
1. Verify service is running:
```bash
kubectl get svc -n pod-mcp
```
2. Check port forwarding:
```bash
kubectl port-forward -n pod-mcp svc/pod-mcp-server 8000:8000
```
### Pods Not Deleting
1. Check TTL watcher is running (check server logs)
2. Manually clean up:
```bash
kubectl delete pods -l managed-by=streamable-pod-mcp
```
## π Development
### Project Structure
```
pod-mcp/
βββ src/
β βββ __init__.py
β βββ pod_manager.py # Pod lifecycle management
β βββ executor.py # Kubernetes exec stream handler
β βββ mcp_server.py # FastMCP server and tools
βββ k8s/ # Kubernetes manifests
βββ helm/ # Helm chart
βββ run_server.py # Server entry point
βββ pyproject.toml # Python dependencies (uv)
βββ Dockerfile # Container image
βββ README.md
```
### Running Tests
```bash
# Install dev dependencies
uv pip install -e ".[dev]"
# Run tests (coming soon)
pytest
```
### Code Formatting
```bash
black src/
```
## π― Roadmap
- [ ] Persistent Volume support for session data
- [ ] Multi-namespace management
- [ ] WebSocket direct streaming mode
- [ ] Enhanced security with command filtering
- [ ] Metrics and Prometheus integration
- [ ] Session snapshots and restoration
- [ ] Support for more base images (Python, Go, etc.)
## π License
MIT License - see LICENSE file for details
## π€ Contributing
Contributions welcome! Please open an issue or submit a pull request.
## π§ Contact
For questions or issues, please open a GitHub issue.
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues