diff --git a/cmd/thv-operator/api/v1alpha1/embeddingserver_types.go b/cmd/thv-operator/api/v1alpha1/embeddingserver_types.go
index 3f82b15e07..ea9e2244ba 100644
--- a/cmd/thv-operator/api/v1alpha1/embeddingserver_types.go
+++ b/cmd/thv-operator/api/v1alpha1/embeddingserver_types.go
@@ -4,6 +4,7 @@
package v1alpha1
import (
+ corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
@@ -77,7 +78,7 @@ type EmbeddingServerSpec struct {
// +listType=map
// +listMapKey=name
// +optional
- Env []EnvVar `json:"env,omitempty"`
+ Env []corev1.EnvVar `json:"env,omitempty"`
// Resources defines compute resources for the embedding server
// +optional
diff --git a/cmd/thv-operator/api/v1alpha1/mcpserver_types.go b/cmd/thv-operator/api/v1alpha1/mcpserver_types.go
index 277046e078..3dc7d0d48e 100644
--- a/cmd/thv-operator/api/v1alpha1/mcpserver_types.go
+++ b/cmd/thv-operator/api/v1alpha1/mcpserver_types.go
@@ -236,7 +236,7 @@ type MCPServerSpec struct {
// +listType=map
// +listMapKey=name
// +optional
- Env []EnvVar `json:"env,omitempty"`
+ Env []corev1.EnvVar `json:"env,omitempty"`
// Volumes are volumes to mount in the MCP server container
// +listType=map
@@ -408,7 +408,7 @@ type ProxyDeploymentOverrides struct {
// +listType=map
// +listMapKey=name
// +optional
- Env []EnvVar `json:"env,omitempty"`
+ Env []corev1.EnvVar `json:"env,omitempty"`
// ImagePullSecrets allows specifying image pull secrets for the proxy runner
// These are applied to both the Deployment and the ServiceAccount
@@ -429,15 +429,15 @@ type ResourceMetadataOverrides struct {
}
// EnvVar represents an environment variable in a container
-type EnvVar struct {
- // Name of the environment variable
- // +kubebuilder:validation:Required
- Name string `json:"name"`
-
- // Value of the environment variable
- // +kubebuilder:validation:Required
- Value string `json:"value"`
-}
+// type EnvVar struct {
+// // Name of the environment variable
+// // +kubebuilder:validation:Required
+// Name string `json:"name"`
+
+// // Value of the environment variable
+// // +kubebuilder:validation:Required
+// Value string `json:"value"`
+// }
// Volume represents a volume to mount in a container
type Volume struct {
diff --git a/cmd/thv-operator/api/v1alpha1/zz_generated.deepcopy.go b/cmd/thv-operator/api/v1alpha1/zz_generated.deepcopy.go
index e278931442..125d6d5060 100644
--- a/cmd/thv-operator/api/v1alpha1/zz_generated.deepcopy.go
+++ b/cmd/thv-operator/api/v1alpha1/zz_generated.deepcopy.go
@@ -21,9 +21,9 @@ limitations under the License.
package v1alpha1
import (
- corev1 "k8s.io/api/core/v1"
+ "k8s.io/api/core/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
- "k8s.io/apimachinery/pkg/apis/meta/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
@@ -174,7 +174,7 @@ func (in *CABundleSource) DeepCopyInto(out *CABundleSource) {
*out = *in
if in.ConfigMapRef != nil {
in, out := &in.ConfigMapRef, &out.ConfigMapRef
- *out = new(corev1.ConfigMapKeySelector)
+ *out = new(v1.ConfigMapKeySelector)
(*in).DeepCopyInto(*out)
}
}
@@ -385,8 +385,10 @@ func (in *EmbeddingServerSpec) DeepCopyInto(out *EmbeddingServerSpec) {
}
if in.Env != nil {
in, out := &in.Env, &out.Env
- *out = make([]EnvVar, len(*in))
- copy(*out, *in)
+ *out = make([]v1.EnvVar, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
}
out.Resources = in.Resources
if in.ModelCache != nil {
@@ -426,7 +428,7 @@ func (in *EmbeddingServerStatus) DeepCopyInto(out *EmbeddingServerStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]v1.Condition, len(*in))
+ *out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -464,21 +466,6 @@ func (in *EmbeddingStatefulSetOverrides) DeepCopy() *EmbeddingStatefulSetOverrid
return out
}
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *EnvVar) DeepCopyInto(out *EnvVar) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvVar.
-func (in *EnvVar) DeepCopy() *EnvVar {
- if in == nil {
- return nil
- }
- out := new(EnvVar)
- in.DeepCopyInto(out)
- return out
-}
-
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalAuthConfigRef) DeepCopyInto(out *ExternalAuthConfigRef) {
*out = *in
@@ -817,7 +804,7 @@ func (in *MCPExternalAuthConfigStatus) DeepCopyInto(out *MCPExternalAuthConfigSt
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]v1.Condition, len(*in))
+ *out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -933,7 +920,7 @@ func (in *MCPGroupStatus) DeepCopyInto(out *MCPGroupStatus) {
}
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]v1.Condition, len(*in))
+ *out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -1059,7 +1046,7 @@ func (in *MCPOIDCConfigStatus) DeepCopyInto(out *MCPOIDCConfigStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]v1.Condition, len(*in))
+ *out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -1159,7 +1146,7 @@ func (in *MCPRegistrySpec) DeepCopyInto(out *MCPRegistrySpec) {
}
if in.PGPassSecretRef != nil {
in, out := &in.PGPassSecretRef, &out.PGPassSecretRef
- *out = new(corev1.SecretKeySelector)
+ *out = new(v1.SecretKeySelector)
(*in).DeepCopyInto(*out)
}
if in.PodTemplateSpec != nil {
@@ -1184,7 +1171,7 @@ func (in *MCPRegistryStatus) DeepCopyInto(out *MCPRegistryStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]v1.Condition, len(*in))
+ *out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -1336,7 +1323,7 @@ func (in *MCPRemoteProxyStatus) DeepCopyInto(out *MCPRemoteProxyStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]v1.Condition, len(*in))
+ *out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -1474,7 +1461,7 @@ func (in *MCPServerEntryStatus) DeepCopyInto(out *MCPServerEntryStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]v1.Condition, len(*in))
+ *out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -1533,8 +1520,10 @@ func (in *MCPServerSpec) DeepCopyInto(out *MCPServerSpec) {
}
if in.Env != nil {
in, out := &in.Env, &out.Env
- *out = make([]EnvVar, len(*in))
- copy(*out, *in)
+ *out = make([]v1.EnvVar, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
}
if in.Volumes != nil {
in, out := &in.Volumes, &out.Volumes
@@ -1649,7 +1638,7 @@ func (in *MCPServerStatus) DeepCopyInto(out *MCPServerStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]v1.Condition, len(*in))
+ *out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -1770,7 +1759,7 @@ func (in *MCPTelemetryConfigStatus) DeepCopyInto(out *MCPTelemetryConfigStatus)
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]v1.Condition, len(*in))
+ *out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -1932,7 +1921,7 @@ func (in *MCPToolConfigStatus) DeepCopyInto(out *MCPToolConfigStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]v1.Condition, len(*in))
+ *out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -2272,12 +2261,14 @@ func (in *ProxyDeploymentOverrides) DeepCopyInto(out *ProxyDeploymentOverrides)
}
if in.Env != nil {
in, out := &in.Env, &out.Env
- *out = make([]EnvVar, len(*in))
- copy(*out, *in)
+ *out = make([]v1.EnvVar, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
}
if in.ImagePullSecrets != nil {
in, out := &in.ImagePullSecrets, &out.ImagePullSecrets
- *out = make([]corev1.LocalObjectReference, len(*in))
+ *out = make([]v1.LocalObjectReference, len(*in))
copy(*out, *in)
}
}
@@ -2999,7 +2990,7 @@ func (in *VirtualMCPCompositeToolDefinitionStatus) DeepCopyInto(out *VirtualMCPC
}
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]v1.Condition, len(*in))
+ *out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -3136,7 +3127,7 @@ func (in *VirtualMCPServerStatus) DeepCopyInto(out *VirtualMCPServerStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]v1.Condition, len(*in))
+ *out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
diff --git a/cmd/thv-operator/controllers/mcpremoteproxy_deployment_test.go b/cmd/thv-operator/controllers/mcpremoteproxy_deployment_test.go
index f4105195c6..482b19cc40 100644
--- a/cmd/thv-operator/controllers/mcpremoteproxy_deployment_test.go
+++ b/cmd/thv-operator/controllers/mcpremoteproxy_deployment_test.go
@@ -136,7 +136,7 @@ func TestDeploymentForMCPRemoteProxy(t *testing.T) {
"custom-annotation": "custom-annotation-value",
},
},
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "CUSTOM_ENV", Value: "custom-value"},
{Name: "TOOLHIVE_DEBUG", Value: "true"},
},
diff --git a/cmd/thv-operator/controllers/mcpserver_controller.go b/cmd/thv-operator/controllers/mcpserver_controller.go
index 68c6f96d47..f7a4a957f1 100644
--- a/cmd/thv-operator/controllers/mcpserver_controller.go
+++ b/cmd/thv-operator/controllers/mcpserver_controller.go
@@ -1149,12 +1149,7 @@ func (r *MCPServerReconciler) deploymentForMCPServer(
// Add user-specified proxy environment variables from ResourceOverrides
if m.Spec.ResourceOverrides != nil && m.Spec.ResourceOverrides.ProxyDeployment != nil {
- for _, envVar := range m.Spec.ResourceOverrides.ProxyDeployment.Env {
- env = append(env, corev1.EnvVar{
- Name: envVar.Name,
- Value: envVar.Value,
- })
- }
+ env = append(env, m.Spec.ResourceOverrides.ProxyDeployment.Env...)
}
// Add volume mounts for user-defined volumes
@@ -1762,12 +1757,7 @@ func (r *MCPServerReconciler) deploymentNeedsUpdate(
// Add user-specified environment variables
if mcpServer.Spec.ResourceOverrides != nil && mcpServer.Spec.ResourceOverrides.ProxyDeployment != nil {
- for _, envVar := range mcpServer.Spec.ResourceOverrides.ProxyDeployment.Env {
- expectedProxyEnv = append(expectedProxyEnv, corev1.EnvVar{
- Name: envVar.Name,
- Value: envVar.Value,
- })
- }
+ expectedProxyEnv = append(expectedProxyEnv, mcpServer.Spec.ResourceOverrides.ProxyDeployment.Env...)
}
// Add default environment variables that are always injected
expectedProxyEnv = ctrlutil.EnsureRequiredEnvVars(ctx, expectedProxyEnv)
diff --git a/cmd/thv-operator/controllers/mcpserver_resource_overrides_test.go b/cmd/thv-operator/controllers/mcpserver_resource_overrides_test.go
index ba6e516752..9f8d1fb61b 100644
--- a/cmd/thv-operator/controllers/mcpserver_resource_overrides_test.go
+++ b/cmd/thv-operator/controllers/mcpserver_resource_overrides_test.go
@@ -155,7 +155,7 @@ func TestResourceOverrides(t *testing.T) {
"environment": "test",
},
},
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{
Name: "HTTP_PROXY",
Value: "http://proxy.example.com:8080",
@@ -203,7 +203,7 @@ func TestResourceOverrides(t *testing.T) {
ProxyPort: 8080,
ResourceOverrides: &mcpv1alpha1.ResourceOverrides{
ProxyDeployment: &mcpv1alpha1.ProxyDeploymentOverrides{
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "TOOLHIVE_DEBUG", Value: "true"},
},
},
@@ -249,7 +249,7 @@ func TestResourceOverrides(t *testing.T) {
"version": "v1.2.3",
},
},
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{
Name: "LOG_LEVEL",
Value: "debug",
@@ -483,7 +483,7 @@ func TestDeploymentNeedsUpdateProxyEnv(t *testing.T) {
ProxyPort: 8080,
ResourceOverrides: &mcpv1alpha1.ResourceOverrides{
ProxyDeployment: &mcpv1alpha1.ProxyDeploymentOverrides{
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "HTTP_PROXY", Value: "http://proxy.example.com:8080"},
{Name: "NO_PROXY", Value: "localhost,127.0.0.1"},
},
@@ -509,7 +509,7 @@ func TestDeploymentNeedsUpdateProxyEnv(t *testing.T) {
ProxyPort: 8080,
ResourceOverrides: &mcpv1alpha1.ResourceOverrides{
ProxyDeployment: &mcpv1alpha1.ProxyDeploymentOverrides{
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "HTTP_PROXY", Value: "http://new-proxy.example.com:8080"},
{Name: "NO_PROXY", Value: "localhost,127.0.0.1"},
},
@@ -535,7 +535,7 @@ func TestDeploymentNeedsUpdateProxyEnv(t *testing.T) {
ProxyPort: 8080,
ResourceOverrides: &mcpv1alpha1.ResourceOverrides{
ProxyDeployment: &mcpv1alpha1.ProxyDeploymentOverrides{
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "HTTP_PROXY", Value: "http://proxy.example.com:8080"},
{Name: "NO_PROXY", Value: "localhost,127.0.0.1"},
{Name: "CUSTOM_ENV", Value: "custom-value"},
@@ -562,7 +562,7 @@ func TestDeploymentNeedsUpdateProxyEnv(t *testing.T) {
ProxyPort: 8080,
ResourceOverrides: &mcpv1alpha1.ResourceOverrides{
ProxyDeployment: &mcpv1alpha1.ProxyDeploymentOverrides{
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "HTTP_PROXY", Value: "http://proxy.example.com:8080"},
},
},
diff --git a/cmd/thv-operator/controllers/mcpserver_runconfig.go b/cmd/thv-operator/controllers/mcpserver_runconfig.go
index 92c1f98d1b..45f4f6dba4 100644
--- a/cmd/thv-operator/controllers/mcpserver_runconfig.go
+++ b/cmd/thv-operator/controllers/mcpserver_runconfig.go
@@ -566,7 +566,7 @@ func (*MCPServerReconciler) validateToolsFilter(config *runner.RunConfig) error
}
// convertEnvVarsFromMCPServer converts MCPServer environment variables to builder format
-func convertEnvVarsFromMCPServer(envs []mcpv1alpha1.EnvVar) map[string]string {
+func convertEnvVarsFromMCPServer(envs []corev1.EnvVar) map[string]string {
if len(envs) == 0 {
return nil
}
diff --git a/cmd/thv-operator/controllers/mcpserver_runconfig_test.go b/cmd/thv-operator/controllers/mcpserver_runconfig_test.go
index 0750c29474..9539d7f706 100644
--- a/cmd/thv-operator/controllers/mcpserver_runconfig_test.go
+++ b/cmd/thv-operator/controllers/mcpserver_runconfig_test.go
@@ -41,7 +41,7 @@ func createRunConfigTestScheme() *runtime.Scheme {
return testScheme
}
-func createTestMCPServerWithConfig(name, namespace, image string, envVars []mcpv1alpha1.EnvVar) *mcpv1alpha1.MCPServer {
+func createTestMCPServerWithConfig(name, namespace, image string, envVars []corev1.EnvVar) *mcpv1alpha1.MCPServer {
return &mcpv1alpha1.MCPServer{
ObjectMeta: metav1.ObjectMeta{
Name: name,
@@ -96,7 +96,7 @@ func TestCreateRunConfigFromMCPServer(t *testing.T) {
Image: "env-image:latest",
Transport: "sse",
ProxyPort: 9090,
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "VAR1", Value: "value1"},
{Name: "VAR2", Value: "value2"},
},
@@ -322,7 +322,7 @@ func TestCreateRunConfigFromMCPServer(t *testing.T) {
MCPPort: 8080,
ProxyMode: "streamable-http",
Args: []string{"--comprehensive", "--test"},
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "ENV1", Value: "value1"},
{Name: "ENV2", Value: "value2"},
{Name: "EMPTY_VALUE", Value: ""},
@@ -611,7 +611,7 @@ func TestDeterministicConfigMapGeneration(t *testing.T) {
ProxyPort: 9090,
MCPPort: 8080,
Args: []string{"--arg1", "--arg2", "--complex-flag=value"},
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "VAR_C", Value: "value_c"},
{Name: "VAR_A", Value: "value_a"},
{Name: "VAR_B", Value: "value_b"},
@@ -1324,7 +1324,7 @@ func TestEnsureRunConfigConfigMapCompleteFlow(t *testing.T) {
}
// Step 1: Create initial MCPServer and ConfigMap
- mcpServer := createTestMCPServerWithConfig("flow-server", "flow-ns", "test:v1", []mcpv1alpha1.EnvVar{
+ mcpServer := createTestMCPServerWithConfig("flow-server", "flow-ns", "test:v1", []corev1.EnvVar{
{Name: "ENV1", Value: "value1"},
})
@@ -1355,7 +1355,7 @@ func TestEnsureRunConfigConfigMapCompleteFlow(t *testing.T) {
// The checksum will automatically change when content changes
mcpServer.Spec.Image = "test:v2"
- mcpServer.Spec.Env = []mcpv1alpha1.EnvVar{
+ mcpServer.Spec.Env = []corev1.EnvVar{
{Name: "ENV1", Value: "value1"},
{Name: "ENV2", Value: "value2"},
}
diff --git a/cmd/thv-operator/test-integration/embedding-server/embeddingserver_creation_test.go b/cmd/thv-operator/test-integration/embedding-server/embeddingserver_creation_test.go
index efb3841a54..f177ffcc78 100644
--- a/cmd/thv-operator/test-integration/embedding-server/embeddingserver_creation_test.go
+++ b/cmd/thv-operator/test-integration/embedding-server/embeddingserver_creation_test.go
@@ -502,7 +502,7 @@ var _ = Describe("EmbeddingServer Controller Integration Tests", func() {
Model: "sentence-transformers/all-MiniLM-L6-v2",
Image: "ghcr.io/huggingface/text-embeddings-inference:latest",
Port: 8080,
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "CUSTOM_VAR_1", Value: "value1"},
{Name: "CUSTOM_VAR_2", Value: "value2"},
},
diff --git a/cmd/thv-operator/test-integration/embedding-server/embeddingserver_update_test.go b/cmd/thv-operator/test-integration/embedding-server/embeddingserver_update_test.go
index 12aecdffa3..887d9698b7 100644
--- a/cmd/thv-operator/test-integration/embedding-server/embeddingserver_update_test.go
+++ b/cmd/thv-operator/test-integration/embedding-server/embeddingserver_update_test.go
@@ -177,7 +177,7 @@ var _ = Describe("EmbeddingServer Controller Update Tests", func() {
Model: "sentence-transformers/all-MiniLM-L6-v2",
Image: "ghcr.io/huggingface/text-embeddings-inference:latest",
Port: 8080,
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "LOG_LEVEL", Value: "info"},
},
},
@@ -186,7 +186,7 @@ var _ = Describe("EmbeddingServer Controller Update Tests", func() {
{
Name: "Should update StatefulSet when env var value changes",
ApplyUpdate: func(es *mcpv1alpha1.EmbeddingServer) {
- es.Spec.Env = []mcpv1alpha1.EnvVar{
+ es.Spec.Env = []corev1.EnvVar{
{Name: "LOG_LEVEL", Value: "debug"},
}
},
@@ -205,7 +205,7 @@ var _ = Describe("EmbeddingServer Controller Update Tests", func() {
{
Name: "Should update StatefulSet when new env var is added",
ApplyUpdate: func(es *mcpv1alpha1.EmbeddingServer) {
- es.Spec.Env = []mcpv1alpha1.EnvVar{
+ es.Spec.Env = []corev1.EnvVar{
{Name: "LOG_LEVEL", Value: "debug"},
{Name: "NEW_VAR", Value: "new_value"},
}
diff --git a/cmd/thv-operator/test-integration/mcp-server/mcpserver_controller_integration_test.go b/cmd/thv-operator/test-integration/mcp-server/mcpserver_controller_integration_test.go
index 846cb3944b..3e8ed79c27 100644
--- a/cmd/thv-operator/test-integration/mcp-server/mcpserver_controller_integration_test.go
+++ b/cmd/thv-operator/test-integration/mcp-server/mcpserver_controller_integration_test.go
@@ -69,7 +69,7 @@ var _ = Describe("MCPServer Controller Integration Tests", func() {
ProxyPort: 8080,
MCPPort: 8080,
Args: []string{"--verbose"},
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{
Name: "DEBUG",
Value: "true",
@@ -113,7 +113,6 @@ var _ = Describe("MCPServer Controller Integration Tests", func() {
})
It("Should create a Deployment with proper configuration", func() {
-
// Wait for Deployment to be created
deployment := &appsv1.Deployment{}
Eventually(func() error {
@@ -229,11 +228,9 @@ var _ = Describe("MCPServer Controller Integration Tests", func() {
Expect(container.ReadinessProbe.ProbeHandler.HTTPGet.Port).To(Equal(intstr.FromString("http")))
Expect(container.ReadinessProbe.InitialDelaySeconds).To(Equal(int32(5)))
Expect(container.ReadinessProbe.PeriodSeconds).To(Equal(int32(5)))
-
})
It("Should create the RunConfig ConfigMap", func() {
-
// Wait for Service to be created (using the correct naming pattern)
configMap := &corev1.ConfigMap{}
configMapName := mcpServerName + "-runconfig"
@@ -253,7 +250,6 @@ var _ = Describe("MCPServer Controller Integration Tests", func() {
})
It("Should create a Service for the MCPServer Proxy", func() {
-
// Wait for Service to be created (using the correct naming pattern)
service := &corev1.Service{}
serviceName := "mcp-" + mcpServerName + "-proxy"
@@ -271,11 +267,9 @@ var _ = Describe("MCPServer Controller Integration Tests", func() {
Expect(service.Spec.Type).To(Equal(corev1.ServiceTypeClusterIP))
Expect(service.Spec.Ports).To(HaveLen(1))
Expect(service.Spec.Ports[0].Port).To(Equal(int32(8080)))
-
})
It("Should create RBAC resources when ServiceAccount is not specified", func() {
-
// Wait for ServiceAccount to be created
serviceAccountName := mcpServerName + "-proxy-runner"
serviceAccount := &corev1.ServiceAccount{}
@@ -320,7 +314,6 @@ var _ = Describe("MCPServer Controller Integration Tests", func() {
Expect(roleBinding.Subjects).To(HaveLen(1))
Expect(roleBinding.Subjects[0].Name).To(Equal(serviceAccountName))
Expect(roleBinding.RoleRef.Name).To(Equal(serviceAccountName))
-
})
It("Should set ObservedGeneration in status after reconciliation", func() {
@@ -359,7 +352,6 @@ var _ = Describe("MCPServer Controller Integration Tests", func() {
})
It("Should update Deployment when MCPServer spec changes", func() {
-
// Wait for Deployment to be created
deployment := &appsv1.Deployment{}
Eventually(func() error {
diff --git a/cmd/thv-operator/test-integration/mcp-server/mcpserver_runconfig_integration_test.go b/cmd/thv-operator/test-integration/mcp-server/mcpserver_runconfig_integration_test.go
index edcb62a849..f57a33caea 100644
--- a/cmd/thv-operator/test-integration/mcp-server/mcpserver_runconfig_integration_test.go
+++ b/cmd/thv-operator/test-integration/mcp-server/mcpserver_runconfig_integration_test.go
@@ -65,7 +65,7 @@ var _ = Describe("RunConfig ConfigMap Integration Tests", func() {
ProxyPort: 8080,
MCPPort: 8081,
Args: []string{"--verbose", "--debug"},
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{
Name: "DEBUG",
Value: "true",
@@ -300,7 +300,7 @@ var _ = Describe("RunConfig ConfigMap Integration Tests", func() {
// Update multiple fields
mcpServer.Spec.Image = "example/mcp-server:v2.0.0"
mcpServer.Spec.ProxyPort = 9090
- mcpServer.Spec.Env = append(mcpServer.Spec.Env, mcpv1alpha1.EnvVar{
+ mcpServer.Spec.Env = append(mcpServer.Spec.Env, corev1.EnvVar{
Name: "NEW_VAR",
Value: "new_value",
})
@@ -777,7 +777,7 @@ var _ = Describe("RunConfig ConfigMap Integration Tests", func() {
ProxyPort: 9090,
MCPPort: 8080,
Args: []string{"--arg1", "--arg2", "--arg3"},
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "VAR_C", Value: "value_c"},
{Name: "VAR_A", Value: "value_a"},
{Name: "VAR_B", Value: "value_b"},
diff --git a/docs/operator/crd-api.md b/docs/operator/crd-api.md
index 4789885ba7..f7cef87805 100644
--- a/docs/operator/crd-api.md
+++ b/docs/operator/crd-api.md
@@ -1108,7 +1108,7 @@ _Appears in:_
| `imagePullPolicy` _string_ | ImagePullPolicy defines the pull policy for the container image | IfNotPresent | Enum: [Always Never IfNotPresent]
Optional: \{\}
|
| `port` _integer_ | Port is the port to expose the embedding service on | 8080 | Maximum: 65535
Minimum: 1
|
| `args` _string array_ | Args are additional arguments to pass to the embedding inference server | | Optional: \{\}
|
-| `env` _[api.v1alpha1.EnvVar](#apiv1alpha1envvar) array_ | Env are environment variables to set in the container | | Optional: \{\}
|
+| `env` _[EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#envvar-v1-core) array_ | Env are environment variables to set in the container | | Optional: \{\}
|
| `resources` _[api.v1alpha1.ResourceRequirements](#apiv1alpha1resourcerequirements)_ | Resources defines compute resources for the embedding server | | Optional: \{\}
|
| `modelCache` _[api.v1alpha1.ModelCacheConfig](#apiv1alpha1modelcacheconfig)_ | ModelCache configures persistent storage for downloaded models
When enabled, models are cached in a PVC and reused across pod restarts | | Optional: \{\}
|
| `podTemplateSpec` _[RawExtension](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#rawextension-runtime-pkg)_ | PodTemplateSpec allows customizing the pod (node selection, tolerations, etc.)
This field accepts a PodTemplateSpec object as JSON/YAML.
Note that to modify the specific container the embedding server runs in, you must specify
the 'embedding' container name in the PodTemplateSpec. | | Type: object
Optional: \{\}
|
@@ -1155,25 +1155,6 @@ _Appears in:_
| `podTemplateMetadataOverrides` _[api.v1alpha1.ResourceMetadataOverrides](#apiv1alpha1resourcemetadataoverrides)_ | PodTemplateMetadataOverrides defines metadata overrides for the pod template | | Optional: \{\}
|
-#### api.v1alpha1.EnvVar
-
-
-
-EnvVar represents an environment variable in a container
-
-
-
-_Appears in:_
-- [api.v1alpha1.EmbeddingServerSpec](#apiv1alpha1embeddingserverspec)
-- [api.v1alpha1.MCPServerSpec](#apiv1alpha1mcpserverspec)
-- [api.v1alpha1.ProxyDeploymentOverrides](#apiv1alpha1proxydeploymentoverrides)
-
-| Field | Description | Default | Validation |
-| --- | --- | --- | --- |
-| `name` _string_ | Name of the environment variable | | Required: \{\}
|
-| `value` _string_ | Value of the environment variable | | Required: \{\}
|
-
-
#### api.v1alpha1.ExternalAuthConfigRef
@@ -2128,7 +2109,7 @@ _Appears in:_
| `proxyPort` _integer_ | ProxyPort is the port to expose the proxy runner on | 8080 | Maximum: 65535
Minimum: 1
|
| `mcpPort` _integer_ | MCPPort is the port that MCP server listens to | | Maximum: 65535
Minimum: 1
Optional: \{\}
|
| `args` _string array_ | Args are additional arguments to pass to the MCP server | | Optional: \{\}
|
-| `env` _[api.v1alpha1.EnvVar](#apiv1alpha1envvar) array_ | Env are environment variables to set in the MCP server container | | Optional: \{\}
|
+| `env` _[EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#envvar-v1-core) array_ | Env are environment variables to set in the MCP server container | | Optional: \{\}
|
| `volumes` _[api.v1alpha1.Volume](#apiv1alpha1volume) array_ | Volumes are volumes to mount in the MCP server container | | Optional: \{\}
|
| `resources` _[api.v1alpha1.ResourceRequirements](#apiv1alpha1resourcerequirements)_ | Resources defines the resource requirements for the MCP server container | | Optional: \{\}
|
| `secrets` _[api.v1alpha1.SecretRef](#apiv1alpha1secretref) array_ | Secrets are references to secrets to mount in the MCP server container | | Optional: \{\}
|
@@ -2647,7 +2628,7 @@ _Appears in:_
| `annotations` _object (keys:string, values:string)_ | Annotations to add or override on the resource | | Optional: \{\}
|
| `labels` _object (keys:string, values:string)_ | Labels to add or override on the resource | | Optional: \{\}
|
| `podTemplateMetadataOverrides` _[api.v1alpha1.ResourceMetadataOverrides](#apiv1alpha1resourcemetadataoverrides)_ | | | |
-| `env` _[api.v1alpha1.EnvVar](#apiv1alpha1envvar) array_ | Env are environment variables to set in the proxy container (thv run process)
These affect the toolhive proxy itself, not the MCP server it manages
Use TOOLHIVE_DEBUG=true to enable debug logging in the proxy | | Optional: \{\}
|
+| `env` _[EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#envvar-v1-core) array_ | Env are environment variables to set in the proxy container (thv run process)
These affect the toolhive proxy itself, not the MCP server it manages
Use TOOLHIVE_DEBUG=true to enable debug logging in the proxy | | Optional: \{\}
|
| `imagePullSecrets` _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#localobjectreference-v1-core) array_ | ImagePullSecrets allows specifying image pull secrets for the proxy runner
These are applied to both the Deployment and the ServiceAccount | | Optional: \{\}
|
diff --git a/pkg/export/k8s.go b/pkg/export/k8s.go
index e57cfda9aa..e6f58fe9bd 100644
--- a/pkg/export/k8s.go
+++ b/pkg/export/k8s.go
@@ -10,6 +10,7 @@ import (
"io"
"strings"
+ corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/yaml"
@@ -94,9 +95,9 @@ func runConfigToMCPServer(config *runner.RunConfig) (*v1alpha1.MCPServer, error)
// Convert environment variables
if len(config.EnvVars) > 0 {
- mcpServer.Spec.Env = make([]v1alpha1.EnvVar, 0, len(config.EnvVars))
+ mcpServer.Spec.Env = make([]corev1.EnvVar, 0, len(config.EnvVars))
for key, value := range config.EnvVars {
- mcpServer.Spec.Env = append(mcpServer.Spec.Env, v1alpha1.EnvVar{
+ mcpServer.Spec.Env = append(mcpServer.Spec.Env, corev1.EnvVar{
Name: key,
Value: value,
})
diff --git a/test/e2e/thv-operator/acceptance_tests/ratelimit_test.go b/test/e2e/thv-operator/acceptance_tests/ratelimit_test.go
index 09a4284c67..4140d5feac 100644
--- a/test/e2e/thv-operator/acceptance_tests/ratelimit_test.go
+++ b/test/e2e/thv-operator/acceptance_tests/ratelimit_test.go
@@ -57,7 +57,7 @@ var _ = Describe("MCPServer Rate Limiting", Ordered, func() {
Transport: "streamable-http",
ProxyPort: 8080,
MCPPort: 8080,
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "TRANSPORT", Value: "streamable-http"},
},
SessionStorage: &mcpv1alpha1.SessionStorageConfig{
@@ -149,7 +149,7 @@ var _ = Describe("MCPServer Rate Limiting", Ordered, func() {
Transport: "streamable-http",
ProxyPort: 8080,
MCPPort: 8080,
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "TRANSPORT", Value: "streamable-http"},
},
SessionStorage: &mcpv1alpha1.SessionStorageConfig{
@@ -210,7 +210,7 @@ var _ = Describe("MCPServer Rate Limiting", Ordered, func() {
Transport: "streamable-http",
ProxyPort: 8080,
MCPPort: 8080,
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "TRANSPORT", Value: "streamable-http"},
},
SessionStorage: &mcpv1alpha1.SessionStorageConfig{
diff --git a/test/e2e/thv-operator/virtualmcp/helpers.go b/test/e2e/thv-operator/virtualmcp/helpers.go
index d68614afda..614c001790 100644
--- a/test/e2e/thv-operator/virtualmcp/helpers.go
+++ b/test/e2e/thv-operator/virtualmcp/helpers.go
@@ -673,7 +673,7 @@ func CreateMCPServerAndWait(
ProxyPort: 8080,
MCPPort: 8080,
Resources: defaultMCPServerResources(),
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "TRANSPORT", Value: "streamable-http"},
},
},
@@ -707,7 +707,7 @@ type BackendConfig struct {
Transport string // defaults to "streamable-http" if empty
ExternalAuthConfigRef *mcpv1alpha1.ExternalAuthConfigRef
Secrets []mcpv1alpha1.SecretRef
- Env []mcpv1alpha1.EnvVar // additional env vars beyond TRANSPORT
+ Env []corev1.EnvVar // additional env vars beyond TRANSPORT
// Resources overrides the default resource requests/limits. When nil,
// defaultMCPServerResources() is used to ensure containers are scheduled
// with reasonable resource guarantees and do not compete excessively.
@@ -765,7 +765,7 @@ func CreateMultipleMCPServersInParallel(
ExternalAuthConfigRef: backends[idx].ExternalAuthConfigRef,
Secrets: backends[idx].Secrets,
Resources: resources,
- Env: append([]mcpv1alpha1.EnvVar{
+ Env: append([]corev1.EnvVar{
{Name: "TRANSPORT", Value: backendTransport},
}, backends[idx].Env...),
},
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 e933c8ee68..138e4988bd 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_auth_discovery_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_auth_discovery_test.go
@@ -1454,7 +1454,7 @@ var _ = Describe("Auth Config Error Handling", Ordered, func() {
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
Name: workingAuthConfigName,
},
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "TRANSPORT", Value: "streamable-http"},
},
},
@@ -1477,7 +1477,7 @@ var _ = Describe("Auth Config Error Handling", Ordered, func() {
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
Name: missingAuthConfigName,
},
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "TRANSPORT", Value: "streamable-http"},
},
},
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_circuit_breaker_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_circuit_breaker_test.go
index 5f10ab327f..2f8032ecc8 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_circuit_breaker_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_circuit_breaker_test.go
@@ -57,7 +57,7 @@ var _ = Describe("VirtualMCPServer Circuit Breaker Lifecycle", Ordered, func() {
Transport: "streamable-http",
ProxyPort: 8080,
MCPPort: 8080,
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "TRANSPORT", Value: "streamable-http"},
},
},
@@ -76,7 +76,7 @@ var _ = Describe("VirtualMCPServer Circuit Breaker Lifecycle", Ordered, func() {
Transport: "streamable-http",
ProxyPort: 8080,
MCPPort: 8080,
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "TRANSPORT", Value: "streamable-http"},
},
},
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 fd1d73e47c..f71dabe4a0 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_external_auth_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_external_auth_test.go
@@ -835,7 +835,7 @@ var _ = Describe("VirtualMCPServer Health Check with HeaderInjection Auth", Orde
Transport: "streamable-http",
ProxyPort: 8080,
MCPPort: 8080,
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "TRANSPORT", Value: "streamable-http"},
},
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
@@ -1051,7 +1051,7 @@ var _ = Describe("VirtualMCPServer Health Check with TokenExchange Auth", Ordere
Transport: "streamable-http",
ProxyPort: 8080,
MCPPort: 8080,
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "TRANSPORT", Value: "streamable-http"},
},
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_optimizer_multibackend_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_optimizer_multibackend_test.go
index 5b2f72a09f..b5bd9d3d08 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_optimizer_multibackend_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_optimizer_multibackend_test.go
@@ -91,7 +91,7 @@ var _ = Describe("VirtualMCPServer Optimizer Multi-Backend", Ordered, func() {
Name: backend5Name, Namespace: testNamespace, GroupRef: mcpGroupName,
Image: images.TerraformMCPServerImage, // 9 tools
Transport: "streamable-http",
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "TRANSPORT_MODE", Value: "streamable-http"},
{Name: "TRANSPORT_HOST", Value: "0.0.0.0"},
},
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_telemetry_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_telemetry_test.go
index 61f01c6904..74e937e405 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_telemetry_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_telemetry_test.go
@@ -47,7 +47,7 @@ var _ = Describe("VirtualMCPServer Telemetry Config", Ordered, func() {
Transport: "streamable-http",
ProxyPort: 8080,
MCPPort: 8080,
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "TRANSPORT", Value: "streamable-http"},
},
},
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 4273a67cac..a0f849481b 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_yardstick_base_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_yardstick_base_test.go
@@ -13,6 +13,7 @@ import (
"github.com/mark3labs/mcp-go/mcp"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
+ corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
@@ -51,7 +52,7 @@ var _ = Describe("VirtualMCPServer Yardstick Base", Ordered, func() {
Transport: "streamable-http",
ProxyPort: 8080,
MCPPort: 8080,
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "TRANSPORT", Value: "streamable-http"},
},
},
@@ -69,7 +70,7 @@ var _ = Describe("VirtualMCPServer Yardstick Base", Ordered, func() {
Transport: "streamable-http",
ProxyPort: 8080,
MCPPort: 8080,
- Env: []mcpv1alpha1.EnvVar{
+ Env: []corev1.EnvVar{
{Name: "TRANSPORT", Value: "streamable-http"},
},
},