Initial homelab GitOps repository setup

This commit establishes the foundation for the homelab GitOps repository:

- Created layered architecture (infrastructure/platform/apps)
- Added MCP servers umbrella chart with SOPS-encrypted secrets
- Configured Flux Kustomizations for infrastructure and platform layers
- Set up SOPS + Age for secrets management
- Added .gitignore and documentation

MCP servers include:
- Gateway with auth (API keys in encrypted secrets)
- n8n MCP (workflow automation)
- Playwright MCP (browser automation)
- Kubernetes MCP (kubectl operations)
- GitHub MCP (repository management)
- Gitea MCP (self-hosted git)
- SQLite MCP (database operations)
- Filesystem MCP (file operations)
- Fetch MCP (HTTP requests)
- Memory MCP (shared memory/state)

All secrets are encrypted with SOPS using Age encryption.
This commit is contained in:
CaffeineTux
2025-11-16 02:28:44 -05:00
commit 9fc30a3573
15 changed files with 1448 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
apiVersion: v2
name: mcp-umbrella
description: Umbrella Helm chart that deploys all MCP servers + MCP Gateway
type: application
version: 1.0.0
appVersion: "1.0.0"
keywords:
- mcp
- model-context-protocol
- automation
- ai
- n8n
- gateway
maintainers:
- name: CaffeineTux
home: https://github.com/modelcontextprotocol
sources:
- https://github.com/modelcontextprotocol/servers
dependencies:
- name: mcp-gateway
version: "1.0.0"
repository: "file://../mcp-gateway"
condition: mcp-gateway.enabled
- name: n8n-mcp
version: "1.0.0"
repository: "file://../n8n-mcp"
condition: n8n-mcp.enabled
- name: playwright-mcp
version: "1.0.0"
repository: "file://../playwright-mcp"
condition: playwright-mcp.enabled
- name: kubernetes-mcp
version: "1.0.0"
repository: "file://../kubernetes-mcp"
condition: kubernetes-mcp.enabled
- name: github-mcp
version: "1.0.0"
repository: "file://../github-mcp"
condition: github-mcp.enabled
- name: postgresql-mcp
version: "1.0.0"
repository: "file://../postgresql-mcp"
condition: postgresql-mcp.enabled
- name: sqlite-mcp
version: "1.0.0"
repository: "file://../sqlite-mcp"
condition: sqlite-mcp.enabled
- name: prometheus-mcp
version: "1.0.0"
repository: "file://../prometheus-mcp"
condition: prometheus-mcp.enabled
- name: slack-mcp
version: "1.0.0"
repository: "file://../slack-mcp"
condition: slack-mcp.enabled
- name: s3-mcp
version: "1.0.0"
repository: "file://../s3-mcp"
condition: s3-mcp.enabled
- name: filesystem-mcp
version: "1.0.0"
repository: "file://../filesystem-mcp"
condition: filesystem-mcp.enabled
- name: puppeteer-mcp
version: "1.0.0"
repository: "file://../puppeteer-mcp"
condition: puppeteer-mcp.enabled
- name: fetch-mcp
version: "1.0.0"
repository: "file://../fetch-mcp"
condition: fetch-mcp.enabled
- name: memory-mcp
version: "1.0.0"
repository: "file://../memory-mcp"
condition: memory-mcp.enabled
- name: gitea-mcp
version: "1.0.0"
repository: "file://../gitea-mcp"
condition: gitea-mcp.enabled

View File

