Skip to content

Align MCPRegistry CRD with registry server v2 config format#4653

Open
rdimitrov wants to merge 8 commits intomainfrom
rdimitrov/mcpregistry-v2-crd-types
Open

Align MCPRegistry CRD with registry server v2 config format#4653
rdimitrov wants to merge 8 commits intomainfrom
rdimitrov/mcpregistry-v2-crd-types

Conversation

@rdimitrov
Copy link
Copy Markdown
Member

@rdimitrov rdimitrov commented Apr 7, 2026

Summary

The registry server (toolhive-registry-server) moved to a v2 config format that separates data sources from registry views and adds claims-based authorization. The operator's MCPRegistry CRD was still generating v1 config (flat registries[] with inline source configs), so operators deploying via the CRD got none of the v2 authorization features.

This updates the MCPRegistry CRD and config generation to produce v2-compatible config with full parity:

  • Split spec.registries into spec.sources (data source definitions) and spec.registries (lightweight views referencing sources by name)
  • Add claims support on both sources and registries via apiextensionsv1.JSON
  • Add ManagedSource, KubernetesSource (with namespace selectors), and URLSource as new source types
  • Add authz (role-based access control) and publicPaths to auth config
  • Add maxMetaSize and dynamicAuth (AWS RDS IAM) to database config
  • Add telemetryConfig with tracing (sampling) and metrics sub-configs
  • Remove PVC source type (not a supported use case)

Closes #4572

Type of change

  • New feature

Test plan

  • Unit tests (task test)
  • Linting (task lint-fix)
  • Manual testing (describe below)

Deployed updated CRDs to a Kind cluster, applied a v2 MCPRegistry resource with sources + registries + claims, ran the operator locally, and verified the generated ConfigMap produces correct v2 YAML with sources[] and registries[].

Changes

