Complete Architecture
flowchart TB
subgraph CLIENTS["External Clients"]
direction LR
OC["π₯οΈ OpenShift Console\nLightspeed Plugin"]
N8N_EXT["βοΈ n8n :443\nWorkflows"]
MCPI["π MCP Inspector"]
CURL["π‘ curl / SDK"]
end
subgraph OLS_NS["Namespace: openshift-lightspeed"]
OLS["π€ lightspeed-app-server\nOLS v1.0.10\nfeatureGate: MCP"]
PROXY["π tool-choice-proxy :4001\nβββββββββββββββββ\nβ’ model remap llamaβdeepseek\nβ’ tool_choice injection\nβ’ SSE bridge\nβ’ budget fail β fallback qwen-cpu"]
LITELLM["π LiteLLM :4000\nβββββββββββββββββ\nmodels: deepseek, llama-scout,\nqwen-cpu β PostgreSQL"]
N8N_INT["π n8n :5678\n17 workflows + Mailpit"]
subgraph MCP_SERVERS["MCP Servers"]
direction LR
OCP_MCP["π§ openshift-mcp-server :8080\nQuarkus Β· 19 tools\nocp_* prefix"]
K8S_MCP["π§ kubernetes-mcp-server :8085\nGo Β· 19 tools\nk8s_* prefix"]
end
end
subgraph MCP_NS["Namespace: mcp-system"]
GW["π MCP Gateway\nKuadrant / Envoy\nβββββββββββββββββ\n38 federated tools on /mcp\nocp_* β openshift-mcp-server\nk8s_* β kubernetes-mcp-server"]
end
subgraph MODELS["LLM Models"]
direction LR
MAAS["βοΈ MaaS LiteLLM\ndeepseek-r1-distill-qwen-14b\nEXTERNAL"]
VLLM["π₯οΈ vLLM CPU Β· KServe\nQwen2.5-7B-Instruct :8080\nRHOAI + Serverless\n~170s/response"]
end
K8S_API["β‘ Kubernetes API Server"]
OC -->|"question"| OLS
OLS -->|"OpenAI API"| PROXY
OLS -->|"MCP Protocol\n(direct)"| OCP_MCP
OLS -->|"MCP Protocol\n(direct)"| K8S_MCP
PROXY --> LITELLM
N8N_EXT --> N8N_INT
N8N_INT --> LITELLM
LITELLM -->|"budget β
"| MAAS
LITELLM -->|"budget β\nfallback"| VLLM
MCPI --> GW
CURL --> GW
GW --> OCP_MCP
GW --> K8S_MCP
OCP_MCP -->|"cluster-admin"| K8S_API
K8S_MCP -->|"cluster-admin"| K8S_API
sequenceDiagram
actor User as π€ User
participant Console as OpenShift Console
Lightspeed Plugin
participant OLS as OLS v1.0.10
lightspeed-app-server
participant Proxy as tool-choice-proxy
:4001
participant LiteLLM as LiteLLM
:4000
participant MaaS as MaaS
deepseek-r1
participant vLLM as vLLM CPU
qwen-2.5-7b
participant MCP as MCP Server
openshift / kubernetes
User->>Console: Ask question
Console->>OLS: Forward query
OLS->>MCP: Discover tools (MCP protocol)
MCP-->>OLS: Available tools list
OLS->>Proxy: chat/completions + tools
Note over Proxy: Remap model:
llama-scout β deepseek-r1
Inject tool_choice
Set stream=false
Proxy->>LiteLLM: Modified request
LiteLLM->>MaaS: Forward to model
alt Budget OK
MaaS-->>LiteLLM: tool_call response
else Budget Exceeded
MaaS-->>LiteLLM: 400 budget error
LiteLLM-->>Proxy: Error response
Note over Proxy: Detect budget error
Retry with fallback model
Proxy->>LiteLLM: Retry β qwen-2.5-7b-cpu
LiteLLM->>vLLM: Forward to CPU model
vLLM-->>LiteLLM: tool_call response (~170s)
end
LiteLLM-->>Proxy: tool_call JSON
Note over Proxy: Convert to SSE stream
for OLS compatibility
Proxy-->>OLS: SSE stream with tool_call
OLS->>MCP: Execute tool (e.g. checkClusterHealth)
MCP-->>OLS: Tool result
OLS->>Proxy: chat/completions + tool result
Proxy->>LiteLLM: Forward
LiteLLM-->>Proxy: Final text response
Proxy-->>OLS: SSE stream
OLS-->>Console: Formatted answer
Console-->>User: Display response
Component Reference
flowchart LR
subgraph CORE["Core Components"]
direction TB
A["π§ openshift-mcp-server\nQuarkus Β· 19 tools Β· ocp_*"]
B["π§ kubernetes-mcp-server\nGo Β· 19 tools Β· k8s_*"]
end
subgraph PROXY_LAYER["Proxy & Model Layer"]
direction TB
C["π tool-choice-proxy\nStreaming fix Β· tool_choice\nModel remap Β· CPU fallback"]
D["π LiteLLM\nMulti-model proxy\nPostgreSQL Β· API keys"]
end
subgraph MODELS_REF["Models"]
direction TB
E["βοΈ MaaS deepseek-r1\nPrimary Β· External"]
F["π₯οΈ vLLM qwen-2.5-7b\nFallback Β· Local CPU"]
end
subgraph EXTERNAL["External Access"]
direction TB
G["π MCP Gateway\nKuadrant/Envoy\n38 federated tools"]
end
A --> PROXY_LAYER
B --> PROXY_LAYER
C --> D
D --> E
D --> F
G --> CORE
| Component | Purpose | Required? |
|---|
| tool-choice-proxy | Fixes OLS bugs: streaming, tool_choice, model remap, CPU fallback | Yes (OLS v1.0.10 bug) |
| MCP Gateway | Unified endpoint for external clients (n8n, curl, SDK) | Yes, for external access |
| LiteLLM | Multi-model proxy with PostgreSQL, API keys, rate limiting | Yes, model management |
| vLLM CPU | Local fallback model when MaaS is unavailable | Yes, resilience |
| openshift-mcp-server | Quarkus tools for OpenShift (ocp_*) | Yes, core |
| kubernetes-mcp-server | Go tools for Kubernetes (k8s_*) | Yes, core |
Active model: deepseek-r1-distill-qwen-14b via MaaS (remapped by proxy from llama-scout-17b)
Fallback model: qwen-2.5-7b-cpu local via OpenShift AI (vLLM CPU, ~170s/response)
Access Channels
| Channel | Tool calling | URL |
|---|
| Console Lightspeed plugin | Yes | https://console-openshift-console.apps.cluster-6tx4w.6tx4w.sandbox5380.opentlc.com |
| n8n workflows (LiteLLM) | Yes | https://n8n.apps.cluster-6tx4w.6tx4w.sandbox5380.opentlc.com |
| MCP Gateway (38 tools) | Yes | https://mcp-gateway.apps.cluster-6tx4w.6tx4w.sandbox5380.opentlc.com/mcp |
| RHOAI Dashboard | Yes | https://rhods-dashboard-redhat-ods-applications.apps.cluster-6tx4w.6tx4w.sandbox5380.opentlc.com |
MCP Servers
- Internal URL:
http://openshift-mcp-server.openshift-lightspeed.svc.cluster.local:8080/mcp - Permissions:
cluster-admin
- Internal URL:
http://kubernetes-mcp-server.openshift-lightspeed.svc.cluster.local:8085/mcp - Permissions:
cluster-admin
- Internal URL:
http://mcp-gateway.mcp-system.svc.cluster.local:8080/mcp - External URL:
https://mcp-gateway.apps.cluster-6tx4w.6tx4w.sandbox5380.opentlc.com/mcp - Aggregates both servers with
ocp_ and k8s_ prefixes
pie title 38 MCP Tools Distribution
"k8s Read (13)" : 13
"k8s Write (6)" : 6
"ocp Observability (9)" : 9
"ocp Provisioning (5)" : 5
"ocp Benchmarks (5)" : 5
kubernetes-mcp-server β Read Operations
| Tool | Description |
|---|
pods_list | List all pods in the cluster (all namespaces) |
pods_list_in_namespace | List pods in a specific namespace |
pods_get | Get pod details by name |
pods_log | Get pod logs (with tail and container) |
pods_top | CPU/memory usage of pods (metrics-server) |
nodes_top | CPU/memory usage of nodes |
nodes_log | Logs from a node (kubelet, kube-proxy, journals) |
nodes_stats_summary | Detailed node statistics via kubelet Summary API |
events_list | K8s events (warnings, errors, state changes) |
namespaces_list | List all namespaces |
projects_list | List all OpenShift Projects |
resources_list | List resources by type (deployments, services, PVCs, CRDs, etc.) |
resources_get | Get a specific resource by apiVersion/kind/name |
kubernetes-mcp-server β Write Operations
| Tool | Description |
|---|
resources_create_or_update | Create or update a resource with YAML |
resources_delete | Delete a resource by apiVersion/kind/name |
resources_scale | Scale replicas of a Deployment/StatefulSet/ReplicaSet |
pods_delete | Delete a pod (force restart) |
pods_exec | Execute a command inside a pod |
pods_run | Create an ephemeral pod with an image |
openshift-mcp-server β Observability
| Tool | Description |
|---|
checkClusterHealth | Overall cluster status (nodes, pods, control plane) |
checkNodeConditions | Node conditions (disk/memory/PID pressure, NotReady) |
detectResourceIssues | Detect pods/nodes with high CPU/memory or excessive restarts |
getPerformanceMetrics | Performance metrics by namespace (kubectl top) |
monitorDeployments | Rollout status and replicas of deployments |
analyzePodDisruptions | Analyze disruptions: evictions, OOM kills, restarts |
checkKubeletStatus | Kubelet status and error logs on nodes |
checkCrioStatus | CRI-O runtime status and recent logs |
analyzeJournalctlPodErrors | Analyze journalctl logs for pod and system errors |
openshift-mcp-server β Provisioning
| Tool | Description |
|---|
createDeployment | Create a Deployment with image, replicas, resources, ports |
createService | Create a Service (ClusterIP/NodePort/LoadBalancer) |
createHpa | Create HorizontalPodAutoscaler with CPU/memory targets |
createNetworkPolicy | Create NetworkPolicy (deny-all, allow-same-namespace, custom) |
deployDatabase | Deploy ephemeral DB (postgresql, mysql, mongodb, redis) |
openshift-mcp-server β Benchmarks
| Tool | Description |
|---|
runCpuStressTest | CPU/memory stress test with stress-ng |
runStorageBenchmark | Storage benchmark with FIO |
runNetworkTest | Network test with iperf3 (throughput, latency, packet loss) |
runDatabaseBenchmark | DB benchmark with pgbench/sysbench |
runKubeBurner | Cluster density test with kube-burner |
n8n Workflow Pipeline
flowchart LR
A["π Manual\nTrigger"] --> B["βοΈ Set\nParameters"]
B --> C["π§ MCP\nTool Call"]
C --> D["π€ AI Analysis\nvia LiteLLM"]
D --> E["π§ Email Report\nvia Mailpit"]
style A fill:#2d2d2d,stroke:#CC0000,color:#e0e0e0
style B fill:#2d2d2d,stroke:#CC0000,color:#e0e0e0
style C fill:#2d2d2d,stroke:#CC0000,color:#e0e0e0
style D fill:#2d2d2d,stroke:#CC0000,color:#e0e0e0
style E fill:#2d2d2d,stroke:#CC0000,color:#e0e0e0
| # | Workflow | MCP Tool | Server |
|---|
| 1 | Pod Status (Agent) | pods_list_in_namespace | kubernetes-mcp |
| 2 | Pod Status (Granite) | pods_list_in_namespace | kubernetes-mcp |
| 3 | Deployment Rollout Status | monitorDeployments | openshift-mcp |
| 4 | Resource Quota Monitor | resources_list | kubernetes-mcp |
| 5 | Helm Releases Audit | helm_list | kubernetes-mcp |
| 6 | Route TLS Expiry | resources_list (routes) | kubernetes-mcp |
| 7 | Event Anomaly Detector | events_list | kubernetes-mcp |
| 8 | Cluster Test Suite | Multi-tool (7 tools) | both |
| 9 | Cluster Revert | resources_delete | kubernetes-mcp |
| 10 | Health Dashboard | Multi-tool (4 tools) | both |
| 11 | Resource Provisioner | createDeployment + deployDatabase | openshift-mcp |
| 12 | Node Capacity Monitor | nodes_top | kubernetes-mcp |
| 13 | Pod Resource Usage (Top) | pods_top | kubernetes-mcp |
| 14 | Namespace Inventory | projects_list | kubernetes-mcp |
| 15 | PVC Storage Monitor | resources_list (PVCs) | kubernetes-mcp |
| 16 | Operator Health Check | resources_list (Subscriptions) | kubernetes-mcp |
| 17 | MCP Gateway Status | Multi-tool (3 tools) | kubernetes-mcp |
Testing with MCP Gateway (curl)
# 1. Initialize session
SESSION=$(curl -sk -X POST \
https://mcp-gateway.apps.cluster-6tx4w.6tx4w.sandbox5380.opentlc.com/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' \
-D - 2>/dev/null | grep -i mcp-session-id | tr -d '\r' | awk -F': ' '{print $2}')
# 2. Send initialized notification
curl -sk -X POST \
https://mcp-gateway.apps.cluster-6tx4w.6tx4w.sandbox5380.opentlc.com/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SESSION" \
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}'
# 3. List all 38 federated tools
curl -sk -X POST \
https://mcp-gateway.apps.cluster-6tx4w.6tx4w.sandbox5380.opentlc.com/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SESSION" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
# 4. Call a tool (e.g. list pods in openshift-lightspeed)
curl -sk -X POST \
https://mcp-gateway.apps.cluster-6tx4w.6tx4w.sandbox5380.opentlc.com/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SESSION" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"k8s_pods_list_in_namespace","arguments":{"namespace":"openshift-lightspeed"}}}'