@@ -0,0 +1,394 @@
# MCP Umbrella Helm Chart
Complete deployment solution for the MCP (Model Context Protocol) server ecosystem. This umbrella chart deploys all MCP servers with a central gateway for unified access.
## Architecture
```
┌─────────────────────────────────────────────────────────────────┐
│ MCP Gateway │
│ (LoadBalancer Service) │
│ http://<LoadBalancer-IP>:3000 │
│ │
│ Routes requests to individual MCP servers: │
│ POST /mcp/n8n-mcp → n8n-mcp:3001 │
│ POST /mcp/playwright-mcp → playwright-mcp:3002 │
│ POST /mcp/kubernetes-mcp → kubernetes-mcp:3003 │
│ POST /mcp/github-mcp → github-mcp:3004 │
│ ... (all 13 MCP servers) │
└─────────────────────────────────────────────────────────────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ n8n-MCP │ │Playwright│ │Kubernetes│ │ GitHub │
│ :3001 │ │ MCP │ │ MCP │ │ MCP │
│ │ │ :3002 │ │ :3003 │ │ :3004 │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
... (9 more servers)
┌──────────────────────────────────────────────────────┐
│ Memory MCP (Central State) │
│ :3013 → Redis/PostgreSQL │
│ Provides shared state for all MCP servers │
└──────────────────────────────────────────────────────┘
```
## Features
- **13 MCP Servers** available for automation
- **Central Gateway** with API key authentication
- **LoadBalancer** access to entire MCP ecosystem
- **Memory-MCP** as central coordinator for shared state
- **Selective Deployment** - enable only the servers you need
- **Production-Ready** with RBAC, security contexts, and health checks
- **Auto-Scaling** for gateway and resource-intensive servers
## Quick Start
### 1. Prerequisites
```bash
# Ensure you're in the right directory
cd /data/data/com.termux/files/home/git/mcp-servers/mcp-umbrella
# Build chart dependencies
helm dependency build
```
### 2. Generate API Keys
```bash
# Generate secure API keys for the gateway
echo "n8n API key: $(openssl rand -hex 32)"
echo "admin API key: $(openssl rand -hex 32)"
```
### 3. Configure Required Secrets
Create a `custom-values.yaml` file:
```yaml
mcp-gateway:
gateway:
auth:
apiKeys:
- name: "n8n"
key: "YOUR_N8N_API_KEY_HERE"
- name: "admin"
key: "YOUR_ADMIN_API_KEY_HERE"
n8n-mcp:
n8nMCP:
n8n:
apiKey: "YOUR_N8N_INSTANCE_API_KEY"
github-mcp:
github:
token: "YOUR_GITHUB_TOKEN"
owner: "your-github-username"
```
### 4. Deploy
```bash
# Create the mcp namespace
kubectl create namespace mcp
# Install the umbrella chart
helm install mcp-ecosystem . \
--namespace mcp \
-f custom-values.yaml
```
### 5. Verify Deployment
```bash
# Check all pods
kubectl get pods -n mcp
# Get gateway LoadBalancer IP
kubectl get svc -n mcp mcp-ecosystem-mcp-gateway
# Test health endpoint
GATEWAY_IP=$(kubectl get svc -n mcp mcp-ecosystem-mcp-gateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl http://$GATEWAY_IP:3000/health
```
## MCP Servers Included
| Server | Port | Status | Description |
|--------|------|--------|-------------|
| **mcp-gateway** | 3000 | Always Enabled | Central routing gateway |
| **n8n-mcp** | 3001 | Enabled | n8n workflow automation |
| **playwright-mcp** | 3002 | Enabled | Browser automation |
| **kubernetes-mcp** | 3003 | Enabled | Kubectl operations |
| **github-mcp** | 3004 | Enabled | GitHub API operations |
| **postgresql-mcp** | 3005 | Disabled* | PostgreSQL operations |
| **sqlite-mcp** | 3006 | Enabled | SQLite operations |
| **prometheus-mcp** | 3007 | Disabled* | Metrics queries |
| **slack-mcp** | 3008 | Disabled* | Slack operations |
| **s3-mcp** | 3009 | Disabled* | S3/MinIO operations |
| **filesystem-mcp** | 3010 | Enabled | File operations |
| **puppeteer-mcp** | 3011 | Disabled* | Chrome automation |
| **fetch-mcp** | 3012 | Enabled | HTTP requests |
| **memory-mcp** | 3013 | Enabled | Central state coordinator |
*\*Requires additional configuration - see [Configuration](#configuration) section*
## Configuration
### Enabling/Disabling Servers
In your `custom-values.yaml`:
```yaml
# Enable a disabled server
prometheus-mcp:
enabled: true
prometheus:
url: "http://your-prometheus-server"
# Disable an enabled server
playwright-mcp:
enabled: false
```
### Configuring the Gateway
```yaml
mcp-gateway:
service:
type: LoadBalancer
loadBalancerIP: "192.168.1.100" # Optional static IP
ingress:
enabled: true # Enable Ingress (currently disabled)
hosts:
- host: mcp.caffeinetux.com
paths:
- path: /
pathType: Prefix
autoscaling:
enabled: true
minReplicas: 1
maxReplicas: 5
```
### Configuring Memory-MCP Backend
Choose Redis or PostgreSQL:
```yaml
memory-mcp:
storage:
backend: "redis" # or "postgres"
redis:
host: "redis.default.svc.cluster.local"
port: 6379
password: "your-redis-password"
```
## Usage Examples
### From n8n Workflow
Use the HTTP Request node:
```javascript
// n8n HTTP Request Node
Method: POST
URL: http://mcp-ecosystem-mcp-gateway.mcp.svc.cluster.local:3000/mcp/playwright-mcp
Authentication: Header Auth
Header Name: Authorization
Header Value: Bearer YOUR_N8N_API_KEY
Body:
{
"jsonrpc": "2.0",
"method": "navigate",
"params": {
"url": "https://example.com"
},
"id": 1
}
```
### From External Client
```bash
# Get list of available servers
curl -H "Authorization: Bearer YOUR_ADMIN_API_KEY" \
http://<LoadBalancer-IP>:3000/servers
# Make MCP request to Kubernetes-MCP
curl -H "Authorization: Bearer YOUR_ADMIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "get_pods",
"params": {"namespace": "default"},
"id": 1
}' \
http://<LoadBalancer-IP>:3000/mcp/kubernetes-mcp
```
### Store Shared State in Memory-MCP
```bash
# Store a value
curl -H "Authorization: Bearer YOUR_ADMIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "memory_store",
"params": {
"namespace": "workflow",
"key": "user_session",
"value": {"user_id": 123, "state": "active"},
"ttl": 3600
},
"id": 1
}' \
http://<LoadBalancer-IP>:3000/mcp/memory-mcp
# Retrieve the value
curl -H "Authorization: Bearer YOUR_ADMIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "memory_retrieve",
"params": {
"namespace": "workflow",
"key": "user_session"
},
"id": 2
}' \
http://<LoadBalancer-IP>:3000/mcp/memory-mcp
```
## Upgrading
```bash
# Update dependencies
helm dependency update
# Upgrade the deployment
helm upgrade mcp-ecosystem . \
--namespace mcp \
-f custom-values.yaml
```
## Uninstalling
```bash
# Remove the deployment
helm uninstall mcp-ecosystem --namespace mcp
# Optionally delete the namespace
kubectl delete namespace mcp
```
## Troubleshooting
### Gateway not accessible
```bash
# Check gateway pod logs
kubectl logs -n mcp -l app.kubernetes.io/name=mcp-gateway
# Check service
kubectl describe svc -n mcp mcp-ecosystem-mcp-gateway
```
### MCP server not responding
```bash
# Check specific server logs
kubectl logs -n mcp -l app.kubernetes.io/name=playwright-mcp
# Check if server is registered in gateway
curl -H "Authorization: Bearer YOUR_ADMIN_API_KEY" \
http://<LoadBalancer-IP>:3000/servers
```
### Authentication errors
```bash
# Verify API keys are set
kubectl get secret -n mcp mcp-ecosystem-mcp-gateway-auth -o yaml
# Test without auth (should fail with 401)
curl http://<LoadBalancer-IP>:3000/servers
```
## Resource Requirements
### Minimal Setup (5 servers)
- **CPU**: ~2 cores total
- **Memory**: ~3Gi total
- **Storage**: ~15Gi (PVCs for SQLite, Filesystem, Playwright)
### Full Setup (all 13 servers)
- **CPU**: ~6 cores total
- **Memory**: ~10Gi total
- **Storage**: ~50Gi (with all persistence enabled)
### Per-Server Resources
| Server | CPU Request | CPU Limit | RAM Request | RAM Limit |
|--------|-------------|-----------|-------------|-----------|
| Gateway | 100m | 500m | 128Mi | 512Mi |
| n8n-MCP | 50m | 200m | 128Mi | 256Mi |
| Playwright | 200m | 1000m | 512Mi | 2Gi |
| Kubernetes | 100m | 100m | 128Mi | 128Mi |
| Memory-MCP | 100m | 200m | 256Mi | 512Mi |
| Others | 50-100m | 100-200m | 64-128Mi | 128-256Mi |
## Security
- **API Key Authentication** on gateway
- **RBAC** for Kubernetes-MCP cluster access
- **Secrets** for all credentials (GitHub tokens, database passwords, etc.)
- **Non-root users** in all containers
- **Read-only root filesystem** where possible
- **Network policies** (add custom NetworkPolicy resources as needed)
## Advanced Configuration
### Custom n8n Node
See [n8n-mcp-node/README.md](../n8n-mcp-node/README.md) for installing a custom n8n node that simplifies MCP gateway access.
### Monitoring
```yaml
# Enable Prometheus monitoring
prometheus-mcp:
enabled: true
prometheus:
url: "http://prometheus-server.prometheus.svc.cluster.local"
```
### High Availability
```yaml
mcp-gateway:
replicaCount: 3
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
```
## Support
For issues or questions:
- Check the individual MCP server READMEs in `../*/README.md`
- Review logs: `kubectl logs -n mcp <pod-name>`
- GitHub Issues: https://github.com/modelcontextprotocol/servers
## License
See individual MCP server repositories for their respective licenses.

View File

@@ -0,0 +1,41 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: mcp-umbrella
namespace: mcp
spec:
interval: 10m
timeout: 5m
chart:
spec:
chart: ./platform/mcp-servers
sourceRef:
kind: GitRepository
name: homelab
namespace: flux-system
interval: 5m
# Depend on namespace and secrets
dependsOn:
- name: mcp-secrets
namespace: mcp
install:
createNamespace: false
remediation:
retries: 3
upgrade:
remediation:
retries: 3
remediateLastFailure: true
cleanupOnFail: true
valuesFrom:
- kind: ConfigMap
name: mcp-umbrella-values
optional: true
values:
# Values from values.yaml will be automatically used
# Additional overrides can be placed here

View File

@@ -0,0 +1,13 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mcp
resources:
- namespace.yaml
- secrets.enc.yaml
- helmrelease.yaml
# SOPS decryption for encrypted secrets
# Flux will automatically decrypt files matching this pattern
# Make sure flux-system has the age secret configured

View File

@@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: mcp
labels:
app.kubernetes.io/part-of: mcp-ecosystem
toolkit.fluxcd.io/tenant: platform

View File

@@ -0,0 +1,119 @@
apiVersion: v1
kind: Secret
metadata:
name: mcp-gateway-api-keys
namespace: mcp
type: Opaque
stringData:
n8n-key: ENC[AES256_GCM,data:s/IIC99kiFR64YcHrukDfHcctfrO6gMY2jpbql2VIikwhpMAnXDN4mVddlwNIwHOtjIgP6oL8c9Q4lfiANy5sg==,iv:rl1pR9IcsOsPNtvb7sH8VE7cEkb1SrKqcqoHTLBcedU=,tag:PJCcbvp3pd94XWPMo2IQ0Q==,type:str]
admin-key: ENC[AES256_GCM,data:m0QIropOzru9e7VxowzFphJYA0O31BLBr+fyTdHgCkHtMpwCgxvBQfmwTpeBM355CPGLUiZ14YhYWXRiOc2fMg==,iv:xVA0HRgu/NaEprersvP9mxWD6rJrsI1yJhBJ+hUaAEY=,tag:bgY2YEKKnHyH5zOCIFStag==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1c7ke5ajhtzua7lrvzsg2p7krnnqv5jhvafh4lsl2s022j46jggnss4rxry
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1eTE4UEt0bzN4OWJuamNt
Mm9aZkNRdVZIckZuMmZNeWVGWkhhWTl2dERjCldzWVZxemQ2ZTJaOFF1cFBRcHFn
eENmcmhjaUNEOFZ1anNLWEpOcGJRVmMKLS0tIG05N1pldmY5d1ZXUVRleXlQWWx1
dmJRbnFzNlZRZElTQVZ3RmNzVzRZWUUKkcXqeJd3Domjt7TlKn78HqgGiCOQ0whM
ZwgQ+6Q97D95bBK3Wa0TiZ4FNqKJvTa5jQ0Onh03eQ5eXKHJiqTcdw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-11-16T07:26:31Z"
mac: ENC[AES256_GCM,data:WliyDuYa0RUFoYOqqaYyXmmf8NYKe9sdOgSaOfSjhnHwvT4Z2nh+k/RR9fmpZ7qjrZFVdE9kfur21Mh6hKZnJ7vlA63u3YFq4Buu3fOdlSPLA3FRTeDbFy0kIDM2R4OqkXQrCVUFxGaQkG4lKw6XAKLZDnmQw9059wKRbbMTWpc=,iv:pU5RJCtoctkIy22VgFJPLEkmsgA/t4x1FwEJgkc1pdE=,tag:96pa5LoubQurpR8Yydcr2A==,type:str]
pgp: []
encrypted_regex: ^(data|stringData|password|token|apiKey|secret|key)$
version: 3.9.2
---
apiVersion: v1
kind: Secret
metadata:
name: n8n-mcp-api-key
namespace: mcp
type: Opaque
stringData:
apiKey: ENC[AES256_GCM,data:v51UaiPHLi0acynqtXkEr1jCcf39hLa0pgcKPg2xLUwTf53IlN+HqbwTzWByTu4zBAHksCqrU1nvCdhi5wuAxjv1YVpObytA+UyPnM13UEw7ThrGqlpq4+lytA0ZsIFgjsDqb7T7Xyr1gNrQjZVpT17LQGAhbEQAuhXxzR3VIzOFpFj4zO7+im9WlEMUz5oq/T70/PMYSR7zw12we9GHfze5WZQ42AuwCIk7kuloSd+/9UzQyJZlRSVVyPBmtJGz3Mfoa02F84RgJsEHEXou,iv:pyO0SFcVFXenBTVMNcC/O9jEfVr79ZMQXVagAc9mjKc=,tag:A+3wEzEkt7qMcYZSR77xgA==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1c7ke5ajhtzua7lrvzsg2p7krnnqv5jhvafh4lsl2s022j46jggnss4rxry
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1eTE4UEt0bzN4OWJuamNt
Mm9aZkNRdVZIckZuMmZNeWVGWkhhWTl2dERjCldzWVZxemQ2ZTJaOFF1cFBRcHFn
eENmcmhjaUNEOFZ1anNLWEpOcGJRVmMKLS0tIG05N1pldmY5d1ZXUVRleXlQWWx1
dmJRbnFzNlZRZElTQVZ3RmNzVzRZWUUKkcXqeJd3Domjt7TlKn78HqgGiCOQ0whM
ZwgQ+6Q97D95bBK3Wa0TiZ4FNqKJvTa5jQ0Onh03eQ5eXKHJiqTcdw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-11-16T07:26:31Z"
mac: ENC[AES256_GCM,data:WliyDuYa0RUFoYOqqaYyXmmf8NYKe9sdOgSaOfSjhnHwvT4Z2nh+k/RR9fmpZ7qjrZFVdE9kfur21Mh6hKZnJ7vlA63u3YFq4Buu3fOdlSPLA3FRTeDbFy0kIDM2R4OqkXQrCVUFxGaQkG4lKw6XAKLZDnmQw9059wKRbbMTWpc=,iv:pU5RJCtoctkIy22VgFJPLEkmsgA/t4x1FwEJgkc1pdE=,tag:96pa5LoubQurpR8Yydcr2A==,type:str]
pgp: []
encrypted_regex: ^(data|stringData|password|token|apiKey|secret|key)$
version: 3.9.2
---
apiVersion: v1
kind: Secret
metadata:
name: github-mcp-token
namespace: mcp
type: Opaque
stringData:
token: ENC[AES256_GCM,data:TDOzJ8eWs+q2y8//fGU5kQN9LBkuvZ0oYvDVG94XsJ9Ul33YBgGCjQ==,iv:hRF5eizLhux3YLoKuCYhdJzQr4jEyGItp6TfYq/OuZ4=,tag:9EiwNhGU/uZ4A0jxQZ4Dwg==,type:str]
owner: ENC[AES256_GCM,data:Wk1V8l0vw7EbHLc=,iv:IcOTaXB7l0+G0ewj33RmwOB14sCYNduO1jDsSTvvjv4=,tag:ois9qnprTmfo3DrtCc/pnQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1c7ke5ajhtzua7lrvzsg2p7krnnqv5jhvafh4lsl2s022j46jggnss4rxry
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1eTE4UEt0bzN4OWJuamNt
Mm9aZkNRdVZIckZuMmZNeWVGWkhhWTl2dERjCldzWVZxemQ2ZTJaOFF1cFBRcHFn
eENmcmhjaUNEOFZ1anNLWEpOcGJRVmMKLS0tIG05N1pldmY5d1ZXUVRleXlQWWx1
dmJRbnFzNlZRZElTQVZ3RmNzVzRZWUUKkcXqeJd3Domjt7TlKn78HqgGiCOQ0whM
ZwgQ+6Q97D95bBK3Wa0TiZ4FNqKJvTa5jQ0Onh03eQ5eXKHJiqTcdw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-11-16T07:26:31Z"
mac: ENC[AES256_GCM,data:WliyDuYa0RUFoYOqqaYyXmmf8NYKe9sdOgSaOfSjhnHwvT4Z2nh+k/RR9fmpZ7qjrZFVdE9kfur21Mh6hKZnJ7vlA63u3YFq4Buu3fOdlSPLA3FRTeDbFy0kIDM2R4OqkXQrCVUFxGaQkG4lKw6XAKLZDnmQw9059wKRbbMTWpc=,iv:pU5RJCtoctkIy22VgFJPLEkmsgA/t4x1FwEJgkc1pdE=,tag:96pa5LoubQurpR8Yydcr2A==,type:str]
pgp: []
encrypted_regex: ^(data|stringData|password|token|apiKey|secret|key)$
version: 3.9.2
---
apiVersion: v1
kind: Secret
metadata:
name: gitea-mcp-token
namespace: mcp
type: Opaque
stringData:
token: ENC[AES256_GCM,data:lmW9WhvdUiSa8rCN7KXHV6USg93QaWqyEA2XCPYshQWm5ZQ0VGza/Q==,iv:Kw6CbzqFKiqELTHZkABdnB1/WUhiP1yW9fXJ94TGSdY=,tag:jVQ8FbHfqwmiGHhsA+is8Q==,type:str]
owner: ENC[AES256_GCM,data:QBY6p1A=,iv:tqcrMSknyxs9DtKzXkotZGM2szY9/LO/9Aa0UKH2cG4=,tag:Gw0DFRNx3WZFld5ZGJY32g==,type:str]
url: ENC[AES256_GCM,data:mTZ85n5G1j3lphgIwMkKket3ARayHhvY8lCcquhrbIBCwBbTeo/zoT2fxTiU6w==,iv:1oZ2Aa+bTqqoqsUT4+cR43f5WSdzgspLFufrMS6Cq4g=,tag:9tker2sFgiC+fRvSo9/X0Q==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1c7ke5ajhtzua7lrvzsg2p7krnnqv5jhvafh4lsl2s022j46jggnss4rxry
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1eTE4UEt0bzN4OWJuamNt
Mm9aZkNRdVZIckZuMmZNeWVGWkhhWTl2dERjCldzWVZxemQ2ZTJaOFF1cFBRcHFn
eENmcmhjaUNEOFZ1anNLWEpOcGJRVmMKLS0tIG05N1pldmY5d1ZXUVRleXlQWWx1
dmJRbnFzNlZRZElTQVZ3RmNzVzRZWUUKkcXqeJd3Domjt7TlKn78HqgGiCOQ0whM
ZwgQ+6Q97D95bBK3Wa0TiZ4FNqKJvTa5jQ0Onh03eQ5eXKHJiqTcdw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-11-16T07:26:31Z"
mac: ENC[AES256_GCM,data:WliyDuYa0RUFoYOqqaYyXmmf8NYKe9sdOgSaOfSjhnHwvT4Z2nh+k/RR9fmpZ7qjrZFVdE9kfur21Mh6hKZnJ7vlA63u3YFq4Buu3fOdlSPLA3FRTeDbFy0kIDM2R4OqkXQrCVUFxGaQkG4lKw6XAKLZDnmQw9059wKRbbMTWpc=,iv:pU5RJCtoctkIy22VgFJPLEkmsgA/t4x1FwEJgkc1pdE=,tag:96pa5LoubQurpR8Yydcr2A==,type:str]
pgp: []
encrypted_regex: ^(data|stringData|password|token|apiKey|secret|key)$
version: 3.9.2

View File

@@ -0,0 +1,311 @@
# MCP Umbrella Chart - Central Configuration
# This chart deploys all MCP servers and the central gateway
# Global configuration shared across all MCP servers
global:
# Namespace to deploy all MCP services
namespace: mcp
# Common labels applied to all resources
commonLabels:
app.kubernetes.io/part-of: mcp-ecosystem
managed-by: mcp-umbrella
# Image pull policy for all charts
imagePullPolicy: IfNotPresent
# Security context for all pods
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
# =============================================================================
# MCP Gateway Configuration
# =============================================================================
mcp-gateway:
enabled: true
replicaCount: 1
service:
type: LoadBalancer
port: 3000
# loadBalancerIP: "192.168.1.100" # Uncomment and set your LoadBalancer IP
ingress:
enabled: false # Disabled by default, can enable later
className: "nginx"
hosts:
- host: mcp.caffeinetux.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: mcp-gateway-tls
hosts:
- mcp.caffeinetux.com
gateway:
auth:
enabled: true
apiKeys:
- name: "n8n"
key: "" # SET THIS: Generate with: openssl rand -hex 32
- name: "admin"
key: "" # SET THIS: Generate with: openssl rand -hex 32
logLevel: "info"
timeout: 30000
# MCP servers will be auto-populated from enabled servers below
servers:
n8n-mcp:
host: "n8n-mcp"
port: 3001
playwright-mcp:
host: "playwright-mcp"
port: 3002
kubernetes-mcp:
host: "kubernetes-mcp"
port: 3003
github-mcp:
host: "github-mcp"
port: 3004
postgresql-mcp:
host: "postgresql-mcp"
port: 3005
sqlite-mcp:
host: "sqlite-mcp"
port: 3006
prometheus-mcp:
host: "prometheus-mcp"
port: 3007
slack-mcp:
host: "slack-mcp"
port: 3008
s3-mcp:
host: "s3-mcp"
port: 3009
filesystem-mcp:
host: "filesystem-mcp"
port: 3010
puppeteer-mcp:
host: "puppeteer-mcp"
port: 3011
fetch-mcp:
host: "fetch-mcp"
port: 3012
memory-mcp:
host: "memory-mcp"
port: 3013
gitea-mcp:
host: "gitea-mcp"
port: 3014
autoscaling:
enabled: true
minReplicas: 1
maxReplicas: 3
targetCPUUtilizationPercentage: 80
# =============================================================================
# n8n MCP Server Configuration
# =============================================================================
n8n-mcp:
enabled: true
n8nMCP:
n8n:
url: "http://n8n.n8n.svc.cluster.local:5678"
apiKey: "" # SET THIS: Get from n8n settings
mode: "full"
logLevel: "info"
# =============================================================================
# Playwright MCP Server Configuration
# =============================================================================
playwright-mcp:
enabled: true
playwrightMCP:
browsers:
- chromium
- firefox
- webkit
headless: true
timeout: 30000
persistence:
enabled: true
size: 10Gi
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 200m
memory: 512Mi
# =============================================================================
# Kubernetes MCP Server Configuration
# =============================================================================
kubernetes-mcp:
enabled: true
rbac:
create: true
# ClusterRole permissions for kubectl operations
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps", "secrets"]
verbs: ["get", "list", "watch", "create", "update", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets", "daemonsets"]
verbs: ["get", "list", "watch", "create", "update", "delete"]
# =============================================================================
# GitHub MCP Server Configuration
# =============================================================================
github-mcp:
enabled: true
github:
token: "" # SET THIS: GitHub Personal Access Token
owner: "" # SET THIS: Default GitHub org/user
# =============================================================================
# PostgreSQL MCP Server Configuration
# =============================================================================
postgresql-mcp:
enabled: false # Disabled by default - requires PostgreSQL instance
postgresql:
host: "postgresql.default.svc.cluster.local"
port: 5432
database: "postgres"
user: "postgres"
password: "" # SET THIS if enabling
# =============================================================================
# SQLite MCP Server Configuration
# =============================================================================
sqlite-mcp:
enabled: true
sqlite:
databasePath: "/data/sqlite.db"
persistence:
enabled: true
size: 1Gi
# =============================================================================
# Prometheus MCP Server Configuration
# =============================================================================
prometheus-mcp:
enabled: false # Disabled by default - requires Prometheus instance
prometheus:
url: "http://prometheus-server.prometheus.svc.cluster.local"
# =============================================================================
# Slack MCP Server Configuration
# =============================================================================
slack-mcp:
enabled: false # Disabled by default - requires Slack tokens
slack:
botToken: "" # SET THIS: Slack Bot Token
appToken: "" # OPTIONAL: Slack App Token for socket mode
# =============================================================================
# S3 MCP Server Configuration
# =============================================================================
s3-mcp:
enabled: false # Disabled by default - requires S3/MinIO credentials
s3:
endpoint: "" # e.g., "s3.amazonaws.com" or MinIO endpoint
region: "us-east-1"
bucket: ""
accessKeyId: "" # SET THIS
secretAccessKey: "" # SET THIS
# =============================================================================
# Filesystem MCP Server Configuration
# =============================================================================
filesystem-mcp:
enabled: true
filesystem:
rootPath: "/data"
persistence:
enabled: true
size: 5Gi
# =============================================================================
# Puppeteer MCP Server Configuration
# =============================================================================
puppeteer-mcp:
enabled: false # Disabled by default - resource intensive
puppeteer:
headless: true
timeout: 30000
persistence:
enabled: true
downloadSize: 5Gi
screenshotSize: 5Gi
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
# =============================================================================
# Fetch MCP Server Configuration
# =============================================================================
fetch-mcp:
enabled: true
fetch:
userAgent: "MCP-Fetch-Server/1.0"
timeout: 30000
# =============================================================================
# Memory MCP Server Configuration (Central Coordinator)
# =============================================================================
memory-mcp:
enabled: true
storage:
backend: "redis" # or "postgres"
# Redis backend configuration (if backend: redis)
redis:
host: "redis.default.svc.cluster.local" # Change to your Redis service
port: 6379
password: "" # SET THIS if Redis requires auth
db: 0
# PostgreSQL backend configuration (if backend: postgres)
postgres:
host: "postgresql.default.svc.cluster.local"
port: 5432
database: "memory_mcp"
user: "postgres"
password: "" # SET THIS if using postgres backend
resources:
limits:
cpu: 200m
memory: 512Mi
requests:
cpu: 100m
memory: 256Mi

View File

@@ -0,0 +1,270 @@
# MCP Umbrella Chart - Central Configuration
# Secrets are managed in secrets.enc.yaml (SOPS-encrypted)
# Global configuration shared across all MCP servers
global:
namespace: mcp
commonLabels:
app.kubernetes.io/part-of: mcp-ecosystem
managed-by: mcp-umbrella
imagePullPolicy: IfNotPresent
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
# =============================================================================
# MCP Gateway Configuration
# =============================================================================
mcp-gateway:
enabled: true
replicaCount: 1
service:
type: LoadBalancer
port: 3000
ingress:
enabled: false
className: "nginx"
hosts:
- host: mcp.caffeinetux.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: mcp-gateway-tls
hosts:
- mcp.caffeinetux.com
gateway:
auth:
enabled: true
# API keys loaded from Secret: mcp-gateway-api-keys
existingSecret: mcp-gateway-api-keys
logLevel: "info"
timeout: 30000
servers:
n8n-mcp:
host: "n8n-mcp"
port: 3001
playwright-mcp:
host: "playwright-mcp"
port: 3002
kubernetes-mcp:
host: "kubernetes-mcp"
port: 3003
github-mcp:
host: "github-mcp"
port: 3004
postgresql-mcp:
host: "postgresql-mcp"
port: 3005
sqlite-mcp:
host: "sqlite-mcp"
port: 3006
prometheus-mcp:
host: "prometheus-mcp"
port: 3007
slack-mcp:
host: "slack-mcp"
port: 3008
s3-mcp:
host: "s3-mcp"
port: 3009
filesystem-mcp:
host: "filesystem-mcp"
port: 3010
puppeteer-mcp:
host: "puppeteer-mcp"
port: 3011
fetch-mcp:
host: "fetch-mcp"
port: 3012
memory-mcp:
host: "memory-mcp"
port: 3013
gitea-mcp:
host: "gitea-mcp"
port: 3014
autoscaling:
enabled: true
minReplicas: 1
maxReplicas: 3
targetCPUUtilizationPercentage: 80
# =============================================================================
# n8n MCP Server Configuration
# =============================================================================
n8n-mcp:
enabled: true
n8nMCP:
n8n:
url: "http://n8n.n8n.svc.cluster.local:5678"
# API key loaded from Secret: n8n-mcp-api-key
existingSecret: n8n-mcp-api-key
mode: "full"
logLevel: "info"
# =============================================================================
# Playwright MCP Server Configuration
# =============================================================================
playwright-mcp:
enabled: true
playwrightMCP:
browsers:
- chromium
- firefox
- webkit
headless: true
timeout: 30000
persistence:
enabled: true
size: 10Gi
storageClassName: nfs-client
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 200m
memory: 512Mi
# =============================================================================
# Kubernetes MCP Server Configuration
# =============================================================================
kubernetes-mcp:
enabled: true
rbac:
create: true
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps", "secrets"]
verbs: ["get", "list", "watch", "create", "update", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets", "daemonsets"]
verbs: ["get", "list", "watch", "create", "update", "delete"]
# =============================================================================
# GitHub MCP Server Configuration
# =============================================================================
github-mcp:
enabled: true
github:
# Token and owner loaded from Secret: github-mcp-token
existingSecret: github-mcp-token
# =============================================================================
# PostgreSQL MCP Server Configuration
# =============================================================================
postgresql-mcp:
enabled: false
postgresql:
host: "postgresql.default.svc.cluster.local"
port: 5432
database: "postgres"
user: "postgres"
# =============================================================================
# SQLite MCP Server Configuration
# =============================================================================
sqlite-mcp:
enabled: true
sqlite:
databasePath: "/data/sqlite.db"
persistence:
enabled: true
size: 1Gi
# =============================================================================
# Prometheus MCP Server Configuration
# =============================================================================
prometheus-mcp:
enabled: false
prometheus:
url: "http://prometheus-server.prometheus.svc.cluster.local"
# =============================================================================
# Slack MCP Server Configuration
# =============================================================================
slack-mcp:
enabled: false
# =============================================================================
# S3 MCP Server Configuration
# =============================================================================
s3-mcp:
enabled: false
s3:
region: "us-east-1"
# =============================================================================
# Filesystem MCP Server Configuration
# =============================================================================
filesystem-mcp:
enabled: true
filesystem:
rootPath: "/data"
persistence:
enabled: true
size: 5Gi
# =============================================================================
# Puppeteer MCP Server Configuration
# =============================================================================
puppeteer-mcp:
enabled: false
puppeteer:
headless: true
timeout: 30000
persistence:
enabled: true
downloadSize: 5Gi
screenshotSize: 5Gi
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
# =============================================================================
# Fetch MCP Server Configuration
# =============================================================================
fetch-mcp:
enabled: true
fetch:
userAgent: "MCP-Fetch-Server/1.0"
timeout: 30000
# =============================================================================
# Memory MCP Server Configuration
# =============================================================================
memory-mcp:
enabled: true
storage:
backend: "redis"
redis:
host: "redis.default.svc.cluster.local"
port: 6379
db: 0
resources:
limits:
cpu: 200m
memory: 512Mi
requests:
cpu: 100m
memory: 256Mi
# =============================================================================
# Gitea MCP Server Configuration
# =============================================================================
gitea-mcp:
enabled: true
gitea:
# Token, owner, and URL loaded from Secret: gitea-mcp-token
existingSecret: gitea-mcp-token