Self-Hosted MCP Server
Deploy FAOS MCP Server in your own infrastructure for maximum control and air-gapped environments.
Overviewβ
Self-hosting options:
- MCP Server Only - Connect to FAOS Cloud backend
- Full Stack - Self-host everything (Enterprise+)
This guide covers option 1. Contact enterprise@faosx.ai for full stack deployment.
Prerequisitesβ
- Docker or Kubernetes cluster
- Network access to FAOS API (or self-hosted backend)
- TLS certificates for secure communication
Docker Deploymentβ
Basic Setupβ
# docker-compose.yml
version: '3.8'
services:
faos-mcp:
image: ghcr.io/faosx/faos-mcp:latest
container_name: faos-mcp
environment:
- FAOS_API_URL=https://api.faosx.ai
- FAOS_API_TOKEN=${FAOS_API_TOKEN}
- MCP_HOST=0.0.0.0
- MCP_PORT=3000
- LOG_LEVEL=info
ports:
- "3000:3000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
Deploy:
export FAOS_API_TOKEN=your-token
docker-compose up -d
With Redis Cacheβ
For improved performance with multiple users:
version: '3.8'
services:
faos-mcp:
image: ghcr.io/faosx/faos-mcp:latest
environment:
- FAOS_API_URL=https://api.faosx.ai
- FAOS_API_TOKEN=${FAOS_API_TOKEN}
- REDIS_URL=redis://redis:6379
- CACHE_TTL=300
ports:
- "3000:3000"
depends_on:
- redis
redis:
image: redis:7-alpine
volumes:
- redis-data:/data
volumes:
redis-data:
Kubernetes Deploymentβ
Namespace and Secretsβ
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: faos-mcp
---
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: faos-credentials
namespace: faos-mcp
type: Opaque
stringData:
api-token: "your-faos-api-token"
Deploymentβ
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: faos-mcp
namespace: faos-mcp
spec:
replicas: 2
selector:
matchLabels:
app: faos-mcp
template:
metadata:
labels:
app: faos-mcp
spec:
containers:
- name: faos-mcp
image: ghcr.io/faosx/faos-mcp:latest
ports:
- containerPort: 3000
env:
- name: FAOS_API_URL
value: "https://api.faosx.ai"
- name: FAOS_API_TOKEN
valueFrom:
secretKeyRef:
name: faos-credentials
key: api-token
- name: MCP_HOST
value: "0.0.0.0"
- name: MCP_PORT
value: "3000"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: faos-mcp
namespace: faos-mcp
spec:
selector:
app: faos-mcp
ports:
- port: 3000
targetPort: 3000
Ingress (Optional)β
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: faos-mcp
namespace: faos-mcp
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- mcp.internal.yourcompany.com
secretName: faos-mcp-tls
rules:
- host: mcp.internal.yourcompany.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: faos-mcp
port:
number: 3000
Client Configurationβ
Local MCP via Networkβ
Configure Claude Desktop to use your self-hosted server:
{
"servers": {
"faos": {
"command": "npx",
"args": ["-y", "mcp-remote-client", "https://mcp.internal.yourcompany.com"]
}
}
}
Or use direct connection:
{
"servers": {
"faos": {
"url": "https://mcp.internal.yourcompany.com",
"transport": "http"
}
}
}
With mTLSβ
For enhanced security:
{
"servers": {
"faos": {
"url": "https://mcp.internal.yourcompany.com",
"transport": "http",
"tls": {
"cert": "/path/to/client.crt",
"key": "/path/to/client.key",
"ca": "/path/to/ca.crt"
}
}
}
}
Configuration Optionsβ
Environment Variablesβ
| Variable | Required | Default | Description |
|---|---|---|---|
FAOS_API_URL | Yes | - | FAOS API endpoint |
FAOS_API_TOKEN | Yes | - | API token (or use SSO) |
MCP_HOST | No | 127.0.0.1 | Server bind address |
MCP_PORT | No | 3000 | Server port |
LOG_LEVEL | No | info | Logging level |
REDIS_URL | No | - | Redis for caching |
CACHE_TTL | No | 300 | Cache TTL in seconds |
MAX_CONNECTIONS | No | 100 | Max concurrent connections |
REQUEST_TIMEOUT | No | 30000 | Request timeout (ms) |
Scalingβ
Horizontal scaling considerations:
- MCP server is stateless
- Use Redis for shared cache
- Load balance with session affinity (optional)
Recommended sizing:
| Users | Replicas | CPU | Memory |
|---|---|---|---|
| 1-10 | 1 | 0.5 | 512Mi |
| 10-50 | 2 | 1 | 1Gi |
| 50-200 | 3-5 | 2 | 2Gi |
| 200+ | 5+ | 4 | 4Gi |
Monitoringβ
Prometheus Metricsβ
The server exposes metrics at /metrics:
# prometheus-scrape-config
- job_name: 'faos-mcp'
kubernetes_sd_configs:
- role: pod
namespaces:
names: ['faos-mcp']
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
regex: faos-mcp
action: keep
Key metrics:
faos_mcp_requests_total- Total requests by toolfaos_mcp_request_duration_seconds- Latency histogramfaos_mcp_errors_total- Error count by typefaos_mcp_active_connections- Current connections
Loggingβ
Structured JSON logs for easy parsing:
{
"timestamp": "2026-01-27T10:30:00Z",
"level": "info",
"tool": "faos_invoke_agent",
"user": "user@company.com",
"duration_ms": 1234,
"status": "success"
}
Security Hardeningβ
Network Policies (Kubernetes)β
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: faos-mcp-policy
namespace: faos-mcp
spec:
podSelector:
matchLabels:
app: faos-mcp
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: corporate-network
ports:
- protocol: TCP
port: 3000
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0 # FAOS API
ports:
- protocol: TCP
port: 443
Service Mesh (Istio)β
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: faos-mcp-mtls
namespace: faos-mcp
spec:
selector:
matchLabels:
app: faos-mcp
mtls:
mode: STRICT
Troubleshootingβ
Common Issuesβ
Connection refused:
- Check firewall rules
- Verify service is running:
kubectl get pods -n faos-mcp - Check logs:
kubectl logs -n faos-mcp -l app=faos-mcp
Authentication failed:
- Verify token is correct
- Check token hasn't expired
- Ensure token has required scopes
High latency:
- Enable Redis caching
- Check network route to FAOS API
- Scale up replicas
Health Check Endpointsβ
GET /health- Liveness (server is running)GET /ready- Readiness (can accept requests)GET /metrics- Prometheus metrics
Updatesβ
Image Tagsβ
| Tag | Description |
|---|---|
latest | Latest stable release |
v1.2.3 | Specific version |
main | Latest build (unstable) |
Update Processβ
# Docker
docker-compose pull
docker-compose up -d
# Kubernetes
kubectl set image deployment/faos-mcp \
faos-mcp=ghcr.io/faosx/faos-mcp:v1.2.3 \
-n faos-mcp
Supportβ
For self-hosted deployment support:
- Documentation: docs.faosx.ai/self-hosted
- Enterprise support: enterprise@faosx.ai