Skip to content
Open
8 changes: 4 additions & 4 deletions cmd/thv-operator/api/v1alpha1/mcpserver_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ type MCPServerSpec struct {
// +kubebuilder:default=stdio
Transport string `json:"transport,omitempty"`

// Port is the port to expose the MCP server on
// ProxyPort is the port to expose the proxy runner on
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=65535
// +kubebuilder:default=8080
Port int32 `json:"port,omitempty"`
ProxyPort int32 `json:"proxyPort,omitempty"`

// TargetPort is the port that MCP server listens to
// McpPort is the port that MCP server listens to
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=65535
// +optional
TargetPort int32 `json:"targetPort,omitempty"`
McpPort int32 `json:"mcpPort,omitempty"`

// Args are additional arguments to pass to the MCP server
// +optional
Expand Down
30 changes: 15 additions & 15 deletions cmd/thv-operator/controllers/mcpserver_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ func (r *MCPServerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (

// Update the MCPServer status with the service URL
if mcpServer.Status.URL == "" {
mcpServer.Status.URL = createServiceURL(mcpServer.Name, mcpServer.Namespace, mcpServer.Spec.Port)
mcpServer.Status.URL = createServiceURL(mcpServer.Name, mcpServer.Namespace, mcpServer.Spec.ProxyPort)
err = r.Status().Update(ctx, mcpServer)
if err != nil {
ctxLogger.Error(err, "Failed to update MCPServer status")
Expand Down Expand Up @@ -463,13 +463,13 @@ func (r *MCPServerReconciler) deploymentForMCPServer(ctx context.Context, m *mcp

// Prepare container args
args := []string{"run", "--foreground=true"}
args = append(args, fmt.Sprintf("--proxy-port=%d", m.Spec.Port))
args = append(args, fmt.Sprintf("--proxy-port=%d", m.Spec.ProxyPort))
args = append(args, fmt.Sprintf("--name=%s", m.Name))
args = append(args, fmt.Sprintf("--transport=%s", m.Spec.Transport))
args = append(args, fmt.Sprintf("--host=%s", getProxyHost()))

if m.Spec.TargetPort != 0 {
args = append(args, fmt.Sprintf("--target-port=%d", m.Spec.TargetPort))
if m.Spec.McpPort != 0 {
args = append(args, fmt.Sprintf("--target-port=%d", m.Spec.McpPort))
}

// Generate pod template patch for secrets and merge with user-provided patch
Expand Down Expand Up @@ -510,7 +510,7 @@ func (r *MCPServerReconciler) deploymentForMCPServer(ctx context.Context, m *mcp
// Add OAuth discovery resource URL for RFC 9728 compliance
resourceURL := m.Spec.OIDCConfig.ResourceURL
if resourceURL == "" {
resourceURL = createServiceURL(m.Name, m.Namespace, m.Spec.Port)
resourceURL = createServiceURL(m.Name, m.Namespace, m.Spec.ProxyPort)
}
args = append(args, fmt.Sprintf("--resource-url=%s", resourceURL))
}
Expand Down Expand Up @@ -720,7 +720,7 @@ func (r *MCPServerReconciler) deploymentForMCPServer(ctx context.Context, m *mcp
VolumeMounts: volumeMounts,
Resources: resources,
Ports: []corev1.ContainerPort{{
ContainerPort: m.Spec.Port,
ContainerPort: m.Spec.ProxyPort,
Name: "http",
Protocol: corev1.ProtocolTCP,
}},
Expand Down Expand Up @@ -859,8 +859,8 @@ func (r *MCPServerReconciler) serviceForMCPServer(m *mcpv1alpha1.MCPServer) *cor
Spec: corev1.ServiceSpec{
Selector: ls, // Keep original labels for selector
Ports: []corev1.ServicePort{{
Port: m.Spec.Port,
TargetPort: intstr.FromInt(int(m.Spec.Port)),
Port: m.Spec.ProxyPort,
TargetPort: intstr.FromInt(int(m.Spec.ProxyPort)),
Protocol: corev1.ProtocolTCP,
Name: "http",
}},
Expand Down Expand Up @@ -1004,7 +1004,7 @@ func (r *MCPServerReconciler) deploymentNeedsUpdate(deployment *appsv1.Deploymen
}

// Check if the port has changed
portArg := fmt.Sprintf("--proxy-port=%d", mcpServer.Spec.Port)
portArg := fmt.Sprintf("--proxy-port=%d", mcpServer.Spec.ProxyPort)
found = false
for _, arg := range container.Args {
if arg == portArg {
Expand Down Expand Up @@ -1057,7 +1057,7 @@ func (r *MCPServerReconciler) deploymentNeedsUpdate(deployment *appsv1.Deploymen
}

// Check if the container port has changed
if len(container.Ports) > 0 && container.Ports[0].ContainerPort != mcpServer.Spec.Port {
if len(container.Ports) > 0 && container.Ports[0].ContainerPort != mcpServer.Spec.ProxyPort {
return true
}

Expand Down Expand Up @@ -1137,12 +1137,12 @@ func (r *MCPServerReconciler) deploymentNeedsUpdate(deployment *appsv1.Deploymen
return true
}

// Check if the targetPort has changed
if mcpServer.Spec.TargetPort != 0 {
targetPortArg := fmt.Sprintf("--target-port=%d", mcpServer.Spec.TargetPort)
// Check if the mcpPort has changed
if mcpServer.Spec.McpPort != 0 {
mcpPortArg := fmt.Sprintf("--target-port=%d", mcpServer.Spec.McpPort)
found := false
for _, arg := range container.Args {
if arg == targetPortArg {
if arg == mcpPortArg {
found = true
break
}
Expand Down Expand Up @@ -1204,7 +1204,7 @@ func (r *MCPServerReconciler) deploymentNeedsUpdate(deployment *appsv1.Deploymen
// serviceNeedsUpdate checks if the service needs to be updated
func serviceNeedsUpdate(service *corev1.Service, mcpServer *mcpv1alpha1.MCPServer) bool {
// Check if the service port has changed
if len(service.Spec.Ports) > 0 && service.Spec.Ports[0].Port != mcpServer.Spec.Port {
if len(service.Spec.Ports) > 0 && service.Spec.Ports[0].Port != mcpServer.Spec.ProxyPort {
return true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8697,9 +8697,9 @@ spec:
- containers
type: object
type: object
port:
proxyPort:
default: 8080
description: Port is the port to expose the MCP server on
description: ProxyPort is the port to expose the proxy runner on
format: int32
maximum: 65535
minimum: 1
Expand Down Expand Up @@ -8831,8 +8831,8 @@ spec:
ServiceAccount is the name of an already existing service account to use by the MCP server.
If not specified, a ServiceAccount will be created automatically and used by the MCP server.
type: string
targetPort:
description: TargetPort is the port that MCP server listens to
mcpPort:
description: McpPort is the port that MCP server listens to
format: int32
maximum: 65535
minimum: 1
Expand Down
4 changes: 2 additions & 2 deletions deploy/keycloak/mcpserver-with-auth.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ spec:
- name: INSECURE_DISABLE_URL_VALIDATION
value: "true"
transport: streamable-http
port: 9090
targetPort: 9090
proxyPort: 9090
mcpPort: 9090
env:

# OIDC authentication with Keycloak
Expand Down
4 changes: 2 additions & 2 deletions examples/operator/mcp-servers/mcpserver_fetch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ metadata:
spec:
image: ghcr.io/stackloklabs/gofetch/server
transport: streamable-http
port: 8080
targetPort: 8080
proxyPort: 8080
mcpPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ spec:
transport: streamable-http
tools:
- fetch
port: 8080
targetPort: 8080
proxyPort: 8080
mcpPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
2 changes: 1 addition & 1 deletion examples/operator/mcp-servers/mcpserver_github.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
spec:
image: ghcr.io/github/github-mcp-server
transport: stdio
port: 8080
proxyPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
2 changes: 1 addition & 1 deletion examples/operator/mcp-servers/mcpserver_mkp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ spec:
image: ghcr.io/stackloklabs/mkp/server
transport: streamable-http
targetPort: 8080
port: 8080
proxyPort: 8080
args:
# Change to true for read-write access.
- --read-write=false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ metadata:
spec:
image: docker.io/mcp/fetch
transport: stdio
port: 8080
proxyPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
spec:
image: docker.io/mcp/fetch
transport: stdio
port: 8080
proxyPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
spec:
image: docker.io/mcp/fetch
transport: stdio
port: 8080
proxyPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ metadata:
spec:
image: ghcr.io/stackloklabs/mcp-fetch:latest
transport: sse
port: 8080
proxyPort: 8080
# Example of using the PodTemplateSpec to customize the pod
podTemplateSpec:
spec:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
spec:
image: docker.io/mcp/github
transport: stdio
port: 8080
proxyPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
4 changes: 2 additions & 2 deletions examples/operator/mcp-servers/mcpserver_yardstick_sse.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ spec:
env:
- name: TRANSPORT
value: sse
port: 8080
targetPort: 8080
proxyPort: 8080
mcpPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
spec:
image: ghcr.io/stackloklabs/yardstick/yardstick-server:0.0.2
transport: stdio
port: 8080
proxyPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ spec:
env:
- name: TRANSPORT
value: streamable-http
port: 8080
targetPort: 8080
proxyPort: 8080
mcpPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ spec:
env:
- name: TRANSPORT
value: sse
port: 8080
targetPort: 8080
proxyPort: 8080
mcpPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
spec:
image: ghcr.io/stackloklabs/yardstick/yardstick-server:0.0.2
transport: stdio
port: 8080
proxyPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ spec:
env:
- name: TRANSPORT
value: streamable-http
port: 8080
targetPort: 8080
proxyPort: 8080
mcpPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ spec:
env:
- name: TRANSPORT
value: sse
port: 8080
targetPort: 8080
proxyPort: 8080
mcpPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
spec:
image: ghcr.io/stackloklabs/yardstick/yardstick-server:0.0.2
transport: stdio
port: 8080
proxyPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ spec:
env:
- name: TRANSPORT
value: streamable-http
port: 8080
targetPort: 8080
proxyPort: 8080
mcpPort: 8080
permissionProfile:
type: builtin
name: network
Expand Down
Loading