diff --git a/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go b/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go
index e1b68d5072..833effc6ad 100644
--- a/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go
+++ b/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go
@@ -9,12 +9,6 @@ import (
// VirtualMCPServerSpec defines the desired state of VirtualMCPServer
type VirtualMCPServerSpec struct {
- // GroupRef references an existing MCPGroup that defines backend workloads
- // The referenced MCPGroup must exist in the same namespace
- // TODO(jerm-dro): migrate to the Config field.
- // +kubebuilder:validation:Required
- GroupRef GroupRef `json:"groupRef"`
-
// IncomingAuth configures authentication for clients connecting to the Virtual MCP server
// Must be explicitly set - use "anonymous" type when no authentication is required
// TODO(jerm-dro): migrate to the Config field.
@@ -85,13 +79,6 @@ type VirtualMCPServerSpec struct {
Config config.Config `json:"config,omitempty"`
}
-// GroupRef references an MCPGroup resource
-type GroupRef struct {
- // Name is the name of the MCPGroup resource in the same namespace
- // +kubebuilder:validation:Required
- Name string `json:"name"`
-}
-
// IncomingAuthConfig configures authentication for clients connecting to the Virtual MCP server
type IncomingAuthConfig struct {
// Type defines the authentication type: anonymous or oidc
diff --git a/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types_test.go b/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types_test.go
index b662908f1d..52d2d1f7b0 100644
--- a/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types_test.go
+++ b/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types_test.go
@@ -5,6 +5,8 @@ import (
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+ "github.com/stacklok/toolhive/pkg/vmcp/config"
)
func TestVirtualMCPServerPhaseTransitions(t *testing.T) {
@@ -138,9 +140,7 @@ func TestVirtualMCPServerDefaultValues(t *testing.T) {
Namespace: "default",
},
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{
- Name: "test-group",
- },
+ Config: config.Config{Group: "test-group"},
OutgoingAuth: &OutgoingAuthConfig{
Source: "", // Should default to "discovered"
},
@@ -166,9 +166,7 @@ func TestVirtualMCPServerNamespaceIsolation(t *testing.T) {
Namespace: "team-a",
},
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{
- Name: "backend-group", // Must be in team-a namespace
- },
+ Config: config.Config{Group: "backend-group"}, // Must be in team-a namespace
},
}
@@ -179,9 +177,7 @@ func TestVirtualMCPServerNamespaceIsolation(t *testing.T) {
Namespace: "team-b",
},
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{
- Name: "backend-group", // Different group in team-b namespace
- },
+ Config: config.Config{Group: "backend-group"}, // Different group in team-b namespace
},
}
@@ -190,9 +186,9 @@ func TestVirtualMCPServerNamespaceIsolation(t *testing.T) {
assert.Equal(t, "vmcp", vmcpTeamB.Name)
assert.NotEqual(t, vmcpTeamA.Namespace, vmcpTeamB.Namespace)
- // GroupRef names can be the same but refer to different groups in different namespaces
- assert.Equal(t, "backend-group", vmcpTeamA.Spec.GroupRef.Name)
- assert.Equal(t, "backend-group", vmcpTeamB.Spec.GroupRef.Name)
+ // Group names can be the same but refer to different groups in different namespaces
+ assert.Equal(t, "backend-group", vmcpTeamA.Spec.Config.Group)
+ assert.Equal(t, "backend-group", vmcpTeamB.Spec.Config.Group)
}
func TestConflictResolutionStrategies(t *testing.T) {
@@ -234,7 +230,7 @@ func TestConflictResolutionStrategies(t *testing.T) {
vmcp := &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
Aggregation: &AggregationConfig{
ConflictResolution: tt.strategy,
ConflictResolutionConfig: tt.config,
@@ -287,7 +283,7 @@ func TestBackendAuthConfigTypes(t *testing.T) {
vmcp := &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
OutgoingAuth: &OutgoingAuthConfig{
Backends: map[string]BackendAuthConfig{
"test-backend": tt.authConfig,
@@ -352,7 +348,7 @@ func TestCompositeToolStepDependencies(t *testing.T) {
vmcp := &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-workflow",
diff --git a/cmd/thv-operator/api/v1alpha1/virtualmcpserver_webhook.go b/cmd/thv-operator/api/v1alpha1/virtualmcpserver_webhook.go
index 8b1cf4b8af..b09f78f424 100644
--- a/cmd/thv-operator/api/v1alpha1/virtualmcpserver_webhook.go
+++ b/cmd/thv-operator/api/v1alpha1/virtualmcpserver_webhook.go
@@ -41,9 +41,9 @@ func (*VirtualMCPServer) ValidateDelete(_ context.Context, _ runtime.Object) (ad
// Validate performs validation for VirtualMCPServer
// This method can be called by the controller during reconciliation or by the webhook
func (r *VirtualMCPServer) Validate() error {
- // Validate GroupRef is set (required field)
- if r.Spec.GroupRef.Name == "" {
- return fmt.Errorf("spec.groupRef.name is required")
+ // Validate Group is set (required field)
+ if r.Spec.Config.Group == "" {
+ return fmt.Errorf("spec.config.groupRef is required")
}
// Validate IncomingAuth configuration
diff --git a/cmd/thv-operator/api/v1alpha1/virtualmcpserver_webhook_test.go b/cmd/thv-operator/api/v1alpha1/virtualmcpserver_webhook_test.go
index 13bb1a4152..ef2b568906 100644
--- a/cmd/thv-operator/api/v1alpha1/virtualmcpserver_webhook_test.go
+++ b/cmd/thv-operator/api/v1alpha1/virtualmcpserver_webhook_test.go
@@ -2,6 +2,8 @@ package v1alpha1
import (
"testing"
+
+ "github.com/stacklok/toolhive/pkg/vmcp/config"
)
func TestVirtualMCPServerValidate(t *testing.T) {
@@ -16,9 +18,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "valid minimal configuration",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{
- Name: "test-group",
- },
+ Config: config.Config{Group: "test-group"},
},
},
wantErr: false,
@@ -27,19 +27,17 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "missing groupRef name",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{
- Name: "",
- },
+ Config: config.Config{Group: ""},
},
},
wantErr: true,
- errMsg: "spec.groupRef.name is required",
+ errMsg: "spec.config.groupRef is required",
},
{
name: "empty IncomingAuth type",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
IncomingAuth: &IncomingAuthConfig{
Type: "",
},
@@ -52,7 +50,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "OIDC auth without OIDCConfig",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
IncomingAuth: &IncomingAuthConfig{
Type: "oidc",
OIDCConfig: nil,
@@ -66,7 +64,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "valid outgoingAuth with discovered source",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
OutgoingAuth: &OutgoingAuthConfig{
Source: "discovered",
},
@@ -78,7 +76,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "invalid outgoingAuth source",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
OutgoingAuth: &OutgoingAuthConfig{
Source: "invalid",
},
@@ -91,7 +89,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "invalid backend auth type",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
OutgoingAuth: &OutgoingAuthConfig{
Backends: map[string]BackendAuthConfig{
"test-backend": {
@@ -108,7 +106,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "valid backend external auth config ref",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
OutgoingAuth: &OutgoingAuthConfig{
Backends: map[string]BackendAuthConfig{
"test-backend": {
@@ -127,7 +125,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "invalid backend external auth config ref - missing name",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
OutgoingAuth: &OutgoingAuthConfig{
Backends: map[string]BackendAuthConfig{
"test-backend": {
@@ -145,7 +143,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "valid aggregation with prefix strategy",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
Aggregation: &AggregationConfig{
ConflictResolution: ConflictResolutionPrefix,
ConflictResolutionConfig: &ConflictResolutionConfig{
@@ -160,7 +158,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "valid aggregation with priority strategy",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
Aggregation: &AggregationConfig{
ConflictResolution: ConflictResolutionPriority,
ConflictResolutionConfig: &ConflictResolutionConfig{
@@ -175,7 +173,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "invalid aggregation - priority strategy without priority order",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
Aggregation: &AggregationConfig{
ConflictResolution: ConflictResolutionPriority,
ConflictResolutionConfig: &ConflictResolutionConfig{},
@@ -189,7 +187,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "valid aggregation with tool config ref",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
Aggregation: &AggregationConfig{
Tools: []WorkloadToolConfig{
{
@@ -208,7 +206,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "invalid aggregation - missing workload name",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
Aggregation: &AggregationConfig{
Tools: []WorkloadToolConfig{
{
@@ -227,7 +225,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "valid composite tool",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -249,7 +247,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "invalid composite tool - missing name",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Description: "Test composite tool",
@@ -270,7 +268,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "invalid composite tool - missing description",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -291,7 +289,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "invalid composite tool - no steps",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -308,7 +306,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "invalid composite tool - duplicate tool names",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -334,7 +332,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "invalid composite tool - missing step ID",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -353,7 +351,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "invalid composite tool - tool step without tool",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -375,7 +373,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "invalid composite tool - elicitation step without message",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -397,7 +395,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "invalid composite tool - duplicate step IDs",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -417,7 +415,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "invalid composite tool - invalid step type",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -440,7 +438,7 @@ func TestVirtualMCPServerValidate(t *testing.T) {
name: "invalid aggregation - invalid conflict resolution strategy",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
Aggregation: &AggregationConfig{
ConflictResolution: "invalid-strategy",
},
@@ -479,7 +477,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "valid step dependencies",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -498,7 +496,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "valid forward dependencies",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -517,7 +515,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "valid error handling with retry",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -542,7 +540,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "invalid error handling action",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -567,7 +565,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "invalid error handling - retry without maxRetries",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -593,7 +591,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "valid error handling with retryDelay",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -619,7 +617,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "valid error handling with complex retryDelay",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -645,7 +643,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "invalid error handling - invalid retryDelay format",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -672,7 +670,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "invalid composite tool - unknown dependency reference",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -695,7 +693,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "valid elicitation with OnDecline skip_remaining",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -720,7 +718,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "valid elicitation with OnDecline abort",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -745,7 +743,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "valid elicitation with OnDecline continue",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -770,7 +768,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "valid elicitation with OnCancel skip_remaining",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -795,7 +793,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "valid elicitation with OnCancel abort",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -820,7 +818,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "valid elicitation with OnCancel continue",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -845,7 +843,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "valid elicitation with both OnDecline and OnCancel",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -873,7 +871,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "invalid elicitation - OnDecline with invalid action",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
@@ -899,7 +897,7 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
name: "invalid elicitation - OnCancel with invalid action",
vmcp: &VirtualMCPServer{
Spec: VirtualMCPServerSpec{
- GroupRef: GroupRef{Name: "test-group"},
+ Config: config.Config{Group: "test-group"},
CompositeTools: []CompositeToolSpec{
{
Name: "test-tool",
diff --git a/cmd/thv-operator/api/v1alpha1/zz_generated.deepcopy.go b/cmd/thv-operator/api/v1alpha1/zz_generated.deepcopy.go
index 7b2053d043..5bef5bf7a7 100644
--- a/cmd/thv-operator/api/v1alpha1/zz_generated.deepcopy.go
+++ b/cmd/thv-operator/api/v1alpha1/zz_generated.deepcopy.go
@@ -415,21 +415,6 @@ func (in *GitSource) DeepCopy() *GitSource {
return out
}
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *GroupRef) DeepCopyInto(out *GroupRef) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupRef.
-func (in *GroupRef) DeepCopy() *GroupRef {
- if in == nil {
- return nil
- }
- out := new(GroupRef)
- in.DeepCopyInto(out)
- return out
-}
-
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HeaderInjectionConfig) DeepCopyInto(out *HeaderInjectionConfig) {
*out = *in
@@ -2326,7 +2311,6 @@ func (in *VirtualMCPServerList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VirtualMCPServerSpec) DeepCopyInto(out *VirtualMCPServerSpec) {
*out = *in
- out.GroupRef = in.GroupRef
if in.IncomingAuth != nil {
in, out := &in.IncomingAuth, &out.IncomingAuth
*out = new(IncomingAuthConfig)
diff --git a/cmd/thv-operator/controllers/virtualmcpserver_controller.go b/cmd/thv-operator/controllers/virtualmcpserver_controller.go
index 7a98a17fb1..ce4c38bdc3 100644
--- a/cmd/thv-operator/controllers/virtualmcpserver_controller.go
+++ b/cmd/thv-operator/controllers/virtualmcpserver_controller.go
@@ -241,12 +241,12 @@ func (r *VirtualMCPServerReconciler) validateGroupRef(
// Validate GroupRef exists
mcpGroup := &mcpv1alpha1.MCPGroup{}
err := r.Get(ctx, types.NamespacedName{
- Name: vmcp.Spec.GroupRef.Name,
+ Name: vmcp.Spec.Config.Group,
Namespace: vmcp.Namespace,
}, mcpGroup)
if errors.IsNotFound(err) {
- message := fmt.Sprintf("Referenced MCPGroup %s not found", vmcp.Spec.GroupRef.Name)
+ message := fmt.Sprintf("Referenced MCPGroup %s not found", vmcp.Spec.Config.Group)
statusManager.SetPhase(mcpv1alpha1.VirtualMCPServerPhaseFailed)
statusManager.SetMessage(message)
statusManager.SetGroupRefValidatedCondition(
@@ -264,7 +264,7 @@ func (r *VirtualMCPServerReconciler) validateGroupRef(
// Check if MCPGroup is ready
if mcpGroup.Status.Phase != mcpv1alpha1.MCPGroupPhaseReady {
message := fmt.Sprintf("Referenced MCPGroup %s is not ready (phase: %s)",
- vmcp.Spec.GroupRef.Name, mcpGroup.Status.Phase)
+ vmcp.Spec.Config.Group, mcpGroup.Status.Phase)
statusManager.SetPhase(mcpv1alpha1.VirtualMCPServerPhasePending)
statusManager.SetMessage(message)
statusManager.SetGroupRefValidatedCondition(
@@ -274,13 +274,13 @@ func (r *VirtualMCPServerReconciler) validateGroupRef(
)
statusManager.SetObservedGeneration(vmcp.Generation)
// Requeue to check again later
- return fmt.Errorf("MCPGroup %s is not ready", vmcp.Spec.GroupRef.Name)
+ return fmt.Errorf("MCPGroup %s is not ready", vmcp.Spec.Config.Group)
}
// GroupRef is valid and ready
statusManager.SetGroupRefValidatedCondition(
mcpv1alpha1.ConditionReasonVirtualMCPServerGroupRefValid,
- fmt.Sprintf("MCPGroup %s is valid and ready", vmcp.Spec.GroupRef.Name),
+ fmt.Sprintf("MCPGroup %s is valid and ready", vmcp.Spec.Config.Group),
metav1.ConditionTrue,
)
statusManager.SetObservedGeneration(vmcp.Generation)
@@ -458,7 +458,7 @@ func (r *VirtualMCPServerReconciler) ensureAllResources(
// This ensures consistency - all functions use the same workload list
// rather than listing at different times which could yield different results
workloadDiscoverer := workloads.NewK8SDiscovererWithClient(r.Client, vmcp.Namespace)
- workloadNames, err := workloadDiscoverer.ListWorkloadsInGroup(ctx, vmcp.Spec.GroupRef.Name)
+ workloadNames, err := workloadDiscoverer.ListWorkloadsInGroup(ctx, vmcp.Spec.Config.Group)
if err != nil {
ctxLogger.Error(err, "Failed to list workloads in group")
return fmt.Errorf("failed to list workloads in group: %w", err)
@@ -1527,7 +1527,7 @@ func (r *VirtualMCPServerReconciler) discoverBackends(
workloadDiscoverer := workloads.NewK8SDiscovererWithClient(r.Client, vmcp.Namespace)
// Get all workloads in the group
- typedWorkloads, err := workloadDiscoverer.ListWorkloadsInGroup(ctx, vmcp.Spec.GroupRef.Name)
+ typedWorkloads, err := workloadDiscoverer.ListWorkloadsInGroup(ctx, vmcp.Spec.Config.Group)
if err != nil {
return nil, fmt.Errorf("failed to list workloads in group: %w", err)
}
@@ -1550,7 +1550,7 @@ func (r *VirtualMCPServerReconciler) discoverBackends(
backendDiscoverer := aggregator.NewUnifiedBackendDiscoverer(workloadDiscoverer, groupsManager, authConfig)
// Discover backends using the aggregator
- backends, err := backendDiscoverer.Discover(ctx, vmcp.Spec.GroupRef.Name)
+ backends, err := backendDiscoverer.Discover(ctx, vmcp.Spec.Config.Group)
if err != nil {
return nil, fmt.Errorf("failed to discover backends: %w", err)
}
@@ -1697,7 +1697,7 @@ func (r *VirtualMCPServerReconciler) mapMCPGroupToVirtualMCPServer(ctx context.C
var requests []reconcile.Request
for _, vmcp := range vmcpList.Items {
- if vmcp.Spec.GroupRef.Name == mcpGroup.Name {
+ if vmcp.Spec.Config.Group == mcpGroup.Name {
requests = append(requests, reconcile.Request{
NamespacedName: types.NamespacedName{
Name: vmcp.Name,
@@ -1768,7 +1768,7 @@ func (r *VirtualMCPServerReconciler) mapMCPServerToVirtualMCPServer(ctx context.
var requests []reconcile.Request
for _, vmcp := range vmcpList.Items {
// Only reconcile if this VirtualMCPServer references an affected MCPGroup
- if affectedGroups[vmcp.Spec.GroupRef.Name] {
+ if affectedGroups[vmcp.Spec.Config.Group] {
requests = append(requests, reconcile.Request{
NamespacedName: types.NamespacedName{
Name: vmcp.Name,
@@ -1777,7 +1777,7 @@ func (r *VirtualMCPServerReconciler) mapMCPServerToVirtualMCPServer(ctx context.
})
ctxLogger.V(1).Info("Queuing VirtualMCPServer for reconciliation due to MCPServer change",
"virtualMCPServer", vmcp.Name,
- "mcpGroup", vmcp.Spec.GroupRef.Name,
+ "mcpGroup", vmcp.Spec.Config.Group,
"mcpServer", mcpServer.Name)
}
}
@@ -1849,7 +1849,7 @@ func (r *VirtualMCPServerReconciler) mapMCPRemoteProxyToVirtualMCPServer(
var requests []reconcile.Request
for _, vmcp := range vmcpList.Items {
// Only reconcile if this VirtualMCPServer references an affected MCPGroup
- if affectedGroups[vmcp.Spec.GroupRef.Name] {
+ if affectedGroups[vmcp.Spec.Config.Group] {
requests = append(requests, reconcile.Request{
NamespacedName: types.NamespacedName{
Name: vmcp.Name,
@@ -1858,7 +1858,7 @@ func (r *VirtualMCPServerReconciler) mapMCPRemoteProxyToVirtualMCPServer(
})
ctxLogger.V(1).Info("Queuing VirtualMCPServer for reconciliation due to MCPRemoteProxy change",
"virtualMCPServer", vmcp.Name,
- "mcpGroup", vmcp.Spec.GroupRef.Name,
+ "mcpGroup", vmcp.Spec.Config.Group,
"mcpRemoteProxy", mcpRemoteProxy.Name)
}
}
@@ -1997,14 +1997,14 @@ func (r *VirtualMCPServerReconciler) mcpGroupBackendsReferenceExternalAuthConfig
// Get the MCPGroup to verify it exists
mcpGroup := &mcpv1alpha1.MCPGroup{}
err := r.Get(ctx, types.NamespacedName{
- Name: vmcp.Spec.GroupRef.Name,
+ Name: vmcp.Spec.Config.Group,
Namespace: vmcp.Namespace,
}, mcpGroup)
if err != nil {
// If we can't get the group, we can't determine if it references the auth config
// Return false to avoid false positives
ctxLogger.Error(err, "Failed to get MCPGroup for ExternalAuthConfig reference check",
- "group", vmcp.Spec.GroupRef.Name,
+ "group", vmcp.Spec.Config.Group,
"vmcp", vmcp.Name)
return false
}
diff --git a/cmd/thv-operator/controllers/virtualmcpserver_controller_test.go b/cmd/thv-operator/controllers/virtualmcpserver_controller_test.go
index 0c9328f74c..c5448e323b 100644
--- a/cmd/thv-operator/controllers/virtualmcpserver_controller_test.go
+++ b/cmd/thv-operator/controllers/virtualmcpserver_controller_test.go
@@ -36,6 +36,7 @@ import (
ctrlutil "github.com/stacklok/toolhive/cmd/thv-operator/pkg/controllerutil"
"github.com/stacklok/toolhive/cmd/thv-operator/pkg/runconfig/configmap/checksum"
"github.com/stacklok/toolhive/cmd/thv-operator/pkg/virtualmcpserverstatus"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/pkg/vmcp/workloads"
)
@@ -65,9 +66,7 @@ func TestVirtualMCPServerValidateGroupRef(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
},
mcpGroup: &mcpv1alpha1.MCPGroup{
@@ -113,9 +112,7 @@ func TestVirtualMCPServerValidateGroupRef(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "missing-group",
- },
+ Config: vmcpconfig.Config{Group: "missing-group"},
},
},
expectError: true,
@@ -130,9 +127,7 @@ func TestVirtualMCPServerValidateGroupRef(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "pending-group",
- },
+ Config: vmcpconfig.Config{Group: "pending-group"},
},
},
mcpGroup: &mcpv1alpha1.MCPGroup{
@@ -225,9 +220,7 @@ func TestVirtualMCPServerEnsureRBACResources(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
@@ -305,9 +298,7 @@ func TestVirtualMCPServerEnsureDeployment(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
@@ -390,9 +381,7 @@ func TestVirtualMCPServerEnsureService(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
@@ -471,9 +460,7 @@ func TestVirtualMCPServerServiceType(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
ServiceType: tt.serviceType,
},
}
@@ -504,9 +491,7 @@ func TestVirtualMCPServerServiceNeedsUpdate(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
ServiceType: "ClusterIP",
},
}
@@ -791,9 +776,7 @@ func TestVirtualMCPServerAuthConfiguredCondition(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
@@ -813,9 +796,7 @@ func TestVirtualMCPServerAuthConfiguredCondition(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "oidc",
OIDCConfig: &mcpv1alpha1.OIDCConfigRef{
@@ -846,9 +827,7 @@ func TestVirtualMCPServerAuthConfiguredCondition(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "oidc",
OIDCConfig: &mcpv1alpha1.OIDCConfigRef{
@@ -889,9 +868,7 @@ func TestVirtualMCPServerAuthConfiguredCondition(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "oidc",
OIDCConfig: &mcpv1alpha1.OIDCConfigRef{
@@ -1026,9 +1003,7 @@ func TestVirtualMCPServerApplyStatusUpdates(t *testing.T) {
Generation: 1,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
},
@@ -1051,9 +1026,7 @@ func TestVirtualMCPServerApplyStatusUpdates(t *testing.T) {
Generation: 1,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
},
@@ -1073,9 +1046,7 @@ func TestVirtualMCPServerApplyStatusUpdates(t *testing.T) {
Generation: 1,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
},
@@ -1159,9 +1130,7 @@ func TestVirtualMCPServerApplyStatusUpdates_ResourceNotFound(t *testing.T) {
Generation: 1,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
@@ -1203,9 +1172,7 @@ func TestVirtualMCPServerEnsureAllResources_Errors(t *testing.T) {
Generation: 1,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
},
@@ -1278,9 +1245,7 @@ func TestVirtualMCPServerContainerNeedsUpdate(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
@@ -1456,9 +1421,7 @@ func TestVirtualMCPServerContainerNeedsUpdate(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
Operational: &mcpv1alpha1.OperationalConfig{
LogLevel: "debug",
},
@@ -1763,9 +1726,7 @@ func TestVirtualMCPServerDeploymentNeedsUpdate(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
@@ -1937,9 +1898,7 @@ func TestVirtualMCPServerReconcile_HappyPath(t *testing.T) {
Generation: 1,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
@@ -2072,9 +2031,7 @@ func TestVirtualMCPServerReconcile_ValidateGroupRefError(t *testing.T) {
Generation: 1,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "nonexistent-group",
- },
+ Config: vmcpconfig.Config{Group: "nonexistent-group"},
},
}
@@ -2130,9 +2087,7 @@ func TestVirtualMCPServerReconcile_GroupNotReady(t *testing.T) {
Generation: 1,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
@@ -2226,9 +2181,7 @@ func TestVirtualMCPServerEnsureDeployment_ConfigMapNotFound(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
@@ -2264,9 +2217,7 @@ func TestVirtualMCPServerEnsureDeployment_CreateDeployment(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
@@ -2323,9 +2274,7 @@ func TestVirtualMCPServerEnsureDeployment_UpdateDeployment(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
@@ -2408,9 +2357,7 @@ func TestVirtualMCPServerEnsureDeployment_NoUpdateNeeded(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
@@ -2496,9 +2443,7 @@ func TestVirtualMCPServerEnsureService_CreateService(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
@@ -2540,9 +2485,7 @@ func TestVirtualMCPServerEnsureService_UpdateService(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
ServiceType: "LoadBalancer",
},
}
@@ -2604,9 +2547,7 @@ func TestVirtualMCPServerEnsureService_NoUpdateNeeded(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: testGroupName,
- },
+ Config: vmcpconfig.Config{Group: testGroupName},
},
}
diff --git a/cmd/thv-operator/controllers/virtualmcpserver_deployment_test.go b/cmd/thv-operator/controllers/virtualmcpserver_deployment_test.go
index e82f310ea4..795f6865ea 100644
--- a/cmd/thv-operator/controllers/virtualmcpserver_deployment_test.go
+++ b/cmd/thv-operator/controllers/virtualmcpserver_deployment_test.go
@@ -28,6 +28,7 @@ import (
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
ctrlutil "github.com/stacklok/toolhive/cmd/thv-operator/pkg/controllerutil"
"github.com/stacklok/toolhive/cmd/thv-operator/pkg/runconfig/configmap/checksum"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/pkg/vmcp/workloads"
)
@@ -41,9 +42,7 @@ func TestDeploymentForVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
}
@@ -93,9 +92,7 @@ func TestBuildContainerArgsForVmcp(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
wantArgs: []string{"serve", "--config=/etc/vmcp-config/config.yaml", "--host=0.0.0.0", "--port=4483"},
@@ -108,9 +105,7 @@ func TestBuildContainerArgsForVmcp(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
Operational: &mcpv1alpha1.OperationalConfig{
LogLevel: "debug",
},
@@ -142,9 +137,7 @@ func TestBuildVolumesForVmcp(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
}
@@ -173,9 +166,7 @@ func TestBuildEnvVarsForVmcp(t *testing.T) {
Namespace: "test-namespace",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
}
@@ -291,9 +282,7 @@ func TestServiceForVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
}
diff --git a/cmd/thv-operator/controllers/virtualmcpserver_discover_backends_test.go b/cmd/thv-operator/controllers/virtualmcpserver_discover_backends_test.go
index c16b1821eb..a6073da323 100644
--- a/cmd/thv-operator/controllers/virtualmcpserver_discover_backends_test.go
+++ b/cmd/thv-operator/controllers/virtualmcpserver_discover_backends_test.go
@@ -33,6 +33,7 @@ import (
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
ctrlutil "github.com/stacklok/toolhive/cmd/thv-operator/pkg/controllerutil"
"github.com/stacklok/toolhive/cmd/thv-operator/pkg/virtualmcpserverstatus"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
)
// TestVirtualMCPServerDiscoverBackends tests the discoverBackends function
@@ -59,9 +60,7 @@ func TestVirtualMCPServerDiscoverBackends(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
mcpGroup: &mcpv1alpha1.MCPGroup{
@@ -120,9 +119,7 @@ func TestVirtualMCPServerDiscoverBackends(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
mcpGroup: &mcpv1alpha1.MCPGroup{
@@ -203,9 +200,7 @@ func TestVirtualMCPServerDiscoverBackends(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
mcpGroup: &mcpv1alpha1.MCPGroup{
@@ -265,9 +260,7 @@ func TestVirtualMCPServerDiscoverBackends(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
mcpGroup: &mcpv1alpha1.MCPGroup{
@@ -429,9 +422,7 @@ func TestVirtualMCPServerStatusManagerDiscoveredBackends(t *testing.T) {
Generation: 1,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
}
@@ -500,9 +491,7 @@ func TestVirtualMCPServerReconcileWithBackendDiscovery(t *testing.T) {
Generation: 1,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
}
diff --git a/cmd/thv-operator/controllers/virtualmcpserver_externalauth_test.go b/cmd/thv-operator/controllers/virtualmcpserver_externalauth_test.go
index 5725018ef5..bf78201309 100644
--- a/cmd/thv-operator/controllers/virtualmcpserver_externalauth_test.go
+++ b/cmd/thv-operator/controllers/virtualmcpserver_externalauth_test.go
@@ -244,7 +244,7 @@ func TestBuildOutgoingAuthConfig(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
},
@@ -316,7 +316,7 @@ func TestBuildOutgoingAuthConfig(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
Backends: map[string]mcpv1alpha1.BackendAuthConfig{
@@ -427,7 +427,7 @@ func TestBuildOutgoingAuthConfig(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "inline",
Backends: map[string]mcpv1alpha1.BackendAuthConfig{
@@ -492,7 +492,7 @@ func TestBuildOutgoingAuthConfig(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
Default: &mcpv1alpha1.BackendAuthConfig{
@@ -535,7 +535,7 @@ func TestBuildOutgoingAuthConfig(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "inline",
Backends: map[string]mcpv1alpha1.BackendAuthConfig{
@@ -584,7 +584,7 @@ func TestBuildOutgoingAuthConfig(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
},
@@ -624,7 +624,7 @@ func TestBuildOutgoingAuthConfig(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
// No OutgoingAuth specified
},
},
@@ -793,7 +793,7 @@ func TestDiscoverBackendsWithExternalAuthConfigIntegration(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
},
diff --git a/cmd/thv-operator/controllers/virtualmcpserver_podtemplatespec_reconcile_test.go b/cmd/thv-operator/controllers/virtualmcpserver_podtemplatespec_reconcile_test.go
index 13b30a5203..1bfe240401 100644
--- a/cmd/thv-operator/controllers/virtualmcpserver_podtemplatespec_reconcile_test.go
+++ b/cmd/thv-operator/controllers/virtualmcpserver_podtemplatespec_reconcile_test.go
@@ -14,6 +14,7 @@ import (
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
"github.com/stacklok/toolhive/cmd/thv-operator/pkg/runconfig/configmap/checksum"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/pkg/vmcp/workloads"
)
@@ -58,9 +59,7 @@ func TestVirtualMCPServerPodTemplateSpecDeterministic(t *testing.T) {
Namespace: namespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: groupName,
- },
+ Config: vmcpconfig.Config{Group: groupName},
PodTemplateSpec: podTemplateSpecToRawExtension(t, podTemplate),
},
}
@@ -134,9 +133,7 @@ func TestVirtualMCPServerPodTemplateSpecPreservesContainer(t *testing.T) {
Namespace: namespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: groupName,
- },
+ Config: vmcpconfig.Config{Group: groupName},
PodTemplateSpec: &runtime.RawExtension{
Raw: []byte(`{"spec":{"nodeSelector":{"disktype":"ssd"}}}`),
},
@@ -252,9 +249,7 @@ func TestVirtualMCPServerPodTemplateSpecNeedsUpdate(t *testing.T) {
Namespace: namespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: groupName,
- },
+ Config: vmcpconfig.Config{Group: groupName},
PodTemplateSpec: podTemplateSpecToRawExtension(t, &tt.existingPodTemplate),
},
}
@@ -291,9 +286,7 @@ func TestVirtualMCPServerPodTemplateSpecNeedsUpdate(t *testing.T) {
Namespace: namespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: groupName,
- },
+ Config: vmcpconfig.Config{Group: groupName},
PodTemplateSpec: tt.newPodTemplateSpec,
},
}
diff --git a/cmd/thv-operator/controllers/virtualmcpserver_vmcpconfig_test.go b/cmd/thv-operator/controllers/virtualmcpserver_vmcpconfig_test.go
index e4bad07d6e..1fd387b3a3 100644
--- a/cmd/thv-operator/controllers/virtualmcpserver_vmcpconfig_test.go
+++ b/cmd/thv-operator/controllers/virtualmcpserver_vmcpconfig_test.go
@@ -31,9 +31,9 @@ import (
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
oidcmocks "github.com/stacklok/toolhive/cmd/thv-operator/pkg/oidc/mocks"
- "github.com/stacklok/toolhive/cmd/thv-operator/pkg/vmcpconfig"
+ vmcpconfigconv "github.com/stacklok/toolhive/cmd/thv-operator/pkg/vmcpconfig"
"github.com/stacklok/toolhive/pkg/vmcp"
- vmcpconfigpkg "github.com/stacklok/toolhive/pkg/vmcp/config"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/pkg/vmcp/workloads"
)
@@ -48,12 +48,12 @@ func newNoOpMockResolver(t *testing.T) *oidcmocks.MockResolver {
}
// newTestConverter creates a Converter with the given resolver, failing the test if creation fails.
-func newTestConverter(t *testing.T, resolver *oidcmocks.MockResolver) *vmcpconfig.Converter {
+func newTestConverter(t *testing.T, resolver *oidcmocks.MockResolver) *vmcpconfigconv.Converter {
t.Helper()
scheme := runtime.NewScheme()
_ = mcpv1alpha1.AddToScheme(scheme)
fakeClient := fake.NewClientBuilder().WithScheme(scheme).Build()
- converter, err := vmcpconfig.NewConverter(resolver, fakeClient)
+ converter, err := vmcpconfigconv.NewConverter(resolver, fakeClient)
require.NoError(t, err)
return converter
}
@@ -76,9 +76,7 @@ func TestCreateVmcpConfigFromVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
expectedName: "test-vmcp",
@@ -157,9 +155,7 @@ func TestConvertOutgoingAuth(t *testing.T) {
vmcpServer := &mcpv1alpha1.VirtualMCPServer{
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: tt.outgoingAuth,
},
}
@@ -221,9 +217,7 @@ func TestConvertBackendAuthConfig(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Default: tt.authConfig,
},
@@ -231,7 +225,7 @@ func TestConvertBackendAuthConfig(t *testing.T) {
}
// For external_auth_config_ref test, create the referenced MCPExternalAuthConfig
- var converter *vmcpconfig.Converter
+ var converter *vmcpconfigconv.Converter
if tt.authConfig.Type == mcpv1alpha1.BackendAuthTypeExternalAuthConfigRef {
// Create a fake MCPExternalAuthConfig
externalAuthConfig := &mcpv1alpha1.MCPExternalAuthConfig{
@@ -252,7 +246,7 @@ func TestConvertBackendAuthConfig(t *testing.T) {
WithObjects(externalAuthConfig).
Build()
var err error
- converter, err = vmcpconfig.NewConverter(newNoOpMockResolver(t), fakeClient)
+ converter, err = vmcpconfigconv.NewConverter(newNoOpMockResolver(t), fakeClient)
require.NoError(t, err)
} else {
converter = newTestConverter(t, newNoOpMockResolver(t))
@@ -344,9 +338,7 @@ func TestConvertAggregation(t *testing.T) {
vmcpServer := &mcpv1alpha1.VirtualMCPServer{
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
Aggregation: tt.aggregation,
},
}
@@ -437,9 +429,7 @@ func TestConvertCompositeTools(t *testing.T) {
vmcpServer := &mcpv1alpha1.VirtualMCPServer{
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeTools: tt.compositeTools,
},
}
@@ -470,9 +460,7 @@ func TestEnsureVmcpConfigConfigMap(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
}
@@ -502,7 +490,7 @@ func TestEnsureVmcpConfigConfigMap(t *testing.T) {
// Fetch workload names (matching production behavior)
ctx := context.Background()
workloadDiscoverer := workloads.NewK8SDiscovererWithClient(fakeClient, testVmcp.Namespace)
- workloadNames, err := workloadDiscoverer.ListWorkloadsInGroup(ctx, testVmcp.Spec.GroupRef.Name)
+ workloadNames, err := workloadDiscoverer.ListWorkloadsInGroup(ctx, testVmcp.Spec.Config.Group)
require.NoError(t, err, "should successfully list workloads in group")
err = r.ensureVmcpConfigConfigMap(ctx, testVmcp, workloadNames)
@@ -543,7 +531,7 @@ func TestValidateVmcpConfig(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
- validator := vmcpconfig.NewValidator()
+ validator := vmcpconfigconv.NewValidator()
// Type assertion will fail for nil, which is expected
if tt.config == nil {
@@ -583,9 +571,7 @@ func TestYAMLMarshalingDeterminism(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
// OutgoingAuth with Backends map
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
@@ -730,9 +716,7 @@ func TestVirtualMCPServerReconciler_CompositeToolRefs_EndToEnd(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
@@ -756,7 +740,7 @@ func TestVirtualMCPServerReconciler_CompositeToolRefs_EndToEnd(t *testing.T) {
// Fetch workload names (matching production behavior)
workloadDiscoverer := workloads.NewK8SDiscovererWithClient(fakeClient, vmcpServer.Namespace)
- workloadNames, err := workloadDiscoverer.ListWorkloadsInGroup(ctx, vmcpServer.Spec.GroupRef.Name)
+ workloadNames, err := workloadDiscoverer.ListWorkloadsInGroup(ctx, vmcpServer.Spec.Config.Group)
require.NoError(t, err, "should successfully list workloads in group")
// Test the ensureVmcpConfigConfigMap function
@@ -775,7 +759,7 @@ func TestVirtualMCPServerReconciler_CompositeToolRefs_EndToEnd(t *testing.T) {
require.Contains(t, configMap.Data, "config.yaml", "ConfigMap should contain config.yaml")
// Parse the YAML config
- var config vmcpconfigpkg.Config
+ var config vmcpconfig.Config
err = yaml.Unmarshal([]byte(configMap.Data["config.yaml"]), &config)
require.NoError(t, err, "should parse config YAML")
@@ -786,7 +770,7 @@ func TestVirtualMCPServerReconciler_CompositeToolRefs_EndToEnd(t *testing.T) {
require.Len(t, config.CompositeTools[0].Steps, 1)
assert.Equal(t, "step1", config.CompositeTools[0].Steps[0].ID)
assert.Equal(t, "backend.echo", config.CompositeTools[0].Steps[0].Tool)
- assert.Equal(t, vmcpconfigpkg.Duration(30*time.Second), config.CompositeTools[0].Timeout)
+ assert.Equal(t, vmcpconfig.Duration(30*time.Second), config.CompositeTools[0].Timeout)
// Verify parameters were converted
require.NotNil(t, config.CompositeTools[0].Parameters)
@@ -841,9 +825,7 @@ func TestVirtualMCPServerReconciler_CompositeToolRefs_MergeInlineAndReferenced(t
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
@@ -880,7 +862,7 @@ func TestVirtualMCPServerReconciler_CompositeToolRefs_MergeInlineAndReferenced(t
// Fetch workload names (matching production behavior)
workloadDiscoverer := workloads.NewK8SDiscovererWithClient(fakeClient, vmcpServer.Namespace)
- workloadNames, err := workloadDiscoverer.ListWorkloadsInGroup(ctx, vmcpServer.Spec.GroupRef.Name)
+ workloadNames, err := workloadDiscoverer.ListWorkloadsInGroup(ctx, vmcpServer.Spec.Config.Group)
require.NoError(t, err, "should successfully list workloads in group")
// Test the ensureVmcpConfigConfigMap function
@@ -896,7 +878,7 @@ func TestVirtualMCPServerReconciler_CompositeToolRefs_MergeInlineAndReferenced(t
require.NoError(t, err, "ConfigMap should exist")
// Parse the YAML config
- var config vmcpconfigpkg.Config
+ var config vmcpconfig.Config
err = yaml.Unmarshal([]byte(configMap.Data["config.yaml"]), &config)
require.NoError(t, err, "should parse config YAML")
@@ -937,9 +919,7 @@ func TestVirtualMCPServerReconciler_CompositeToolRefs_NotFound(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
@@ -963,7 +943,7 @@ func TestVirtualMCPServerReconciler_CompositeToolRefs_NotFound(t *testing.T) {
// Fetch workload names (matching production behavior)
workloadDiscoverer := workloads.NewK8SDiscovererWithClient(fakeClient, vmcpServer.Namespace)
- workloadNames, err := workloadDiscoverer.ListWorkloadsInGroup(ctx, vmcpServer.Spec.GroupRef.Name)
+ workloadNames, err := workloadDiscoverer.ListWorkloadsInGroup(ctx, vmcpServer.Spec.Config.Group)
require.NoError(t, err, "should successfully list workloads in group")
// Test should fail with not found error
diff --git a/cmd/thv-operator/controllers/virtualmcpserver_watch_test.go b/cmd/thv-operator/controllers/virtualmcpserver_watch_test.go
index 64dd634642..659b165811 100644
--- a/cmd/thv-operator/controllers/virtualmcpserver_watch_test.go
+++ b/cmd/thv-operator/controllers/virtualmcpserver_watch_test.go
@@ -26,6 +26,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
)
// TestMapMCPGroupToVirtualMCPServer tests the MCPGroup watch handler
@@ -54,9 +55,7 @@ func TestMapMCPGroupToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
},
@@ -78,9 +77,7 @@ func TestMapMCPGroupToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
{
@@ -89,9 +86,7 @@ func TestMapMCPGroupToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
},
@@ -113,9 +108,7 @@ func TestMapMCPGroupToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "other-group",
- },
+ Config: vmcpconfig.Config{Group: "other-group"},
},
},
},
@@ -137,9 +130,7 @@ func TestMapMCPGroupToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
{
@@ -148,9 +139,7 @@ func TestMapMCPGroupToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "other-group",
- },
+ Config: vmcpconfig.Config{Group: "other-group"},
},
},
},
@@ -268,9 +257,7 @@ func TestMapMCPServerToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
},
@@ -303,9 +290,7 @@ func TestMapMCPServerToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
},
@@ -338,9 +323,7 @@ func TestMapMCPServerToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "other-group",
- },
+ Config: vmcpconfig.Config{Group: "other-group"},
},
},
},
@@ -382,9 +365,7 @@ func TestMapMCPServerToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "group-1",
- },
+ Config: vmcpconfig.Config{Group: "group-1"},
},
},
{
@@ -393,9 +374,7 @@ func TestMapMCPServerToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "group-2",
- },
+ Config: vmcpconfig.Config{Group: "group-2"},
},
},
{
@@ -404,9 +383,7 @@ func TestMapMCPServerToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "group-3",
- },
+ Config: vmcpconfig.Config{Group: "group-3"},
},
},
},
@@ -530,9 +507,7 @@ func TestMapMCPRemoteProxyToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
},
@@ -565,9 +540,7 @@ func TestMapMCPRemoteProxyToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
},
@@ -600,9 +573,7 @@ func TestMapMCPRemoteProxyToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "other-group",
- },
+ Config: vmcpconfig.Config{Group: "other-group"},
},
},
},
@@ -644,9 +615,7 @@ func TestMapMCPRemoteProxyToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "group-1",
- },
+ Config: vmcpconfig.Config{Group: "group-1"},
},
},
{
@@ -655,9 +624,7 @@ func TestMapMCPRemoteProxyToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "group-2",
- },
+ Config: vmcpconfig.Config{Group: "group-2"},
},
},
{
@@ -666,9 +633,7 @@ func TestMapMCPRemoteProxyToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "group-3",
- },
+ Config: vmcpconfig.Config{Group: "group-3"},
},
},
},
@@ -912,9 +877,7 @@ func TestMapExternalAuthConfigToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
},
@@ -961,9 +924,7 @@ func TestMapExternalAuthConfigToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
},
@@ -1010,9 +971,7 @@ func TestMapExternalAuthConfigToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
},
@@ -1059,9 +1018,7 @@ func TestMapExternalAuthConfigToVirtualMCPServer(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
},
@@ -1538,9 +1495,7 @@ func TestVmcpReferencesExternalAuthConfig(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
},
@@ -1579,9 +1534,7 @@ func TestVmcpReferencesExternalAuthConfig(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
},
@@ -1620,9 +1573,7 @@ func TestVmcpReferencesExternalAuthConfig(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "nonexistent-group",
- },
+ Config: vmcpconfig.Config{Group: "nonexistent-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
},
@@ -1639,9 +1590,7 @@ func TestVmcpReferencesExternalAuthConfig(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
},
@@ -1701,9 +1650,7 @@ func TestVmcpReferencesExternalAuthConfig(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
},
@@ -1742,9 +1689,7 @@ func TestVmcpReferencesExternalAuthConfig(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: "test-group",
- },
+ Config: vmcpconfig.Config{Group: "test-group"},
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
},
diff --git a/cmd/thv-operator/pkg/vmcpconfig/converter.go b/cmd/thv-operator/pkg/vmcpconfig/converter.go
index 9532d79ccf..c8e0060ed2 100644
--- a/cmd/thv-operator/pkg/vmcpconfig/converter.go
+++ b/cmd/thv-operator/pkg/vmcpconfig/converter.go
@@ -67,7 +67,7 @@ func (c *Converter) Convert(
) (*vmcpconfig.Config, error) {
config := &vmcpconfig.Config{
Name: vmcp.Name,
- Group: vmcp.Spec.GroupRef.Name,
+ Group: vmcp.Spec.Config.Group,
}
// Convert IncomingAuth - required field, no defaults
diff --git a/cmd/thv-operator/pkg/vmcpconfig/converter_test.go b/cmd/thv-operator/pkg/vmcpconfig/converter_test.go
index 5d4ced3c52..51a4d2edb9 100644
--- a/cmd/thv-operator/pkg/vmcpconfig/converter_test.go
+++ b/cmd/thv-operator/pkg/vmcpconfig/converter_test.go
@@ -62,7 +62,7 @@ func newTestVMCPServer(oidcConfig *mcpv1alpha1.OIDCConfigRef) *mcpv1alpha1.Virtu
return &mcpv1alpha1.VirtualMCPServer{
ObjectMeta: metav1.ObjectMeta{Name: "test-vmcp", Namespace: "default"},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{Type: "oidc", OIDCConfig: oidcConfig},
},
}
@@ -281,7 +281,7 @@ func TestConvertCompositeTools_Parameters(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeTools: []mcpv1alpha1.CompositeToolSpec{
{
Name: "test-tool",
@@ -364,7 +364,7 @@ func TestConvertCompositeTools_Timeout(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeTools: []mcpv1alpha1.CompositeToolSpec{
{
Name: "test-tool",
@@ -488,7 +488,7 @@ func TestConverter_ConvertCompositeTools_ErrorHandling(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeTools: []mcpv1alpha1.CompositeToolSpec{
{
Name: "test-tool",
@@ -537,7 +537,7 @@ func TestConverter_ConvertCompositeTools_NoErrorHandling(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeTools: []mcpv1alpha1.CompositeToolSpec{
{
Name: "test-tool",
@@ -656,7 +656,7 @@ func TestConverter_ConvertCompositeTools_ElicitationResponseHandlers(t *testing.
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeTools: []mcpv1alpha1.CompositeToolSpec{
{
Name: "test-tool",
@@ -714,7 +714,7 @@ func TestConverter_ConvertCompositeTools_StepTimeout(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeTools: []mcpv1alpha1.CompositeToolSpec{
{
Name: "test-tool",
@@ -802,7 +802,7 @@ func TestConvertCompositeTools_NonStringArguments(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeTools: []mcpv1alpha1.CompositeToolSpec{
{
Name: "test-tool",
@@ -843,7 +843,7 @@ func TestConvertCompositeTools_NonStringArguments(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeTools: []mcpv1alpha1.CompositeToolSpec{
{
Name: "test-tool",
@@ -882,7 +882,7 @@ func TestConvertCompositeTools_NonStringArguments(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeTools: []mcpv1alpha1.CompositeToolSpec{
{
Name: "test-tool",
@@ -1224,7 +1224,7 @@ func TestConverter_ConvertCompositeTools_OutputSpec(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeTools: []mcpv1alpha1.CompositeToolSpec{
{
Name: "test-tool",
@@ -1346,7 +1346,7 @@ func TestConverter_IncomingAuthRequired(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
IncomingAuth: tt.incomingAuth,
},
}
@@ -1421,7 +1421,7 @@ func TestConverter_CompositeToolRefs(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeToolRefs: []mcpv1alpha1.CompositeToolDefinitionRef{
{Name: "referenced-tool"},
},
@@ -1465,7 +1465,7 @@ func TestConverter_CompositeToolRefs(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeTools: []mcpv1alpha1.CompositeToolSpec{
{
Name: "inline-tool",
@@ -1524,7 +1524,7 @@ func TestConverter_CompositeToolRefs(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeToolRefs: []mcpv1alpha1.CompositeToolDefinitionRef{
{Name: "non-existent-tool"},
},
@@ -1542,7 +1542,7 @@ func TestConverter_CompositeToolRefs(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeTools: []mcpv1alpha1.CompositeToolSpec{
{
Name: "duplicate-tool",
@@ -1591,7 +1591,7 @@ func TestConverter_CompositeToolRefs(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
compositeDefs: []*mcpv1alpha1.VirtualMCPCompositeToolDefinition{},
@@ -1607,7 +1607,7 @@ func TestConverter_CompositeToolRefs(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeToolRefs: []mcpv1alpha1.CompositeToolDefinitionRef{
{Name: "tool1"},
{Name: "tool2"},
@@ -1670,7 +1670,7 @@ func TestConverter_CompositeToolRefs(t *testing.T) {
Namespace: "default",
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
CompositeToolRefs: []mcpv1alpha1.CompositeToolDefinitionRef{
{Name: "referenced-tool"},
},
@@ -2165,7 +2165,7 @@ func TestConvert_MCPToolConfigFailClosed(t *testing.T) {
vmcp: &mcpv1alpha1.VirtualMCPServer{
ObjectMeta: metav1.ObjectMeta{Name: "test-vmcp", Namespace: "default"},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
Aggregation: &mcpv1alpha1.AggregationConfig{
Tools: []mcpv1alpha1.WorkloadToolConfig{{
Workload: "backend1",
@@ -2183,7 +2183,7 @@ func TestConvert_MCPToolConfigFailClosed(t *testing.T) {
vmcp: &mcpv1alpha1.VirtualMCPServer{
ObjectMeta: metav1.ObjectMeta{Name: "test-vmcp", Namespace: "default"},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
Aggregation: &mcpv1alpha1.AggregationConfig{
Tools: []mcpv1alpha1.WorkloadToolConfig{{
Workload: "backend1",
@@ -2200,7 +2200,7 @@ func TestConvert_MCPToolConfigFailClosed(t *testing.T) {
vmcp: &mcpv1alpha1.VirtualMCPServer{
ObjectMeta: metav1.ObjectMeta{Name: "test-vmcp", Namespace: "default"},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{Name: "test-group"},
+ Config: vmcpconfig.Config{Group: "test-group"},
},
},
existingConfig: nil,
diff --git a/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_compositetool_watch_test.go b/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_compositetool_watch_test.go
index b736e4048f..cc221a96e9 100644
--- a/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_compositetool_watch_test.go
+++ b/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_compositetool_watch_test.go
@@ -11,6 +11,7 @@ import (
"k8s.io/apimachinery/pkg/types"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
)
var _ = Describe("VirtualMCPServer CompositeToolDefinition Watch Integration Tests", func() {
@@ -68,9 +69,7 @@ var _ = Describe("VirtualMCPServer CompositeToolDefinition Watch Integration Tes
Namespace: namespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
@@ -269,9 +268,7 @@ var _ = Describe("VirtualMCPServer CompositeToolDefinition Watch Integration Tes
Namespace: namespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
@@ -391,9 +388,7 @@ var _ = Describe("VirtualMCPServer CompositeToolDefinition Watch Integration Tes
Namespace: namespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
diff --git a/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_elicitation_integration_test.go b/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_elicitation_integration_test.go
index 21ee96770f..dc5e42ec25 100644
--- a/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_elicitation_integration_test.go
+++ b/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_elicitation_integration_test.go
@@ -11,6 +11,7 @@ import (
"k8s.io/apimachinery/pkg/types"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
)
var _ = Describe("VirtualMCPServer Elicitation Integration Tests", func() {
@@ -132,9 +133,7 @@ var _ = Describe("VirtualMCPServer Elicitation Integration Tests", func() {
Namespace: namespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
@@ -339,9 +338,7 @@ var _ = Describe("VirtualMCPServer Elicitation Integration Tests", func() {
Namespace: namespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
@@ -527,9 +524,7 @@ var _ = Describe("VirtualMCPServer Elicitation Integration Tests", func() {
Namespace: namespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
diff --git a/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_externalauth_watch_test.go b/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_externalauth_watch_test.go
index 9ceb3781bc..6b05b7b275 100644
--- a/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_externalauth_watch_test.go
+++ b/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_externalauth_watch_test.go
@@ -10,6 +10,7 @@ import (
"k8s.io/apimachinery/pkg/types"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
)
var _ = Describe("VirtualMCPServer ExternalAuthConfig Watch Integration Tests", func() {
@@ -104,9 +105,7 @@ var _ = Describe("VirtualMCPServer ExternalAuthConfig Watch Integration Tests",
Namespace: namespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
diff --git a/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_podtemplatespec_integration_test.go b/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_podtemplatespec_integration_test.go
index 8d9ccb2f95..fcf38ad81b 100644
--- a/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_podtemplatespec_integration_test.go
+++ b/cmd/thv-operator/test-integration/virtualmcp/virtualmcpserver_podtemplatespec_integration_test.go
@@ -14,6 +14,7 @@ import (
"k8s.io/apimachinery/pkg/types"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
)
var _ = Describe("VirtualMCPServer PodTemplateSpec Integration Tests", func() {
@@ -68,9 +69,7 @@ var _ = Describe("VirtualMCPServer PodTemplateSpec Integration Tests", func() {
Namespace: namespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
@@ -209,9 +208,7 @@ var _ = Describe("VirtualMCPServer PodTemplateSpec Integration Tests", func() {
Namespace: namespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
@@ -314,9 +311,7 @@ var _ = Describe("VirtualMCPServer PodTemplateSpec Integration Tests", func() {
Namespace: namespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
diff --git a/deploy/charts/operator-crds/Chart.yaml b/deploy/charts/operator-crds/Chart.yaml
index 3097480de4..84f6159538 100644
--- a/deploy/charts/operator-crds/Chart.yaml
+++ b/deploy/charts/operator-crds/Chart.yaml
@@ -2,5 +2,5 @@ apiVersion: v2
name: toolhive-operator-crds
description: A Helm chart for installing the ToolHive Operator CRDs into Kubernetes.
type: application
-version: 0.0.89
+version: 0.0.90
appVersion: "0.0.1"
diff --git a/deploy/charts/operator-crds/README.md b/deploy/charts/operator-crds/README.md
index b1af8ad208..9e231efa51 100644
--- a/deploy/charts/operator-crds/README.md
+++ b/deploy/charts/operator-crds/README.md
@@ -1,6 +1,6 @@
# ToolHive Operator CRDs Helm Chart
-
+

A Helm chart for installing the ToolHive Operator CRDs into Kubernetes.
diff --git a/deploy/charts/operator-crds/files/crds/toolhive.stacklok.dev_virtualmcpservers.yaml b/deploy/charts/operator-crds/files/crds/toolhive.stacklok.dev_virtualmcpservers.yaml
index bc69d0e157..1acbf361fe 100644
--- a/deploy/charts/operator-crds/files/crds/toolhive.stacklok.dev_virtualmcpservers.yaml
+++ b/deploy/charts/operator-crds/files/crds/toolhive.stacklok.dev_virtualmcpservers.yaml
@@ -707,8 +707,9 @@ spec:
type: object
type: array
groupRef:
- description: Group references the ToolHive group containing backend
- workloads.
+ description: |-
+ Group references an existing MCPGroup that defines backend workloads.
+ In Kubernetes, the referenced MCPGroup must exist in the same namespace.
type: string
incomingAuth:
description: IncomingAuth configures how clients authenticate
@@ -1102,21 +1103,8 @@ spec:
type: object
required:
- groupRef
- - name
type: object
x-kubernetes-preserve-unknown-fields: true
- groupRef:
- description: |-
- GroupRef references an existing MCPGroup that defines backend workloads
- The referenced MCPGroup must exist in the same namespace
- properties:
- name:
- description: Name is the name of the MCPGroup resource in the
- same namespace
- type: string
- required:
- - name
- type: object
incomingAuth:
description: |-
IncomingAuth configures authentication for clients connecting to the Virtual MCP server
@@ -1567,7 +1555,6 @@ spec:
type: object
type: object
required:
- - groupRef
- incomingAuth
type: object
status:
diff --git a/deploy/charts/operator-crds/templates/toolhive.stacklok.dev_virtualmcpservers.yaml b/deploy/charts/operator-crds/templates/toolhive.stacklok.dev_virtualmcpservers.yaml
index ee00971bb0..ec87016d22 100644
--- a/deploy/charts/operator-crds/templates/toolhive.stacklok.dev_virtualmcpservers.yaml
+++ b/deploy/charts/operator-crds/templates/toolhive.stacklok.dev_virtualmcpservers.yaml
@@ -710,8 +710,9 @@ spec:
type: object
type: array
groupRef:
- description: Group references the ToolHive group containing backend
- workloads.
+ description: |-
+ Group references an existing MCPGroup that defines backend workloads.
+ In Kubernetes, the referenced MCPGroup must exist in the same namespace.
type: string
incomingAuth:
description: IncomingAuth configures how clients authenticate
@@ -1105,21 +1106,8 @@ spec:
type: object
required:
- groupRef
- - name
type: object
x-kubernetes-preserve-unknown-fields: true
- groupRef:
- description: |-
- GroupRef references an existing MCPGroup that defines backend workloads
- The referenced MCPGroup must exist in the same namespace
- properties:
- name:
- description: Name is the name of the MCPGroup resource in the
- same namespace
- type: string
- required:
- - name
- type: object
incomingAuth:
description: |-
IncomingAuth configures authentication for clients connecting to the Virtual MCP server
@@ -1570,7 +1558,6 @@ spec:
type: object
type: object
required:
- - groupRef
- incomingAuth
type: object
status:
diff --git a/docs/operator/crd-api.md b/docs/operator/crd-api.md
index 0d7bc5dfcb..ef65385fc8 100644
--- a/docs/operator/crd-api.md
+++ b/docs/operator/crd-api.md
@@ -419,22 +419,6 @@ _Appears in:_
| `path` _string_ | Path is the path to the registry file within the repository | registry.json | Pattern: `^.*\.json$`
|
-#### GroupRef
-
-
-
-GroupRef references an MCPGroup resource
-
-
-
-_Appears in:_
-- [VirtualMCPServerSpec](#virtualmcpserverspec)
-
-| Field | Description | Default | Validation |
-| --- | --- | --- | --- |
-| `name` _string_ | Name is the name of the MCPGroup resource in the same namespace | | Required: \{\}
|
-
-
#### HeaderInjectionConfig
@@ -2072,7 +2056,6 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `groupRef` _[GroupRef](#groupref)_ | GroupRef references an existing MCPGroup that defines backend workloads
The referenced MCPGroup must exist in the same namespace | | Required: \{\}
|
| `incomingAuth` _[IncomingAuthConfig](#incomingauthconfig)_ | IncomingAuth configures authentication for clients connecting to the Virtual MCP server
Must be explicitly set - use "anonymous" type when no authentication is required | | Required: \{\}
|
| `outgoingAuth` _[OutgoingAuthConfig](#outgoingauthconfig)_ | OutgoingAuth configures authentication from Virtual MCP to backend MCPServers | | |
| `aggregation` _[AggregationConfig](#aggregationconfig)_ | Aggregation defines tool aggregation and conflict resolution strategies | | |
diff --git a/docs/operator/virtualmcpcompositetooldefinition-guide.md b/docs/operator/virtualmcpcompositetooldefinition-guide.md
index 3598b5ec11..5bb4ba10ac 100644
--- a/docs/operator/virtualmcpcompositetooldefinition-guide.md
+++ b/docs/operator/virtualmcpcompositetooldefinition-guide.md
@@ -696,8 +696,8 @@ metadata:
name: production-vmcp
namespace: default
spec:
- groupRef:
- name: production-backends
+ config:
+ groupRef: production-backends
# Reference composite tool definitions
compositeToolRefs:
diff --git a/docs/operator/virtualmcpserver-api.md b/docs/operator/virtualmcpserver-api.md
index 14a70f2397..15d9871790 100644
--- a/docs/operator/virtualmcpserver-api.md
+++ b/docs/operator/virtualmcpserver-api.md
@@ -24,20 +24,17 @@ The `VirtualMCPServer` CRD enables aggregation of multiple backend MCPServers in
## Spec Fields
-### `.spec.groupRef` (required)
+### `.spec.config.groupRef` (required)
References an existing `MCPGroup` that defines the backend workloads to aggregate.
-**Type**: `GroupRef`
-
-**Fields**:
-- `name` (string, required): Name of the MCPGroup resource in the same namespace
+**Type**: `string`
**Example**:
```yaml
spec:
- groupRef:
- name: engineering-team
+ config:
+ groupRef: engineering-team
```
### `.spec.incomingAuth` (optional)
@@ -411,8 +408,8 @@ metadata:
namespace: default
spec:
# Reference to MCPGroup defining backend workloads
- groupRef:
- name: engineering-team
+ config:
+ groupRef: engineering-team
# Client authentication
incomingAuth:
@@ -558,9 +555,9 @@ status:
The VirtualMCPServer CRD includes comprehensive validation:
1. **Required Fields**:
- - `spec.groupRef.name` must be specified
+ - `spec.config.groupRef` must be specified
- `spec.incomingAuth.type` must be explicitly specified (use `anonymous` when no auth is needed)
-2. **Reference Validation**: All references (groupRef, authConfigRef, toolConfigRef) must be valid
+2. **Reference Validation**: All references (config.groupRef, authConfigRef, toolConfigRef) must be valid
3. **Conflict Resolution**: Priority strategy requires `priorityOrder` configuration
4. **Composite Tools**: Must have unique names, valid steps with IDs, and proper dependencies
5. **Token Cache**: Redis provider requires valid address configuration
diff --git a/docs/operator/virtualmcpserver-kubernetes-guide.md b/docs/operator/virtualmcpserver-kubernetes-guide.md
index 2223372cc5..ba5ffaa392 100644
--- a/docs/operator/virtualmcpserver-kubernetes-guide.md
+++ b/docs/operator/virtualmcpserver-kubernetes-guide.md
@@ -205,8 +205,8 @@ metadata:
name: my-vmcp
namespace: default
spec:
- groupRef:
- name: my-services
+ config:
+ groupRef: my-services
# Configure authentication (adjust from CLI if using OIDC)
incomingAuth:
@@ -365,8 +365,8 @@ kind: VirtualMCPServer
metadata:
name: services-vmcp
spec:
- groupRef:
- name: services
+ config:
+ groupRef: services
incomingAuth:
type: anonymous
outgoingAuth:
@@ -451,7 +451,7 @@ kubectl get virtualmcpserver my-vmcp -o yaml | grep -A 5 conditions
kubectl get mcpgroup
```
-Create if missing or fix the `groupRef.name` in VirtualMCPServer spec.
+Create if missing or fix `spec.config.groupRef` in VirtualMCPServer spec.
**2. No Backend MCPServers in Group**
diff --git a/docs/operator/virtualmcpserver-observability.md b/docs/operator/virtualmcpserver-observability.md
index 048c1a7d6d..d2608511bc 100644
--- a/docs/operator/virtualmcpserver-observability.md
+++ b/docs/operator/virtualmcpserver-observability.md
@@ -54,8 +54,8 @@ kind: VirtualMCPServer
metadata:
name: my-vmcp
spec:
- groupRef:
- name: my-group
+ config:
+ groupRef: my-group
incomingAuth:
type: anonymous
telemetry:
diff --git a/examples/operator/virtual-mcps/composite_tool_complex.yaml b/examples/operator/virtual-mcps/composite_tool_complex.yaml
index 751967c5cf..dd7f0d7f40 100644
--- a/examples/operator/virtual-mcps/composite_tool_complex.yaml
+++ b/examples/operator/virtual-mcps/composite_tool_complex.yaml
@@ -288,8 +288,8 @@ metadata:
name: vmcp-data-processor
namespace: default
spec:
- groupRef:
- name: data-processing-services
+ config:
+ groupRef: data-processing-services
incomingAuth:
type: anonymous
diff --git a/examples/operator/virtual-mcps/composite_tool_simple.yaml b/examples/operator/virtual-mcps/composite_tool_simple.yaml
index 57d2987fe5..e3e3c6a6f3 100644
--- a/examples/operator/virtual-mcps/composite_tool_simple.yaml
+++ b/examples/operator/virtual-mcps/composite_tool_simple.yaml
@@ -146,8 +146,8 @@ metadata:
name: vmcp-simple-composite
namespace: default
spec:
- groupRef:
- name: my-services
+ config:
+ groupRef: my-services
incomingAuth:
type: anonymous
diff --git a/examples/operator/virtual-mcps/composite_tool_with_elicitations.yaml b/examples/operator/virtual-mcps/composite_tool_with_elicitations.yaml
index 62154f9a8e..357ce97b91 100644
--- a/examples/operator/virtual-mcps/composite_tool_with_elicitations.yaml
+++ b/examples/operator/virtual-mcps/composite_tool_with_elicitations.yaml
@@ -203,8 +203,8 @@ metadata:
name: vmcp-interactive-deploy
namespace: default
spec:
- groupRef:
- name: deployment-services
+ config:
+ groupRef: deployment-services
incomingAuth:
type: anonymous
diff --git a/examples/operator/virtual-mcps/vmcp_conflict_resolution.yaml b/examples/operator/virtual-mcps/vmcp_conflict_resolution.yaml
index 9139e00e83..7ea0d27bac 100644
--- a/examples/operator/virtual-mcps/vmcp_conflict_resolution.yaml
+++ b/examples/operator/virtual-mcps/vmcp_conflict_resolution.yaml
@@ -100,8 +100,8 @@ metadata:
name: vmcp-prefix-strategy
namespace: default
spec:
- groupRef:
- name: my-services
+ config:
+ groupRef: my-services
incomingAuth:
type: anonymous
@@ -142,8 +142,8 @@ metadata:
name: vmcp-priority-strategy
namespace: default
spec:
- groupRef:
- name: my-services
+ config:
+ groupRef: my-services
incomingAuth:
type: anonymous
@@ -187,8 +187,8 @@ metadata:
name: vmcp-manual-strategy
namespace: default
spec:
- groupRef:
- name: my-services
+ config:
+ groupRef: my-services
incomingAuth:
type: anonymous
diff --git a/examples/operator/virtual-mcps/vmcp_inline_incoming_auth.yaml b/examples/operator/virtual-mcps/vmcp_inline_incoming_auth.yaml
index b3b0a3748c..a430edef6d 100644
--- a/examples/operator/virtual-mcps/vmcp_inline_incoming_auth.yaml
+++ b/examples/operator/virtual-mcps/vmcp_inline_incoming_auth.yaml
@@ -120,8 +120,8 @@ metadata:
name: inline-auth-vmcp
namespace: default
spec:
- groupRef:
- name: my-services
+ config:
+ groupRef: my-services
# Incoming authentication - inline OIDC configuration
incomingAuth:
diff --git a/examples/operator/virtual-mcps/vmcp_production_full.yaml b/examples/operator/virtual-mcps/vmcp_production_full.yaml
index 8593ded7b2..a977fbfd7b 100644
--- a/examples/operator/virtual-mcps/vmcp_production_full.yaml
+++ b/examples/operator/virtual-mcps/vmcp_production_full.yaml
@@ -140,8 +140,8 @@ metadata:
environment: production
spec:
# Reference to the MCPGroup containing backend MCPServers
- groupRef:
- name: production-services
+ config:
+ groupRef: production-services
# Incoming authentication (client -> vMCP)
# Using OIDC for secure authentication
diff --git a/examples/operator/virtual-mcps/vmcp_simple_discovered.yaml b/examples/operator/virtual-mcps/vmcp_simple_discovered.yaml
index ad9bab803b..cc9951a2e4 100644
--- a/examples/operator/virtual-mcps/vmcp_simple_discovered.yaml
+++ b/examples/operator/virtual-mcps/vmcp_simple_discovered.yaml
@@ -53,8 +53,8 @@ metadata:
namespace: default
spec:
# Reference to the MCPGroup containing backend MCPServers
- groupRef:
- name: my-services
+ config:
+ groupRef: my-services
# Incoming authentication (client -> vMCP)
# Using anonymous auth for simplicity - replace with OIDC in production
diff --git a/pkg/vmcp/config/config.go b/pkg/vmcp/config/config.go
index 3392833b8b..aeb05dc138 100644
--- a/pkg/vmcp/config/config.go
+++ b/pkg/vmcp/config/config.go
@@ -69,9 +69,12 @@ func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error {
// +kubebuilder:validation:Type=object
type Config struct {
// Name is the virtual MCP server name.
- Name string `json:"name" yaml:"name"`
+ // +optional
+ Name string `json:"name,omitempty" yaml:"name,omitempty"`
- // Group references the ToolHive group containing backend workloads.
+ // Group references an existing MCPGroup that defines backend workloads.
+ // In Kubernetes, the referenced MCPGroup must exist in the same namespace.
+ // +kubebuilder:validation:Required
Group string `json:"groupRef" yaml:"groupRef"`
// IncomingAuth configures how clients authenticate to the virtual MCP server.
diff --git a/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/audit-chainsaw-test.yaml b/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/audit-chainsaw-test.yaml
index 0b2ce27f48..ae24f6f2d7 100644
--- a/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/audit-chainsaw-test.yaml
+++ b/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/audit-chainsaw-test.yaml
@@ -40,8 +40,8 @@ spec:
name: test-vmcp-audit-enabled
namespace: toolhive-system
spec:
- groupRef:
- name: test-audit-group
+ config:
+ groupRef: test-audit-group
incomingAuth:
type: anonymous
audit:
@@ -88,8 +88,8 @@ spec:
name: test-vmcp-no-audit
namespace: toolhive-system
spec:
- groupRef:
- name: test-audit-group
+ config:
+ groupRef: test-audit-group
incomingAuth:
type: anonymous
- assert:
@@ -145,8 +145,8 @@ spec:
name: test-vmcp-audit-disabled
namespace: toolhive-system
spec:
- groupRef:
- name: test-audit-group
+ config:
+ groupRef: test-audit-group
incomingAuth:
type: anonymous
audit:
diff --git a/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/basic/chainsaw-test.yaml b/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/basic/chainsaw-test.yaml
index 787448057b..d25ad9464b 100644
--- a/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/basic/chainsaw-test.yaml
+++ b/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/basic/chainsaw-test.yaml
@@ -25,8 +25,8 @@ spec:
metadata:
name: test-vmcp
spec:
- groupRef:
- name: test-group
+ config:
+ groupRef: test-group
incomingAuth:
type: oidc
oidcConfig:
diff --git a/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/vmcp-controller.yaml b/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/vmcp-controller.yaml
index 1f5676fb31..05547e0585 100644
--- a/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/vmcp-controller.yaml
+++ b/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/vmcp-controller.yaml
@@ -4,8 +4,8 @@ metadata:
name: test-vmcp-controller
namespace: toolhive-system
spec:
- groupRef:
- name: test-group-controller
+ config:
+ groupRef: test-group-controller
incomingAuth:
# Using anonymous authentication for testing
type: anonymous
diff --git a/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/vmcp-with-oidc.yaml b/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/vmcp-with-oidc.yaml
index c9a853fe3b..6ee6170189 100644
--- a/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/vmcp-with-oidc.yaml
+++ b/test/e2e/chainsaw/operator/single-tenancy/test-scenarios/vmcp/vmcp-with-oidc.yaml
@@ -4,8 +4,8 @@ metadata:
name: test-vmcp-oidc
namespace: toolhive-system
spec:
- groupRef:
- name: test-group-controller
+ config:
+ groupRef: test-group-controller
incomingAuth:
type: oidc
oidcConfig:
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_aggregation_filtering_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_aggregation_filtering_test.go
index 9a36c43812..da6a55219d 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_aggregation_filtering_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_aggregation_filtering_test.go
@@ -12,6 +12,7 @@ import (
"k8s.io/apimachinery/pkg/types"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/test/e2e/images"
)
@@ -45,9 +46,7 @@ var _ = Describe("VirtualMCPServer Aggregation Filtering", Ordered, func() {
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_aggregation_overrides_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_aggregation_overrides_test.go
index 94ca911ff1..bda565dda0 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_aggregation_overrides_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_aggregation_overrides_test.go
@@ -11,6 +11,7 @@ import (
"k8s.io/apimachinery/pkg/types"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/test/e2e/images"
)
@@ -46,9 +47,7 @@ var _ = Describe("VirtualMCPServer Tool Overrides", Ordered, func() {
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_auth_discovery_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_auth_discovery_test.go
index 3d070501c6..970e798972 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_auth_discovery_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_auth_discovery_test.go
@@ -22,6 +22,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/test/e2e/images"
)
@@ -820,9 +821,7 @@ with socketserver.TCPServer(("", PORT), OIDCHandler) as httpd:
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
// OIDC incoming auth - clients must present valid OIDC tokens
// vMCP will validate tokens and then exchange them for backend-specific tokens
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_defaultresults_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_defaultresults_test.go
index e6ea3b7299..1aa6b345a8 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_defaultresults_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_defaultresults_test.go
@@ -12,6 +12,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/test/e2e/images"
)
@@ -74,9 +75,7 @@ var _ = Describe("VirtualMCPServer Composite Tool DefaultResults", Ordered, func
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_parallel_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_parallel_test.go
index 96cf678ed8..92cbaaf31c 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_parallel_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_parallel_test.go
@@ -13,6 +13,7 @@ import (
"k8s.io/apimachinery/pkg/types"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/test/e2e/images"
)
@@ -79,9 +80,7 @@ var _ = Describe("VirtualMCPServer Composite Parallel Workflow", Ordered, func()
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_referenced_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_referenced_test.go
index 6e73435b9f..a20d335eda 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_referenced_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_referenced_test.go
@@ -13,6 +13,7 @@ import (
"k8s.io/apimachinery/pkg/types"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/test/e2e/images"
)
@@ -109,9 +110,7 @@ var _ = Describe("VirtualMCPServer Composite Referenced Workflow", Ordered, func
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_sequential_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_sequential_test.go
index db868b6b32..17830c3424 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_sequential_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_composite_sequential_test.go
@@ -13,6 +13,7 @@ import (
"k8s.io/apimachinery/pkg/types"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/test/e2e/images"
)
@@ -72,9 +73,7 @@ var _ = Describe("VirtualMCPServer Composite Sequential Workflow", Ordered, func
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_conflict_resolution_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_conflict_resolution_test.go
index ad4aa1f256..96061d8ac0 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_conflict_resolution_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_conflict_resolution_test.go
@@ -12,6 +12,7 @@ import (
"k8s.io/apimachinery/pkg/types"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/test/e2e/images"
)
@@ -48,9 +49,7 @@ func setupConflictResolutionTest(setup conflictResolutionTestSetup) int32 {
Namespace: setup.namespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: setup.groupName,
- },
+ Config: vmcpconfig.Config{Group: setup.groupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_discovered_mode_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_discovered_mode_test.go
index 47c5295070..92290e7cc2 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_discovered_mode_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_discovered_mode_test.go
@@ -15,6 +15,7 @@ import (
"k8s.io/apimachinery/pkg/types"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/test/e2e/images"
)
@@ -113,9 +114,7 @@ var _ = Describe("VirtualMCPServer Discovered Mode", Ordered, func() {
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_external_auth_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_external_auth_test.go
index 6dbd96307b..a1b1303ac8 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_external_auth_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_external_auth_test.go
@@ -13,6 +13,7 @@ import (
"k8s.io/apimachinery/pkg/types"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/test/e2e/images"
)
@@ -93,9 +94,7 @@ var _ = Describe("VirtualMCPServer Unauthenticated Backend Auth", Ordered, func(
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
@@ -266,9 +265,7 @@ var _ = Describe("VirtualMCPServer Inline Unauthenticated Backend Auth", Ordered
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
@@ -448,9 +445,7 @@ var _ = Describe("VirtualMCPServer HeaderInjection Backend Auth", Ordered, func(
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
@@ -669,9 +664,7 @@ var _ = Describe("VirtualMCPServer Inline HeaderInjection Backend Auth", Ordered
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_lifecycle_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_lifecycle_test.go
index 03493cc6e8..1842cf5c67 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_lifecycle_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_lifecycle_test.go
@@ -19,6 +19,7 @@ import (
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/test/e2e/images"
)
@@ -88,9 +89,7 @@ var _ = Describe("VirtualMCPServer Lifecycle - DynamicRegistry", Ordered, Pendin
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
@@ -656,9 +655,7 @@ var _ = Describe("VirtualMCPServer K8s Manager Infrastructure", Ordered, func()
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_toolconfig_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_toolconfig_test.go
index 6604f76b49..d7a388deab 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_toolconfig_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_toolconfig_test.go
@@ -12,6 +12,7 @@ import (
"k8s.io/apimachinery/pkg/types"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/test/e2e/images"
)
@@ -67,9 +68,7 @@ var _ = Describe("VirtualMCPServer Tool Filtering via MCPToolConfig", Ordered, f
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
@@ -391,9 +390,7 @@ var _ = Describe("VirtualMCPServer MCPToolConfig Dynamic Updates", Ordered, func
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_yardstick_base_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_yardstick_base_test.go
index 64dddd737a..779e13c550 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_yardstick_base_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_yardstick_base_test.go
@@ -15,6 +15,7 @@ import (
"k8s.io/apimachinery/pkg/types"
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
+ vmcpconfig "github.com/stacklok/toolhive/pkg/vmcp/config"
"github.com/stacklok/toolhive/test/e2e/images"
)
@@ -108,9 +109,7 @@ var _ = Describe("VirtualMCPServer Yardstick Base", Ordered, func() {
Namespace: testNamespace,
},
Spec: mcpv1alpha1.VirtualMCPServerSpec{
- GroupRef: mcpv1alpha1.GroupRef{
- Name: mcpGroupName,
- },
+ Config: vmcpconfig.Config{Group: mcpGroupName},
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
Type: "anonymous",
},