Loading...
Loading...
One of MCPX's most powerful features is its workspace system, which provides complete isolation between different environments or projects. Whether you're managing development, staging, and production environments, or organizing MCP servers for different teams, workspaces ensure clean separation and enhanced security.
Workspaces in MCPX are isolated environments that contain:
Think of workspaces as separate "projects" or "environments" within your organization, each with its own isolated runtime.
MCPX implements a unique architecture where each workspace gets its own dedicated container:
Organization: "Acme Corp"
├── Workspace: "Development"
│ └── Container: mcpx-org123-dev-workspace
│ ├── MCP Server: filesystem
│ ├── MCP Server: database
│ └── MCP Server: github
├── Workspace: "Staging"
│ └── Container: mcpx-org123-staging-workspace
│ ├── MCP Server: filesystem
│ └── MCP Server: database
└── Workspace: "Production"
└── Container: mcpx-org123-prod-workspace
└── MCP Server: database (readonly)
MCPX uses a predictable naming pattern for workspace containers:
mcpx-{orgId}-{workspaceSlug}
For example:
mcpx-org_abc123-developmentmcpx-org_abc123-stagingmcpx-org_abc123-productionThis naming ensures containers are easily identifiable and prevents conflicts.
Each workspace container has its own resource limits:
// Default workspace resource limits
{
memoryMb: 512, // 512MB RAM limit
cpuShares: 512, // CPU allocation
storageMb: 1024 // 1GB storage limit
}
These limits prevent one workspace from affecting another's performance.
Each workspace gets unique port allocations:
// Example port allocation for a workspace
{
mcpx: 9001, // MCPX server port
api: 8081, // API gateway port
metrics: 9091, // Metrics endpoint
web: 3001 // Web interface
}
Port ranges are automatically managed to prevent conflicts between workspaces.
Workspaces provide multiple security layers:
MCP server configurations are completely separated:
// Development workspace might have debug MCP servers
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["@modelcontextprotocol/server-filesystem", "/tmp/dev-files"]
},
"database": {
"command": "mcp-server-postgres",
"args": ["--connection", "postgres://dev:dev@localhost/dev"]
}
}
}
// Production workspace has different, secured configurations
{
"mcpServers": {
"database": {
"command": "mcp-server-postgres",
"args": ["--connection", "postgres://user:pass@prod-db/prod", "--readonly"]
}
}
}
You can create workspaces through the MCPX dashboard or API:
Via Dashboard:
Via API:
curl -X POST /api/org/{orgId}/workspaces \
-H "Content-Type: application/json" \
-d '{
"name": "Development Environment",
"slug": "development",
"description": "Development and testing environment",
"visibility": "PRIVATE"
}'
When creating a workspace, you can configure:
{
name: "Development",
slug: "development",
description: "Development and testing environment",
visibility: "PRIVATE", // PRIVATE, INTERNAL, SHARED
settings: {
resources: {
maxMemoryMb: 1024, // Increase memory for dev work
maxCpuShares: 1024, // More CPU for development
maxStorageMb: 2048 // Extra storage for dev files
},
security: {
allowedTools: ["filesystem", "git", "database"],
blockedTools: ["dangerous-tool"],
rateLimits: {
requestsPerMinute: 100
}
}
}
}
Workspaces support role-based access control:
// Workspace roles and permissions
const roles = {
OWNER: [
"view", "edit", "manage", "delete",
"invite_users", "manage_containers"
],
ADMIN: [
"view", "edit", "manage",
"invite_users", "manage_containers"
],
EDITOR: [
"view", "edit", "manage_containers"
],
VIEWER: [
"view"
]
}
Adding Members:
# Add a user to a workspace
curl -X POST /api/org/{orgId}/workspaces/{workspaceId}/members \
-d '{
"userId": "user_123",
"role": "EDITOR"
}'
// Development Workspace
{
name: "Development",
servers: ["filesystem", "database-dev", "github", "debugging-tools"],
resources: { memoryMb: 1024 }, // More resources for development
visibility: "INTERNAL" // All team members can access
}
// Staging Workspace
{
name: "Staging",
servers: ["database-staging", "github"],
resources: { memoryMb: 512 }, // Production-like resources
visibility: "PRIVATE" // Limited access for testing
}
// Production Workspace
{
name: "Production",
servers: ["database-prod-readonly"],
resources: { memoryMb: 256 }, // Minimal resources
visibility: "PRIVATE" // Highly restricted access
}
// Frontend Team Workspace
{
name: "Frontend Team",
servers: ["filesystem", "github", "figma-api", "component-lib"],
members: ["frontend-dev-1", "frontend-dev-2", "ui-designer"]
}
// Backend Team Workspace
{
name: "Backend Team",
servers: ["database", "redis", "github", "docker-api"],
members: ["backend-dev-1", "backend-dev-2", "devops"]
}
// Data Science Workspace
{
name: "Data Science",
servers: ["jupyter", "database-analytics", "ml-models"],
resources: { memoryMb: 2048 }, // More resources for ML workloads
members: ["data-scientist-1", "ml-engineer"]
}
// Client A Project
{
name: "Client Alpha Project",
servers: ["filesystem", "client-alpha-db", "client-alpha-apis"],
visibility: "PRIVATE",
members: ["project-manager-1", "dev-team-alpha"]
}
// Client B Project
{
name: "Client Beta Project",
servers: ["filesystem", "client-beta-db", "client-beta-apis"],
visibility: "PRIVATE",
members: ["project-manager-2", "dev-team-beta"]
}
MCPX automatically manages workspace containers to optimize resource usage:
// Hibernation triggers
const hibernationRules = {
idleThreshold: 30 * 60 * 1000, // 30 minutes of inactivity
resourceThreshold: {
maxMemoryPercent: 5, // < 5% memory usage
maxCpuPercent: 1 // < 1% CPU usage
}
}
// When hibernating:
// 1. Container state is saved to database
// 2. Docker container is stopped
// 3. Ports are released
// 4. Resources are freed
// When waking up:
// 1. New ports are allocated
// 2. Container is recreated with saved state
// 3. MCP servers are restarted
// 4. Workspace becomes active again
MCPX includes robust container discovery to handle Docker restarts:
// Container discovery process
async function discoverWorkspaceContainer(orgId, workspaceSlug) {
// 1. Find containers by label
const containers = await docker.listContainers({
all: true,
filters: {
label: [`mcpx.org=${orgId}`, `mcpx.workspace.slug=${workspaceSlug}`]
}
});
// 2. Sync port mappings with database
const ports = extractPortMappings(containers[0]);
await syncPortsToDatabase(workspaceId, ports);
// 3. Update registry for fast access
updateWorkspaceRegistry(workspaceId, containerInfo);
}
Each workspace can have its own authentication:
// Organization-level internal API key (shared)
const orgApiKey = await getOrganizationApiKey(orgId);
// Workspace-specific authentication (future feature)
const workspaceApiKey = await getWorkspaceApiKey(orgId, workspaceId);
Workspaces are isolated at the network level:
// Container networking configuration
const containerConfig = {
NetworkMode: 'bridge',
HostConfig: {
PortBindings: {
'9002/tcp': [{ HostPort: allocatedPorts.mcpx.toString() }]
},
// Memory and CPU limits
Memory: workspace.maxMemoryMb * 1024 * 1024,
CpuShares: workspace.maxCpuShares
},
// Security labels
Labels: {
'mcpx.type': 'workspace',
'mcpx.org': orgId,
'mcpx.workspace': workspaceId,
'mcpx.workspace.slug': workspaceSlug
}
}
Control which tools are available in each workspace:
// Workspace tool permissions
{
workspaceId: "ws_123",
toolName: "filesystem",
allowedRoles: ["OWNER", "ADMIN", "EDITOR"],
isBlocked: false,
rateLimitOverride: 50 // Override default rate limit
}
Recommended Structure:
Organization: "Your Company"
├── development (all developers, full tool access)
├── staging (limited access, production-like setup)
├── production (minimal access, readonly tools)
└── sandbox (experimental, isolated testing)
// Development: More resources for productivity
{
memoryMb: 1024,
cpuShares: 1024,
storageMb: 2048
}
// Staging: Production-like resources
{
memoryMb: 512,
cpuShares: 512,
storageMb: 1024
}
// Production: Minimal, monitored resources
{
memoryMb: 256,
cpuShares: 256,
storageMb: 512
}
INTERNAL visibility, all team membersPRIVATE visibility, senior developers + QAPRIVATE visibility, DevOps + team leads onlyKeep environment-specific configurations:
// Use environment variables in MCP server configs
{
"database": {
"command": "mcp-server-postgres",
"args": ["--connection", "${DATABASE_URL}"]
},
"filesystem": {
"command": "mcp-filesystem",
"args": ["--root", "${WORKSPACE_ROOT}"]
}
}
// Check if workspace container is healthy
const isHealthy = await isWorkspaceContainerRunning(orgId, workspaceId);
// Get detailed workspace status
const deployment = await getWorkspaceDeployment(orgId, workspaceId);
console.log({
containerName: deployment.containerName,
ports: deployment.ports,
resourceLimits: deployment.resourceLimits,
status: deployment.mcpxContainer.State?.Running ? 'running' : 'stopped'
});
// Get workspace container stats
const stats = await getWorkspaceContainerStats(orgId, workspaceId);
console.log({
memory: {
used: `${stats.memory.usageMb}MB`,
limit: `${stats.memory.limitMb}MB`,
percent: `${stats.memory.percentUsed}%`
},
cpu: {
usage: `${stats.cpu.usagePercent}%`
}
});
netstat -tulpn | grep :9001 # Check if port is in use
docker ps # Should list containers without sudo
docker system df # Check available disk space
free -h # Check available memory
await workspaceMcpService.clearWorkspaceSession(orgId, workspaceId);
const isConnected = await workspaceMcpService.testWorkspaceMCPConnectivity(orgId, workspaceId);
MCPX automatically manages port allocation, but you can check assignments:
// View current port allocations
const workspace = await db.workspace.findUnique({
where: { id: workspaceId },
select: {
containerApiPort: true,
containerMcpxPort: true,
containerMetricsPort: true,
containerWebPort: true
}
});
Pass environment-specific configuration:
const containerConfig = {
Env: [
`ORG_ID=${orgId}`,
`WORKSPACE_ID=${workspaceId}`,
`WORKSPACE_NAME=${workspace.name}`,
`MCP_CONFIG=${JSON.stringify(mcpConfig)}`,
`NODE_ENV=${process.env.NODE_ENV || 'production'}`
]
}
Create reusable workspace configurations:
// Template for development environments
const devTemplate = {
name: "Development Template",
settings: {
resources: { memoryMb: 1024, cpuShares: 1024 },
mcpServers: ["filesystem", "github", "database-dev"],
permissions: {
defaultRole: "EDITOR",
allowedTools: "*"
}
}
}
Export workspace configuration for backup:
# Export workspace settings
curl /api/org/{orgId}/workspaces/{workspaceId}/export > workspace-backup.json
# Import to new workspace
curl -X POST /api/org/{orgId}/workspaces/import \
-d @workspace-backup.json
MCPX's workspace system provides powerful isolation and organization capabilities for managing MCP servers. By understanding the one-container-per-workspace architecture, you can:
The workspace system is designed to grow with your organization, from simple development setups to complex multi-team, multi-environment deployments.
For more advanced workspace configuration and management, check out our Workspace API Reference and Container Orchestration Guide.