Skip to content

Latest commit

Β 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🧭 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

    git clone https://github.com/uengine-oss/process-gpt-computer-use
    cd pod-mcp
  2. Install dependencies with uv

    uv pip install -e .
  3. Set up Kubernetes resources

    # 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

    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:

{
  "ttl": 600,
  "image": "node:20",
  "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

upload_file

Upload a Pod file to Supabase Storage (requires Supabase credentials).

Parameters:

  • session_id (str): Session ID
  • source_path (str): Absolute path to the file inside the Pod
  • destination_path (str, optional): Relative path (within prefix) for the object. Defaults to the filename.
  • bucket (str, optional): Supabase bucket (default: files or SUPABASE_BUCKET env value)
  • overwrite (bool, optional): Overwrite existing object (default: false)
  • content_type (str, optional): Explicit content type; auto-detected when omitted

Note: Uploaded paths are automatically nested under the /pod_mcp prefix unless overridden via SUPABASE_PATH_PREFIX.

Code Execution

run_node

Execute Node.js code (streaming output).

Note: Requires Node.js in the container image (recommended: node:20)

Parameters:

  • session_id (str): Session ID
  • code (str): JavaScript/Node.js code to execute
  • ensure_dependencies (bool, optional): When true, runs a safe npm install (with cache isolation) if dependencies are missing before executing your code

If the session contains a package.json but no node_modules, the server automatically bootstraps dependencies even when ensure_dependencies is false, so first-time executions succeed without manual installs.

Example:

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:

"echo 'Hello World' && date && pwd"

npm install / npm ci commands are automatically wrapped with cache isolation, retry logic, and safe defaults to avoid common "idealTree" lock conflicts inside the shared container environment.

🐳 Docker Deployment

Build Image

docker build -t streamable-pod-mcp:latest .

Push to Registry

docker tag streamable-pod-mcp:latest your-registry/streamable-pod-mcp:latest
docker push your-registry/streamable-pod-mcp:latest

Deploy to Kubernetes

# Update image in k8s/deployment.yaml
kubectl apply -f k8s/deployment.yaml

⎈ Helm Installation

Install

helm install pod-mcp ./helm/streamable-pod-mcp \
  --namespace pod-mcp \
  --create-namespace

Custom Values

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

helm upgrade pod-mcp ./helm/streamable-pod-mcp \
  --namespace pod-mcp

Uninstall

helm uninstall pod-mcp --namespace pod-mcp

πŸ§ͺ Testing with kind

1. Create kind Cluster

kind create cluster --name mcp-test

2. Load Docker Image

# Build image
docker build -t streamable-pod-mcp:latest .
kubectl delete deploy pod-mcp-server -n pod-mcp

# Load into kind
kind load docker-image streamable-pod-mcp:latest --name mcp-test

3. Deploy

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

kubectl port-forward -n pod-mcp svc/pod-mcp-server 8000:8000

5. Test

# The server should now be accessible at localhost:8000
curl http://localhost:8000/health

kubectl exec -it -n pod-mcp session-9c4f386a -- sh

πŸ” 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

kubectl logs -n pod-mcp deployment/pod-mcp-server -f

List Session Pods

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:

{
  "mcpServers": {
    "pod-shell": {
      "url": "http://localhost:8888",
      "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:20"]

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: v20.11.1

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)
  • SUPABASE_URL: Supabase project URL (required for upload_file tool)
  • SUPABASE_KEY: Supabase service role key (required for upload_file; older log messages may still refer to SUPABASE_SERVICE_ROLE_KEY)
  • SUPABASE_BUCKET: Supabase storage bucket name (default: files)
  • SUPABASE_PATH_PREFIX: Storage path prefix applied to uploads (default: /pod_mcp)

Server Configuration

Edit run_server.py to customize:

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:

    kubectl auth can-i create pods --namespace=default --as=system:serviceaccount:pod-mcp:pod-mcp-server
  2. Check server logs:

    kubectl logs -n pod-mcp deployment/pod-mcp-server

Connection Refused

  1. Verify service is running:

    kubectl get svc -n pod-mcp
  2. Check port forwarding:

    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:
    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

# Install dev dependencies
uv pip install -e ".[dev]"

# Run tests (coming soon)
pytest

Code Formatting

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.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages