Skip to content

HorizontalPodAutoscaler cannot scale MCPServer deployments: replicas reset to 1 on every reconcile #145

Open

Description

@gaarutyunov

Description

A HorizontalPodAutoscaler targeting the Deployment of an MCPServer gets overridden by the kmcp controller. As soon as the HPA scales the Deployment up, the controller sets spec.replicas back to the MCPServer value, which is 1 unless set.

Cause

  • The MCPServer CRD sets +kubebuilder:default=1 on spec.deployment.replicas, so the field is always filled in, even when the manifest leaves it out.
  • upsertOutput in pkg/controller/mcpserver_controller.go replaces the whole Deployment with Update, replicas included.
  • The controller watches its Deployments (Owns(&appsv1.Deployment{}) with ResourceVersionChangedPredicate). Each HPA scale event therefore triggers a reconcile that undoes it right away.

The result is that the only way to run more than one pod is a fixed replicas in the MCPServer.

kagent already handles this for Agent Deployments. mutateDeployment in kagent's go/core/internal/controller/translator/mutate.go only sets replicas when the Agent specifies them, "so not to override HPA settings".

Steps to reproduce

  1. Create an MCPServer without spec.deployment.replicas.
  2. Create an autoscaling/v2 HorizontalPodAutoscaler with scaleTargetRef pointing at the generated Deployment, and minReplicas: 2.
  3. Watch the Deployment: the HPA scales it to 2, and the controller immediately sets it back to 1. This repeats in a loop.

Expected

When spec.deployment.replicas is not set, kmcp creates the Deployment with the Kubernetes default of 1 replica, then leaves spec.replicas alone so an HPA can manage it.

Environment

kmcp 0.3.0, shipped with kagent 0.10.6. The same code is on main and in v0.4.0.

Proposed fix: #144

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions