Chapter 2. Deploy isolated MCP gateway instances
You can deploy multiple MCP gateway instances within a single cluster to isolate traffic between teams. Each instance uses a single MCPGatewayExtension custom resource (CR) to manage associated MCP servers.
MCP gateway is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. Red Hat does not recommend using them in production. These features offer early access to upcoming product features, enabling customers to test functionality and give feedback during the development process.
For more information about the support scope of Red Hat Technology Preview features, see Technology Preview Features Support Scope.
2.1. How isolated MCP gateway deployment works Copy linkLink copied to clipboard!
By using isolated MCP gateway deployments, different teams can manage their own Model Context Protocol (MCP) servers independently. Each isolated MCP gateway deployment uses a single MCPGatewayExtension custom resource (CR).
You can deploy more than one MCP gateway instance within a single cluster by using more than one Gateway CR. You must use one MCPGatewayExtension CR for each Gateway CR.
Each deployment of the MCP gateway manages its associated MCP servers by using the MCPGatewayExtension CR in the following ways:
-
Defines which
Gatewayobject the MCP gateway instance is responsible for. -
Determines where configuration
Secretobjects are created. -
Enables isolation by allowing multiple MCP gateway instances in different namespaces to target different
Gatewayobjects.
For example, Team A and Team B share a single, cluster-wide MCP gateway controller. Each team namespace has a different Gateway object, uses different Secrets, and has different MCPServerRegistration CRs.
- Team A namespace
-
MCPGatewayExtensionCR targetingGatewayA - MCP broker and router
- Config Secret
-
MCPServerRegistrationCRs
-
- Team B namespace
-
MCPGatewayExtensionCR targetingGatewayB - MCP broker and router
- Config Secret
-
MCPServerRegistrationCRs
-
2.1.1. Important considerations Copy linkLink copied to clipboard!
- One
MCPGatewayExtensionCR per namespace -
Each namespace can have only one
MCPGatewayExtensionCR. The controller writes configuration to a well-knownSecretobject name. More than one extension in the same namespace causes them to overwrite each other. - One
MCPGatewayExtensionCR perGatewayobject and listener -
Only one
MCPGatewayExtensionCR can target a specified listener for a givenGatewayobject. When more than one extension targets the sameGatewayobject, the controller marks newer ones asReady: False, with a message starting with `conflict: `. The oldest extension by creation timestamp takes precedence. - Cross-namespace
Gatewayobject references require aReferenceGrantCR -
The
ReferenceGrantCR must exist in the targetGatewayobject namespace.
2.2. Deploy isolated MCP gateway instances Copy linkLink copied to clipboard!
You can deploy more than one isolated MCP gateway instance, each with its own Gateway object, MCPGatewayExtension custom resource (CR), and ReferenceGrant CR. To get started, create an isolated instance for a team. Repeat this procedure for each team that you need to isolate.
Prerequisites
- You installed OpenShift Container Platform.
-
You installed OpenShift CLI (
oc). - You installed the MCP gateway in a cluster-central namespace.
-
You configured at least one listener on the
Gatewayobject applied in your central namespace. - You set up multi-tenancy on your OpenShift Container Platform cluster.
Procedure
Get the hostname for Team A by running the following command:
$ echo "team-a.apps.$(oc get dns cluster -o jsonpath='{.spec.baseDomain}')"Create a team
Gatewayobject for Team A by using the following example:apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: <team_a_mcp_gateway> namespace: <gateway_system> spec: gatewayClassName: openshift-default listeners: - name: mcp hostname: <team_a_hostname> port: 443 protocol: HTTPS allowedRoutes: namespaces: from: All tls: certificateRefs: - group: '' kind: Secret name: default-ingress-cert mode: Terminate-
Replace the
metadata.namevalue with the name you want to use. -
If you want your central platform team to manage network infrastructure, TLS certificates, and public IP address allocations, use the same value for
metadata.namespaceas the cluster-wideGatewayobject. -
If you want Team A to own everything from the network entry point to their MCP server pods, apply the
Gatewayobject directly inside<team_a>in themetadata.namespaceparameter. -
Replace the value of
spec.listeners.hostnamewith the hostname for Team A.
-
Replace the
Apply the
GatewayCR by running the following command:$ oc apply -f <team_a_mcp_gateway.yaml>Replace
<team_a_mcp_gateway.yaml>with the filename you used.Verify the Team A
Gatewayobject by running the following command:$ oc get gateway <team_a_mcp_gateway> -n <gateway_system>-
Replace with the Team A
Gatewayobject name. -
Replace with the namespace where the Team A
Gatewayobject is applied.
-
Replace with the Team A
Create an
MCPGatewayExtensionCR for Team A to associate the namespace with the teamGatewayobject by using the following example:apiVersion: mcp.kuadrant.io/v1alpha1 kind: MCPGatewayExtension metadata: name: <team_a_mcp_gateway_ext> namespace: <team_a> spec: targetRef: group: gateway.networking.k8s.io kind: Gateway name: <team_a_mcp_gateway> namespace: <gateway_system> sectionName: mcp-
Replace the
metadata.namevalue with the name you want to use. -
Replace the
metadata.namespacevalue with the team namespace. -
Replace the
spec.targetRef.namevalue with the name of the teamGatewayobject. Replace the
spec.targetRef.namespacevalue with the name of theGatewayobject namespace.ImportantYou can create several
Gatewayobjects in the same namespace, but you must only reference oneGatewayobject one time in yourMCPGatewayExtensionCRs.
-
Replace the
Apply the
MCPGatewayExtensionCR by running the following command:$ oc apply -f <team_a_mcp_gateway_ext.yaml>Replace
<team_a_mcp_gateway_ext.yaml>with the filename you used.If you are using the central
Gatewayobject namespace, create aReferenceGrantCR in theGatewayobject namespace by using the following example:apiVersion: gateway.networking.k8s.io/v1beta1 kind: ReferenceGrant metadata: name: _<team_a_ref_grant>_ namespace: _<gateway_system>_ spec: from: - group: mcp.kuadrant.io kind: MCPGatewayExtension namespace: _<team_a>_ to: - group: gateway.networking.k8s.io kind: Gateway name: _<team_a_mcp_gateway>_-
Replace the
metadata.namevalue with the name you want to use. -
Replace the
metadata.namespacevalue with the namespace where yourGatewayobject is applied. -
Replace the
spec.from.namespacevalue with the team namespace. -
Replace the
spec.to.namevalue with the teamGatewayobject name.
-
Replace the
Apply the
ReferenceGrantCR by running the following command:$ oc apply -f <team_a_ref_grant.yaml>Replace
<team_a_ref_grant.yaml>with the filename you used.Verify the team
MCPGatewayExtensionCR by running the following command:$ oc wait --for=condition=Ready mcpgatewayextension/<team_a_mcp_gateway_ext> -n <team_a> --timeout=60s-
Replace
<team_a_mcp_gateway_ext>with the name of the extension. -
Replace
<team_a>with the team namespace.
-
Replace
Verify that a pod prefixed
mcp-gateway-in the team namespace is running by using the following command:$ oc get pods -n <team_a>-
Replace
<team_a>with the team namespace.
-
Replace
Next steps
-
Repeat the steps for additional teams by creating the namespace,
Gatewayobject,MCPGatewayExtensionCR, andReferenceGrantCR with the relevant team values. For example, "Team B", and so on.
2.3. Expose isolated MCP gateway instances externally Copy linkLink copied to clipboard!
After you deploy isolated MCP gateway instances, you can expose each Gateway object externally by creating OpenShift Container Platform routes with TLS termination. Repeat these steps for each team.
Prerequisites
- You installed OpenShift Container Platform.
-
You installed OpenShift CLI (
oc). - You deployed an isolated MCP gateway instance for a team.
Procedure
Create an OpenShift Container Platform route for the Team A
Gatewayobject by using the following example:apiVersion: route.openshift.io/v1 kind: Route metadata: name: <team_a_route> namespace: <gateway_system> spec: host: <team_a_host> tls: insecureEdgeTerminationPolicy: Redirect termination: edge port: targetPort: mcp to: kind: Service name: <team_a_mcp_gateway>-openshift-default weight: 100 wildcardPolicy: None-
Replace the
metadata.namevalue with the route name that you want to use. -
Replace the
metadata.namespacevalue with the namespace where theGatewayobject is applied. -
Replace the value of
spec.hostwith the hostname for the team you are making the route for. -
Replace the value of
spec.to.namewith theGatewayobject name andgatewayClassNamevalue.
-
Replace the
Apply the CR by running the following command:
$ oc apply -f <team_a_route.yaml>Replace
<team_a_route.yaml>with the name that you used for yourRouteCR.Verify that the router has successfully admitted the route and mapped it to active endpoints by running the following command:
$ oc describe route <team_a_route> -n <gateway_system>-
Replace
<team_a_route>with the name of the route. -
Replace
<gateway_system>with the namespace where theGatewayobject is applied.
-
Replace
Next steps
Register MCP servers with each Gateway object. When registering MCP servers, ensure that each HTTPRoute CR parentRef targets the correct Gateway object, for example:
-
Team A instance:
team_a_gatewayin thegateway_systemnamespace.