File Change
cmd/thv-operator/api/v1alpha1/mcpregistry_types.go New MCPRegistrySourceConfig, MCPRegistryViewConfig, ManagedSource, KubernetesSource, URLSource, MCPRegistryAuthzConfig, MCPRegistryRolesConfig, MCPRegistryTelemetryConfig, MCPRegistryDynamicAuthConfig; claims via apiextensionsv1.JSON; PublicPaths on auth; MaxMetaSize/DynamicAuth on database; removed PVCSource
cmd/thv-operator/api/v1alpha1/zz_generated.deepcopy.go Regenerated
cmd/thv-operator/pkg/registryapi/config/config.go v2 SourceConfig/RegistryConfig structs, claims deserialization, authz mapping, telemetry/database config mapping, URL source support, removed PVC config building
cmd/thv-operator/pkg/registryapi/config/config_test.go All tests migrated to v2 types, removed PVC tests
cmd/thv-operator/pkg/registryapi/deployment.go Iterate Spec.Sources for git auth mounts
cmd/thv-operator/pkg/registryapi/podtemplatespec.go WithRegistrySourceMounts takes []MCPRegistrySourceConfig, removed PVC volume mounting
cmd/thv-operator/pkg/registryapi/{*_test.go} All tests migrated to v2 types
cmd/thv-operator/test-integration/mcp-registry/*.go Test helpers and integration tests migrated; builder syncs source names; removed PVC test file
deploy/charts/operator-crds/** Regenerated CRD manifests
docs/operator/crd-api.md Regenerated CRD API reference docs
examples/operator/mcp-registries/*.yaml Example manifests updated to v2 format; removed PVC and multi-source PVC examples

Does this introduce a user-facing change?

Yes. This is a breaking CRD changespec.registries changes meaning from source definitions to registry views. Since this is v1alpha1 (explicitly unstable), an in-place update is acceptable. Existing MCPRegistry resources must be updated to the new format.

Migration example:

Before:

spec:
  registries:
    - name: production
      format: toolhive
      configMapRef: { name: prod-registry, key: registry.json }

After:

spec:
  sources:
    - name: production
      format: toolhive
      configMapRef: { name: prod-registry, key: registry.json }
  registries:
    - name: default
      sources: ["production"]

Special notes for reviewers

  • Claims typing: Uses apiextensionsv1.JSON for claims fields on sources and registries, and for role entries in authz config. The config generator deserializes and validates that values are string or []string before emitting map[string]any in the YAML output.
  • No auto-injection: Users must explicitly define all sources including Kubernetes discovery sources. This avoids implicit behavior that would be surprising with claims-based authorization.
  • PVC source removed: The PVC source type was removed as it is not a supported use case.
  • PR size: The diff is large but most of it is generated code (CRD manifests, deepcopy), test migrations, and example YAML updates. The core logic changes are in mcpregistry_types.go and config.go.

Generated with Claude Code

@github-actions github-actions bot added the size/XL Extra large PR: 1000+ lines changed label Apr 7, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 transformation

Alternative:

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
Copy link
Copy Markdown

codecov bot commented Apr 7, 2026

Codecov Report

❌ Patch coverage is 37.79904% with 130 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.69%. Comparing base (d04eb02) to head (d2d6430).

Files with missing lines Patch % Lines
cmd/thv-operator/pkg/registryapi/config/config.go 34.34% 111 Missing and 19 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4653      +/-   ##
==========================================
- Coverage   68.84%   68.69%   -0.15%     
==========================================
  Files         508      508              
  Lines       52604    52725     +121     
==========================================
+ Hits        36215    36222       +7     
- Misses      13587    13687     +100     
- Partials     2802     2816      +14     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@rdimitrov rdimitrov force-pushed the rdimitrov/mcpregistry-v2-crd-types branch from fee3776 to 821ccda Compare April 7, 2026 22:44
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Apr 7, 2026
rdimitrov and others added 3 commits April 8, 2026 12:09
The registry server has moved to a v2 config format that separates data
sources from registry views, adds claims-based authorization, and
supports managed and Kubernetes source types. The operator's MCPRegistry
CRD was still generating v1 config (flat registries[] with inline source
configs), meaning operators deploying via the CRD got none of the v2
authorization features.

This updates the CRD spec to use separate sources[] and registries[]
fields, adds support for claims (apiextensionsv1.JSON), authz roles,
managed sources, Kubernetes sources with namespace selectors, and public
paths on auth config. The config generator now produces v2-compatible
YAML that the registry server can consume directly.

A default Kubernetes source is auto-injected when the user defines none,
preserving backward compatibility for MCP server discovery.

Closes #4572

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Users should explicitly define all sources in their MCPRegistry spec,
including Kubernetes discovery sources. The auto-injection was adding
implicit behavior that would be surprising when combined with
claims-based authorization.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
rdimitrov and others added 5 commits April 8, 2026 12:09
Add remaining v2 config fields to achieve full parity with the registry
server configuration format:

- MaxMetaSize (*int32) on DatabaseConfig for controlling metadata size
  limits
- DynamicAuth with AWS RDS IAM support on DatabaseConfig for short-lived
  database credentials
- TelemetryConfig on MCPRegistrySpec for OpenTelemetry configuration
  with tracing (sampling rate) and metrics sub-configs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add URLSource as a new source type for fetching registry data from
HTTP/HTTPS URLs. This maps to the registry server's FileConfig with the
url and timeout fields, complementing the existing ConfigMapRef and
PVCRef file-based sources.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The RegistryBuilder's Build() method now syncs the default registry
view's source list with the actual source names from spec.sources. This
fixes integration test failures where WithRegistryName changed a source
name but the registry view still referenced the old "default" name.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PVC-based registry sources are not a supported use case. Remove the
PVCRef field, PVCSource struct, all associated config building,
pod template volume mounting, tests, examples, and documentation.
Also fix mutual exclusivity comments on remaining source types to
consistently list all alternatives including URL.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The test was asserting the config YAML contains `registryName:` which
was removed in the v2 format. Check for `sources:` instead, which is
the v2 top-level key.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rdimitrov rdimitrov force-pushed the rdimitrov/mcpregistry-v2-crd-types branch from 99e64c0 to d2d6430 Compare April 8, 2026 09:09
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Apr 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XL Extra large PR: 1000+ lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Align MCPRegistry CRD with registry server v2 config format

1 participant