Summary
The MCPRegistry CRD currently mirrors the registry server's config.yaml structure field-by-field. Every time the registry server's configuration format evolves, the operator must update its CRD types, config generation logic, and tests — often as a breaking CRD change.
Evidence: PR #4653 required 2,993 additions / 2,458 deletions to align the CRD with a v2 config format, adding 10+ new Go types, rewriting config generation, and introducing a breaking API change.
Approach
Replace the typed config fields with a pass-through model:
configYAML — raw YAML string passed directly to the registry server as config.yaml. The operator does not parse, validate, or transform it.
volumes / volumeMounts — standard Kubernetes volume definitions (as raw JSON) for user-managed volume wiring (secrets, ConfigMaps, PVCs).
pgpassSecretRef — operator-managed pgpass mount with init container for chmod 0600 permissions (the one piece of Kubernetes plumbing users cannot express through volumes alone).
The two config paths (new decoupled vs legacy typed) are mutually exclusive. The existing typed fields are deprecated but retained for backward compatibility, allowing gradual migration.
There are increased amount of things users have to do in the new CRD types, however, all around, we believe it is a better user experience longer term. This is because there will be less breaking changes needed to the CRD every time the registry server config changes, the volumes configuration also gives users more control over where they want things mounted. The operator will still abstract complexity under the hood around the initContainer, however there are conversations around deprecated the PGPASSFILE and sticking with an environment variable for ease of use in future.
Implementation Plan
This is split into two phases:
-
Phase 1: Add new decoupled config path — add configYAML, volumes, volumeMounts, pgpassSecretRef fields alongside existing typed fields. Both paths work. No existing functionality is removed.
-
Phase 2: Remove deprecated legacy fields — after users have migrated, remove the typed fields (sources, registries, databaseConfig, authConfig, telemetryConfig) and all associated config generation code (~2,200 lines).
Sub-issues
- Phase 1: Add new decoupled config path
- Phase 2: Remove deprecated legacy fields
Summary
The MCPRegistry CRD currently mirrors the registry server's
config.yamlstructure field-by-field. Every time the registry server's configuration format evolves, the operator must update its CRD types, config generation logic, and tests — often as a breaking CRD change.Evidence: PR #4653 required 2,993 additions / 2,458 deletions to align the CRD with a v2 config format, adding 10+ new Go types, rewriting config generation, and introducing a breaking API change.
Approach
Replace the typed config fields with a pass-through model:
configYAML— raw YAML string passed directly to the registry server asconfig.yaml. The operator does not parse, validate, or transform it.volumes/volumeMounts— standard Kubernetes volume definitions (as raw JSON) for user-managed volume wiring (secrets, ConfigMaps, PVCs).pgpassSecretRef— operator-managed pgpass mount with init container forchmod 0600permissions (the one piece of Kubernetes plumbing users cannot express through volumes alone).The two config paths (new decoupled vs legacy typed) are mutually exclusive. The existing typed fields are deprecated but retained for backward compatibility, allowing gradual migration.
There are increased amount of things users have to do in the new CRD types, however, all around, we believe it is a better user experience longer term. This is because there will be less breaking changes needed to the CRD every time the registry server config changes, the volumes configuration also gives users more control over where they want things mounted. The operator will still abstract complexity under the hood around the initContainer, however there are conversations around deprecated the PGPASSFILE and sticking with an environment variable for ease of use in future.
Implementation Plan
This is split into two phases:
Phase 1: Add new decoupled config path — add
configYAML,volumes,volumeMounts,pgpassSecretReffields alongside existing typed fields. Both paths work. No existing functionality is removed.Phase 2: Remove deprecated legacy fields — after users have migrated, remove the typed fields (
sources,registries,databaseConfig,authConfig,telemetryConfig) and all associated config generation code (~2,200 lines).Sub-issues