-
Notifications
You must be signed in to change notification settings - Fork 147
Closed
Labels
bugSomething isn't workingSomething isn't workingkubernetesItems related to KubernetesItems related to Kubernetesoperator
Description
Type: Missing feature / regression
Introduced: November 10, 2025
Description
Volumes defined in spec.volumes are accepted by the MCPServer CRD but are never:
- Added to runconfig.json
- Created in the pod spec
- Mounted in the container
This makes it impossible to deploy applications that need writable filesystem access (databases, caches, logs) because the operator enforces readOnlyRootFilesystem: true.
Root Cause
File: cmd/thv-operator/controllers/mcpserver_runconfig.go:87
envVars := convertEnvVarsFromMCPServer(m.Spec.Env)
volumes := convertVolumesFromMCPServer(m.Spec.Volumes) // ← Converted but never used!The volumes are read and converted to the builder format, but they're never:
- Added to the runconfig.json (not in the RunConfigBuilder options)
- Applied to the pod spec when creating workloads
Steps to Reproduce
- Create an MCPServer with volumes:
apiVersion: toolhive.stacklok.dev/v1alpha1
kind: MCPServer
metadata:
name: test-server
spec:
image: my-image:latest
volumes:
- name: data
hostPath: "" # emptyDir
mountPath: /data
readOnly: false
env:
- name: DATA_PATH
value: /data- Deploy and check the runconfig:
kubectl get configmap test-server-runconfig -o jsonpath='{.data.runconfig\.json}' | jq '.volumes'
# Output: null- Check the pod spec:
kubectl get pod test-server-0 -o jsonpath='{.spec.volumes[*].name}'
# Output: Only "kube-api-access-*" (no user-defined volumes)
kubectl get pod test-server-0 -o jsonpath='{.spec.containers[0].volumeMounts}' | jq
# Output: Only serviceaccount mount (no user-defined mounts)- Application fails trying to write:
kubectl logs test-server-0
# Error: unable to open database file
# Or: Read-only file systemExpected Behavior
Volumes defined in spec.volumes should be:
- Included in runconfig.json OR applied directly to pod spec
- Created as Kubernetes volumes in the pod
- Mounted in the container at the specified mount paths
- Writable (when
readOnly: false)
Actual Behavior
- Volumes are accepted in MCPServer CRD validation ✓
- Volumes appear in
spec.volumes✓ - Volumes are NOT in runconfig.json ✗
- Volumes are NOT in pod spec ✗
- Applications crash trying to write to read-only filesystem ✗
Impact
- Blocks critical deployments: Applications needing disk writes cannot be deployed
- No workaround available: Cannot be fixed from MCPServer configuration
- Affects MCP Optimizer: Cannot deploy the official MCP Optimizer in Kubernetes
- Security conflict:
readOnlyRootFilesystem: true(good security) + no volume mounts (bug) = impossible to write files
Evidence from MCP Optimizer Deployment
Security Context Applied by Operator:
{
"allowPrivilegeEscalation": false,
"privileged": false,
"readOnlyRootFilesystem": true, // ← Makes entire filesystem read-only
"runAsNonRoot": true,
"runAsUser": 1000
}MCPServer Configuration:
spec:
volumes:
- name: data
hostPath: ""
mountPath: /data
readOnly: false
env:
- name: DB_URL
value: "sqlite:///data/mcp_optimizer.db"Result:
- Volume not mounted
/datadirectory doesn't exist or is read-only- SQLite error:
unable to open database file - Pod in CrashLoopBackOff
What Used to Work (Before Nov 10, 2025)
The original configuration in helm/mcp-optimizer/values.yaml (commit 48921bc):
spec:
podTemplateSpec:
spec:
volumes:
- name: data
emptyDir: {}
- name: tmp
emptyDir: {}
containers:
- name: mcp
volumeMounts:
- name: data
mountPath: /data
- name: tmp
mountPath: /tmp
env:
- name: DB_URL
value: "sqlite:///data/mcp_optimizer.db"This worked because the operator:
- Read
podTemplateSpec - Converted it to CLI flags for
thv-proxyrunner - Proxyrunner created pods with proper volumes and env vars
Environment
- ToolHive Operator Version: 0.2.22
- ToolHive Operator CRDs: 0.0.34
- Kubernetes: Rancher Desktop (Docker-based)
- Test Application: MCP Optimizer v0.1.1
- Test Date: November 17, 2025
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingkubernetesItems related to KubernetesItems related to Kubernetesoperator