Summary
mcp-proxy exists in the codebase and the operator supports injecting it as an optional sidecar for MCPServer workloads, but the live cluster can report gatewayReady=true even when the generated Deployment has no proxy/gateway sidecar container at all.
This creates two problems:
- runtime status is misleading
- analytics never get emitted from the proxy path because the proxy is not actually running
What I observed in cluster
Date checked: 2026-04-29
1. The codebase supports the sidecar
Relevant code paths:
services/mcp-proxy/main.go
api/v1alpha1/mcpserver_types.go (spec.gateway, spec.analytics)
internal/operator/controller.go (gatewayEnabled, buildGatewayContainer, sidecar appended during Deployment rendering)
k8s/14-mcp-proxy-sidecar.yaml example manifest
2. The sentinel analytics stack is running, but no analytics are landing
In mcp-sentinel:
clickhouse-0 is healthy
- table
mcp.events exists
SELECT count() FROM mcp.events returned 0
mcp-sentinel-ingest logs show only readiness/liveness probes, not event ingestion
3. The live MCPServer status says gateway is ready
kubectl get mcpservers -A showed:
NAMESPACE NAME PHASE POLICY GATEWAY READY AGE
mcp-servers go-example-mcp Ready true true true 2d18h
kubectl get mcpserver -n mcp-servers go-example-mcp -o yaml shows:
status.gatewayReady: true
status.policyReady: true
phase: Ready
4. But the live MCPServer spec does not currently include gateway config
The same MCPServer object has no spec.gateway block at all.
5. The generated Deployment has no sidecar
kubectl get deploy -n mcp-servers go-example-mcp -o yaml shows only one container:
There is no mcp-proxy or mcp-gateway container in the pod template.
6. The live pods confirm only one container
kubectl get pods -A -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,CONTAINERS:.spec.containers[*].name' | rg 'mcp-servers|mcp-proxy|mcp-gateway|go-example'
returned pods in mcp-servers with only:
7. Operator logs report successful reconciliation anyway
Operator deployment:
mcp-runtime/mcp-runtime-operator-controller-manager
The operator logs repeatedly show successful reconcile/update for go-example-mcp, but no indication that a gateway sidecar was rendered or omitted due to configuration.
Why this is a bug
The current runtime state is internally inconsistent:
gatewayReady=true
policyReady=true
- no
spec.gateway
- no gateway sidecar in the rendered Deployment
- no proxy-generated analytics in sentinel
At minimum, readiness/status is incorrect.
Potentially, reconciliation is also failing to clear gateway-related status after spec.gateway is removed or changed.
Expected behavior
One of these should be true:
- If
spec.gateway.enabled is not set, then:
- no gateway sidecar should be rendered
status.gatewayReady should be false
status.policyReady should reflect the disabled state appropriately
- any gateway-related conditions/messages should make it clear the gateway is disabled, not ready
- If
status.gatewayReady=true, then:
spec.gateway.enabled should be present
- the rendered Deployment should include the proxy sidecar container
- the live pod should contain both app container and gateway/proxy container
Suspected areas to inspect
internal/operator/controller.go
- readiness/status computation for
GatewayReady and PolicyReady
- reconciliation behavior when gateway was previously enabled and is later removed
- any metadata/CRD defaulting or generation paths that may set status independently of current
spec.gateway
- any code path where gateway status is inferred from prior conditions rather than the current rendered pod template
Repro direction
- Create or update an
MCPServer
- Ensure gateway was enabled at some point, or transition config through gateway on/off states
- Observe whether:
status.gatewayReady stays true
- the Deployment no longer has the sidecar
- pods no longer contain the sidecar
Acceptance criteria
gatewayReady and policyReady accurately reflect current spec + rendered Deployment state
- removing or disabling gateway clears/updates gateway-related status correctly
- if gateway is enabled, the sidecar is actually present in the pod template and live pods
- an e2e or controller test covers the mismatch case so status cannot say ready when no sidecar is deployed
Summary
mcp-proxyexists in the codebase and the operator supports injecting it as an optional sidecar forMCPServerworkloads, but the live cluster can reportgatewayReady=trueeven when the generated Deployment has no proxy/gateway sidecar container at all.This creates two problems:
What I observed in cluster
Date checked:
2026-04-291. The codebase supports the sidecar
Relevant code paths:
services/mcp-proxy/main.goapi/v1alpha1/mcpserver_types.go(spec.gateway,spec.analytics)internal/operator/controller.go(gatewayEnabled,buildGatewayContainer, sidecar appended during Deployment rendering)k8s/14-mcp-proxy-sidecar.yamlexample manifest2. The sentinel analytics stack is running, but no analytics are landing
In
mcp-sentinel:clickhouse-0is healthymcp.eventsexistsSELECT count() FROM mcp.eventsreturned0mcp-sentinel-ingestlogs show only readiness/liveness probes, not event ingestion3. The live MCPServer status says gateway is ready
kubectl get mcpservers -Ashowed:kubectl get mcpserver -n mcp-servers go-example-mcp -o yamlshows:status.gatewayReady: truestatus.policyReady: truephase: Ready4. But the live MCPServer spec does not currently include gateway config
The same
MCPServerobject has nospec.gatewayblock at all.5. The generated Deployment has no sidecar
kubectl get deploy -n mcp-servers go-example-mcp -o yamlshows only one container:go-example-mcpThere is no
mcp-proxyormcp-gatewaycontainer in the pod template.6. The live pods confirm only one container
kubectl get pods -A -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,CONTAINERS:.spec.containers[*].name' | rg 'mcp-servers|mcp-proxy|mcp-gateway|go-example'returned pods in
mcp-serverswith only:go-example-mcp7. Operator logs report successful reconciliation anyway
Operator deployment:
mcp-runtime/mcp-runtime-operator-controller-managerThe operator logs repeatedly show successful reconcile/update for
go-example-mcp, but no indication that a gateway sidecar was rendered or omitted due to configuration.Why this is a bug
The current runtime state is internally inconsistent:
gatewayReady=truepolicyReady=truespec.gatewayAt minimum, readiness/status is incorrect.
Potentially, reconciliation is also failing to clear gateway-related status after
spec.gatewayis removed or changed.Expected behavior
One of these should be true:
spec.gateway.enabledis not set, then:status.gatewayReadyshould befalsestatus.policyReadyshould reflect the disabled state appropriatelystatus.gatewayReady=true, then:spec.gateway.enabledshould be presentSuspected areas to inspect
internal/operator/controller.goGatewayReadyandPolicyReadyspec.gatewayRepro direction
MCPServerstatus.gatewayReadystaystrueAcceptance criteria
gatewayReadyandpolicyReadyaccurately reflect current spec + rendered Deployment state