Consolidate MCPRegistry status to match MCPServer pattern#4643
Consolidate MCPRegistry status to match MCPServer pattern#4643ChrisJBurns wants to merge 1 commit intomainfrom
Conversation
MCPRegistry had an over-engineered three-phase status model with separate SyncStatus and APIStatus sub-objects, a DeriveOverallPhase() method, and a StatusCollector batching pattern. With sync operations moved to the registry server itself, only deployment readiness remains as a status source, making this complexity unnecessary. Flatten MCPRegistryStatus to the standard Kubernetes workload pattern used by MCPServer: Phase + Ready condition + ReadyReplicas + URL. This enables kubectl wait --for=condition=Ready and consistent tooling across all ToolHive workloads. Closes #4251 Closes #4269 Closes #4270 Closes #4510 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Large PR Detected
This PR exceeds 1000 lines of changes and requires justification before it can be reviewed.
How to unblock this PR:
Add a section to your PR description with the following format:
## Large PR Justification
[Explain why this PR must be large, such as:]
- Generated code that cannot be split
- Large refactoring that must be atomic
- Multiple related changes that would break if separated
- Migration or data transformationAlternative:
Consider splitting this PR into smaller, focused changes (< 1000 lines each) for easier review and reduced risk.
See our Contributing Guidelines for more details.
This review will be automatically dismissed once you add the justification section.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #4643 +/- ##
==========================================
- Coverage 68.89% 68.82% -0.07%
==========================================
Files 505 502 -3
Lines 52425 52329 -96
==========================================
- Hits 36118 36016 -102
- Misses 13514 13527 +13
+ Partials 2793 2786 -7 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@claude Please review this using the agents |
|
Claude finished @ChrisJBurns's task in 3m 15s —— View job PR Review: Consolidate MCPRegistry status to match MCPServer pattern
OverviewThe refactoring goal is sound and the overall design is correct. The Issues to Fix1. Stale When a registry transitions from // In the not-ready branch:
latest.Status.Phase = mcpv1alpha1.MCPRegistryPhasePending
latest.Status.URL = "" // add this
// In the error branch:
latest.Status.Phase = mcpv1alpha1.MCPRegistryPhaseFailed
latest.Status.URL = "" // add this2. Each call makes a live The fix is to return the readiness result from func (r *MCPRegistryReconciler) updateRegistryStatus(...) (bool, error) { // return isReady
...
isReady := r.registryAPIManager.IsAPIReady(ctx, mcpRegistry)
...
return isReady, r.Status().Update(ctx, latest)
}3. Redundant
4. Status update failure silently ignored on valid PodTemplateSpec path The invalid-spec path returns 5. Use The constant endpoint := fmt.Sprintf("http://%s.%s:%d",
mcpRegistry.GetAPIResourceName(), mcpRegistry.Namespace, registryapi.RegistryAPIPort)Suggestions (non-blocking)6. Missing tests for Codecov reports 7. Duplicate condition reason values These values are identical to 8. Unconditional The status is always written even when nothing changed. This causes a minor reconcile-loop amplification (triggers a new watch event → re-enqueues). This is pre-existing debt shared with the MCPServer controller, so not a regression — worth a follow-up issue. 9. Large PR justification section needed The automated review bot ( ## Large PR Justification
- Deletes the entire `pkg/mcpregistrystatus/` package (7 files, ~1100 lines) atomically — splitting would leave the codebase in an inconsistent state between old and new status models
- CRD and deepcopy files are generated and cannot be partially splitKubernetes Operator Pattern VerificationThe kubernetes-expert agent confirmed:
|
Summary
MCPRegistry had an over-engineered three-phase status model with separate
SyncStatusandAPIStatussub-objects, aDeriveOverallPhase()method, and aStatusCollectorbatching pattern. With sync operations moved to the registry server itself, only deployment readiness remains as a status source — making this complexity unnecessary and coupling the operator to internal registry server state.This flattens
MCPRegistryStatusto the standard Kubernetes workload pattern used by MCPServer:Phase+Readycondition +ReadyReplicas+URL. This enableskubectl wait --for=condition=Readyand consistent tooling across all ToolHive workloads.Closes #4251
Closes #4269
Closes #4270
Closes #4510
Type of change
Test plan
task test)task lint-fix)Changes
api/v1alpha1/mcpregistry_types.goMCPRegistryStatustoPhase/Message/URL/ReadyReplicas/Conditions/ObservedGeneration. RemoveSyncStatus,APIStatus,StorageReference,SyncPhase,APIPhasetypes. SimplifyMCPRegistryPhasetoPending/Running/Failed/Terminating. Update printer columns to match MCPServer.controllers/mcpregistry_controller.goStatusManager/StatusDeriver. AddupdateRegistryStatus()with refetch-before-update. AddsetRegistryReadyCondition()using sharedConditionTypeReady. SetObservedGenerationon conditions.pkg/registryapi/types.goErrortype from deletedmcpregistrystatuspackage. AddGetReadyReplicas()toManagerinterface.pkg/registryapi/manager.goErrorreferences, replaceConditionAPIReadywithConditionTypeReady, addGetReadyReplicasimplementation.pkg/mcpregistrystatus/pkg/validation/image_validation.goMCPRegistryPhaseReady→MCPRegistryPhaseRunningtest-integration/mcp-registry/DESIGN.mdDoes this introduce a user-facing change?
Yes —
MCPRegistrystatus is simplified:.status.phasevalues change:Readyis nowRunning,Syncingis removed.status.syncStatusand.status.apiStatusfields are removed.status.urland.status.readyReplicaskubectl get mcpregistriescolumns change fromPhase/Sync/API/Servers/Last Sync/AgetoStatus/Ready/Replicas/URL/Agekubectl wait --for=condition=Readynow worksThis is a breaking API change to
v1alpha1which carries no stability guarantee.Special notes for reviewers
v1alpha1has no stability guarantee, no conversion webhook needed. Orphaned etcd fields will be overwritten on next reconciliation.Stoppedphase intentionally omitted — MCPServer has it for scale-to-zero but MCPRegistry has noreplicasspec field.TestMCPRemoteProxyStatusProgressionhas a data race unrelated to this PR. The vmcptask genmockgen failures are a Go version mismatch (go1.24mockgen vsgo1.26runtime) also pre-existing.Generated with Claude Code