Loading...
Loading...
When running third-party MCP (Model Context Protocol) servers, security is paramount. MCPX addresses this challenge through a comprehensive Docker-based container isolation strategy that ensures MCP servers can operate safely without compromising your host system. This post explores the technical architecture behind MCPX's security model.
MCP servers are powerful tools that can access files, execute commands, and interact with external services. Without proper isolation, a malicious or compromised MCP server could:
MCPX solves these problems through multi-layered container isolation.
MCPX implements a strict isolation model where each workspace gets its own dedicated Docker container:
Host System
├── MCPX API Gateway (Host)
├── Container 1: Workspace A
│ ├── MCP Server Instance
│ ├── Isolated File System
│ └── Restricted Network Access
├── Container 2: Workspace B
│ ├── MCP Server Instance
│ ├── Isolated File System
│ └── Restricted Network Access
└── Container N: Workspace N
├── MCP Server Instance
├── Isolated File System
└── Restricted Network Access
This architecture ensures that:
graph TD
A[Workspace Created] --> B[Container Image Built]
B --> C[Security Policies Applied]
C --> D[Container Started]
D --> E[MCP Server Initialized]
E --> F[Ready for Connections]
F --> G[Session Active]
G --> H[Workspace Deleted]
H --> I[Container Destroyed]
I --> J[Resources Cleaned Up]
All communication between clients and MCP servers flows through the MCPX API Gateway:
Client Application
↓
API Gateway (Authentication & Authorization)
↓
Docker Network Bridge (Isolated)
↓
MCP Server Container
Example network configuration:
# Docker Compose Network Configuration
networks:
mcpx-isolated:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
internal: true # No external access by default
Each container operates under strict resource constraints:
# Example resource limits
version: '3.8'
services:
mcp-server:
image: mcpx/workspace:latest
deploy:
resources:
limits:
cpus: '0.5' # Max 50% of one CPU core
memory: 512M # Max 512MB RAM
reservations:
cpus: '0.1' # Min 10% CPU guarantee
memory: 64M # Min 64MB RAM guarantee
# Temporary file system for sensitive operations
tmpfs:
- /tmp:size=100m,noexec,nosuid,nodev
- /var/tmp:size=50m,noexec,nosuid,nodev
# Limited persistent storage
volumes:
- workspace-data:/workspace:rw,size=1G
# Security options
security_opt:
- no-new-privileges:true
ulimits:
nproc: 64 # Max 64 processes
nofile: 1024 # Max 1024 file descriptors
MCPX uses a secure environment variable injection system:
interface SecureEnvironment {
// Encrypted at rest
secrets: Record<string, EncryptedValue>;
// Public configuration
config: Record<string, string>;
// System variables (read-only)
system: Record<string, string>;
}
class EnvironmentManager {
async injectSecrets(container: Container, workspace: Workspace) {
const decryptedSecrets = await this.vault.decrypt(workspace.secrets);
// Inject through secure channel
await container.updateEnvironment({
...workspace.config,
...decryptedSecrets,
// System isolation
WORKSPACE_ID: workspace.id,
CONTAINER_ID: container.id,
MCPX_API_ENDPOINT: this.getAPIEndpoint(),
});
}
}
# Container environment is isolated
$ docker exec container-id env
WORKSPACE_ID=ws-123
CONTAINER_ID=cnt-456
MCPX_API_ENDPOINT=https://api.internal
PATH=/usr/local/bin:/usr/bin:/bin
# No host environment variables leak through
MCPX implements multiple layers of file system protection:
Container File System Layers:
┌─────────────────────────────────┐
│ Workspace Volume (Read/Write) │ ← User data
├─────────────────────────────────┤
│ Application Layer (Read-Only) │ ← MCP server code
├─────────────────────────────────┤
│ Runtime Layer (Read-Only) │ ← Node.js/Python runtime
├─────────────────────────────────┤
│ Base OS Layer (Read-Only) │ ← Alpine Linux base
└─────────────────────────────────┘
# Secure mount configuration
volumes:
# Workspace data (isolated per workspace)
- type: volume
source: workspace-${WORKSPACE_ID}
target: /workspace
read_only: false
# Temporary storage (cleaned on restart)
- type: tmpfs
target: /tmp
tmpfs:
size: 100m
mode: 1777
# Bind mounts are explicitly prohibited
# No access to host file system
# Non-root user execution
RUN adduser -D -s /bin/sh mcpx
USER mcpx
# Restricted permissions
RUN chmod 750 /workspace
RUN chown mcpx:mcpx /workspace
sequenceDiagram
participant C as Client
participant G as API Gateway
participant A as Auth Service
participant D as Docker Container
participant M as MCP Server
C->>G: MCP Request + JWT
G->>A: Validate Token
A-->>G: User Context
G->>G: Check Workspace Access
G->>D: Proxy Request
D->>M: Local MCP Call
M-->>D: MCP Response
D-->>G: Response Data
G-->>C: Filtered Response
class SecureMCPProxy {
async proxyRequest(request: MCPRequest, context: UserContext): Promise<MCPResponse> {
// 1. Validate request against workspace permissions
await this.validateWorkspaceAccess(context.userId, request.workspaceId);
// 2. Sanitize request payload
const sanitizedRequest = this.sanitizeRequest(request);
// 3. Route to container
const container = await this.getWorkspaceContainer(request.workspaceId);
const response = await container.sendMCPRequest(sanitizedRequest);
// 4. Filter response data
return this.filterResponse(response, context.permissions);
}
private sanitizeRequest(request: MCPRequest): MCPRequest {
// Remove potentially dangerous parameters
const { exec, eval, import: importStmt, ...safe } = request.params;
return { ...request, params: safe };
}
}
# Container capabilities (minimal set)
cap_add:
- SETUID
- SETGID
cap_drop:
- ALL
- SYS_ADMIN
- NET_ADMIN
- SYS_PTRACE
# Immutable container base
FROM alpine:3.18
RUN adduser -D mcpx
USER mcpx
# Read-only root filesystem
docker run --read-only --tmpfs /tmp --tmpfs /var/tmp
class ContainerSecurityScanner {
async scanImage(imageTag: string): Promise<SecurityReport> {
// Vulnerability scanning
const vulns = await this.scanner.scanImage(imageTag);
// Policy compliance check
const compliance = await this.checkCompliance(imageTag);
// Generate security report
return {
vulnerabilities: vulns,
compliance: compliance,
recommendation: this.getRecommendation(vulns, compliance)
};
}
}
class RuntimeSecurityMonitor {
async monitorContainer(containerId: string) {
// Resource usage monitoring
const metrics = await this.collectMetrics(containerId);
// Anomaly detection
if (this.detectAnomaly(metrics)) {
await this.alertAndQuarantine(containerId);
}
// Network traffic analysis
await this.analyzeNetworkTraffic(containerId);
}
}
| Feature | MCPX (Container) | Process Isolation |
|---|---|---|
| File System | Complete isolation | Shared file system |
| Network | Isolated network stack | Shared network |
| Resources | Hard limits | Soft limits |
| Recovery | Complete cleanup | Potential residue |
| Security | Kernel-level isolation | User-space isolation |
| Feature | MCPX (Container) | Virtual Machine |
|---|---|---|
| Startup Time | 2-5 seconds | 30-60 seconds |
| Resource Overhead | ~50MB | 500MB+ |
| Isolation Level | Process isolation | Hardware isolation |
| Density | 100+ per host | 10-20 per host |
| Management | Container orchestration | Hypervisor |
| Feature | MCPX | Chrome Sandbox | FreeBSD Jail |
|---|---|---|---|
| Portability | Cross-platform | Chrome-specific | FreeBSD only |
| Overhead | Low | Very low | Low |
| Flexibility | High | Low | Medium |
| Ecosystem | Docker ecosystem | Browser only | OS-specific |
interface ContainerMetrics {
cpuUsage: number; // 5-10% overhead
memoryOverhead: number; // 20-50MB base
storageOverhead: number; // 100-200MB per container
networkLatency: number; // <1ms additional latency
}
// Intel TXT / AMD SVM integration
class HardwareIsolation {
async enableTrustedExecution(container: Container) {
await container.enableTEE(); // Trusted Execution Environment
await container.attestRemotely(); // Remote attestation
}
}
# Istio service mesh integration
apiVersion: networking.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: mcpx-workspace-policy
spec:
rules:
- from:
- source:
principals: ["cluster.local/ns/mcpx/sa/api-gateway"]
- to:
- operation:
methods: ["POST"]
paths: ["/mcp/*"]
class AIThreatDetection {
async analyzeContainerBehavior(containerId: string) {
const behavior = await this.collectBehaviorData(containerId);
const prediction = await this.mlModel.predict(behavior);
if (prediction.threatLevel > 0.8) {
await this.quarantineContainer(containerId);
}
}
}
MCPX's container-based isolation strategy provides enterprise-grade security for running MCP servers. By combining Docker's proven container technology with custom security policies, resource management, and network isolation, MCPX ensures that:
This approach balances security, performance, and usability, making MCPX suitable for both development and production environments where security is critical.
The container isolation model positions MCPX as a secure, scalable platform for MCP server orchestration, providing the foundation for safe AI-agent interactions in enterprise environments.