Skip to content

MCPServer can report gateway ready while mcp-proxy sidecar is not present in the live Deployment #94

@Agent-Hellboy

Description

@Agent-Hellboy

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:

  • go-example-mcp

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:

  • go-example-mcp

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:

  1. 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
  1. 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

  1. Create or update an MCPServer
  2. Ensure gateway was enabled at some point, or transition config through gateway on/off states
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority:highImportant; should land in current cycleservice-mcp-proxyservices/mcp-proxy — MCP gateway / policy enforcement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions