Chapter 1. Installing and configuring MCP gateway
You can get started with the MCP gateway by installing the Operator by using Operator Lifecycle Manager (OLM), and then continuing to set up connections by applying the custom resources that you require.
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 provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.
For more information about the support scope of Red Hat Technology Preview features, see Technology Preview Features Support Scope.
1.1. Installing the MCP gateway with OLM Copy linkLink copied to clipboard!
You can install the MCP gateway deployment Operator by using Operator Lifecycle Manager (OLM) with the CLI. When choosing this path, you must create a MCPGatewayExtension custom resources (CR) manually and apply it to complete your initial setup.
Prerequisites
- You installed OpenShift Container Platform.
-
You installed OpenShift CLI (
oc).
Procedure
Create the namespace where you want to install MCP gateway by running the following command:
$ oc create ns <mcp_system>Replace the default
<mcp_system>with the namespace you want to use.Create and apply the MCP gateway
SubscriptionandOperatorGroupcustom resources (CRs) by running the following command:$ oc apply -n <mcp_system> -f - <<EOF apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: mcp-gateway spec: source: redhat-operators sourceNamespace: openshift-marketplace name: mcp-gateway channel: preview --- apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: mcp-gateway spec: targetNamespaces: - <mcp_system> EOFReplace
<mcp_system>with the namespace you used in the earlier step.Confirm that the MCP gateway installation has finished by running the following commands:
$ oc wait --for=jsonpath={.status.installPlanRef.name} subscription mcp-gateway -n <mcp_system> --timeout=10s ip=$(oc get subscription mcp-gateway -n <mcp_system> -o=jsonpath={.status.installPlanRef.name})Replace
<mcp_system>with the namespace you used in the earlier step.$ oc wait --for=condition=Installed installplan -n <mcp_system> ${ip} --timeout=60s-
Replace
<mcp_system>with the namespace you used in the earlier step. -
Expect the status of
installplan.operators.coreos.com/install-<suffix>when MCP gateway is ready. The name of the install plan has a random suffix, for example,4rql7.
-
Replace
Verification
Wait for the controller to be ready by running the following command:
$ oc wait csv -n <mcp_system> -l operators.coreos.com/mcp-gateway.<mcp_system>="" --for=jsonpath='{.status.phase}'=Succeeded --timeout=5mReplace
<mcp_system>with the namespace you used.
Next steps
-
Configure a listener for your
Gatewayobject. -
Create a
ReferenceGrantCR if you require cross-namespace referencing. -
Deploy the MCP gateway by creating an
MCPGatewayExtensionCR. - Configure authentication and authorization for your connections.
-
Create
MCPServerRegistrationCRs to register your MCP servers.
1.2. Creating a Gateway object for your MCP gateway Copy linkLink copied to clipboard!
You must create a Gateway object and configure listeners to create pods to handle your traffic, assign IP addresses, and give HTTP routes a place to connect.
You can attach your Red Hat Connectivity Link DNSPolicy CR to your Gateway object to automatically map your hostnames to your Gateway object’s IP address. Point your DNSPolicy CR to your Gateway object by name in the targetRef: section. The DNSPolicy CR must reside in the same namespace as the Gateway object.
Prerequisites
- You installed OpenShift Container Platform.
-
You installed OpenShift CLI (
oc). - You installed the MCP gateway Operator.
Procedure
Create a
Gatewayobject by using the following example as a template:Example Gateway CR with listeners
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: mcp-gateway namespace: gateway-namespace spec: gatewayClassName: openshift-default listeners: - name: http port: 80 protocol: HTTP allowedRoutes: namespaces: from: All - name: mcps hostname: mcp.example.com port: 8080 protocol: HTTP allowedRoutes: namespaces: from: All - name: https hostname: mcp.apps.openshift.example.com port: 443 protocol: HTTPS allowedRoutes: namespaces: from: All tls: certificateRefs: - group: '' kind: Secret name: default-ingress-cert mode: Terminate-
The custom resource (CR) is a
Gatewaynamedmcp-gatewaythat exists in thegateway-namespacenamespace and has three listeners configured. On OpenShift Container Platform, the
spec.listeners.tls.certificateRefs:value can specify theSecretCR containing the default wildcard certificate for the OpenShift Ingress controller.ImportantYou must use the
spec.listeners[].namevalue in the correspondingMCPGatewayExtensionCRspec.targetRef.sectionName:field.Optional. Verify the Connectivity Link
DNSPolicyCR attachment by checking its status with the following command:$ oc get dnspolicy <mcp_dns_policy> -n <gateway_namespace> -o wide
-
Replace
<mcp_dns_policy>with the name of your Connectivity LinkDNSPolicyCR. Replace
<gateway_namespace>with theGatewayobject namespace.Example output
ACCEPTED: True
1.3. Configuring MCP gateway listeners Copy linkLink copied to clipboard!
Connect your MCP gateway to your agentic AI systems by appending your Gateway custom resource (CR) with your MCP listener information. The MCP listener handles the transport protocol, opens an MCP session on the port, and establishes a security perimeter. You can also add listeners for unencrypted web traffic and secured traffic.
Prerequisites
- You are logged in to your OpenShift Container Platform cluster.
- You created a gateway custom resource (CR).
- You installed MCP gateway.
- You configured a gateway API provider.
-
Optional. If you are adding a secure listener, you have a TLS certificate to reference. The certificate must be in the same namespace as the
GatewayCR.
Procedure
Add an MCP gateway listener to your
GatewayCR by appending it with the following command:$ $ oc patch gateway <mcp_gateway> -n <gateway_namespace> --type='json' -p='[ { "op": "add", "path": "/spec/listeners/-", "value": { "name": "mcps", "hostname": "<mcp.example.com>", "port": 8080, "protocol": "HTTP", "allowedRoutes": { "namespaces": { "from": "All" } } } } ]'-
Replace
<mcp_gateway>with the name of your MCP gateway. -
Replace
<gateway_namespace>with the namespace where yourGatewayobject is applied. -
Replace
<mcp.example.com>with the hostname you want to use.
-
Replace
Verify that your listener is working by running the following command:
$ oc get gateway <mcp_gateway> -n <gateway_namespace> -o yaml-
Replace
<mcp_gateway>with the name of your MCP gateway deployment. -
Replace
<gateway_namespace>with the namespace where yourGatewayobject is applied. -
The conditions
Accepted: TrueandProgrammed: Trueare expected in thestatusof the output.
-
Replace
Add a standard web traffic listener to your
GatewayCR by appending it with the following command:$ oc patch gateway <mcp_gateway> -n <gateway_namespace> --type='json' -p='[ { "op": "add", "path": "/spec/listeners/-", "value": { "name": "http-web", "port": 80, "protocol": "HTTP", "allowedRoutes": { "namespaces": { "from": "All" } } } } ]'-
Replace
<mcp_gateway>with the name of your MCP gateway. -
Replace
<gateway_namespace>with the namespace where yourGatewayobject is applied. -
The
listener.namevalue must be a unique name within theGatewayobject. In this example,http-webis used. -
The
listener.port: 80,is the standard port for unencrypted web traffic. -
You can add a
hostnameif you want to limit incoming domain names.
-
Replace
Add a secure listener to your
GatewayCR by appending it with the following command:$ oc patch gateway <mcp_gateway> -n <gateway_namespace> --type='json' -p='[ { "op": "add", "path": "/spec/listeners/-", "value": { "name": "https", "hostname": "<mcp.example.com>", "port": 443, "protocol": "HTTPS", "tls": { "mode": "Terminate", "certificateRefs": [ { "name": "mcp-tls-secret", "kind": "Secret" } ] }, "allowedRoutes": { "namespaces": { "from": "All" } } } } ]'-
Replace
<mcp_gateway>with the name of your MCP gateway deployment. -
Replace
<gateway_namespace>with the namespace where yourGatewayobject is applied. -
Replace
<mcp.example.com>with the hostname you are targeting. -
The
spec.listeners.tls.certificateRefs.name:parameter specifies the name of your secret. This example usesmcp-tls-secret. -
The
spec.listeners.tls.mode: Terminatevalue means that the gateway decrypts the traffic and sends it as plain text to your MCP server. You can specify the mode that you require. -
You must set a
spec.listeners.hostnameso that the relevant certificate is presented to the correct client.
-
Replace
Check that your certificates are properly linked by running the following command:
$ oc get gateway <mcp_gateway> -n <gateway_namespace> -o jsonpath='{.status.listeners[?(@.name=="https")]}'-
Replace
<mcp_gateway>with the name of your MCP gateway deployment. -
Replace
<gateway_namespace>with the namespace where yourGatewayobject is applied. -
The
statusmessage outputs any errors.
-
Replace
Verification
Check the status your listeners and related objects by running the following command:
$ oc describe gateway <mcp_gateway> -n <gateway_namespace>-
Replace
<mcp_gateway>with the name of your MCP gateway deployment. Replace
<gateway_namespace>with the namespace where yourGatewayobject is applied.Example output
# ... Status: Listeners: - Name: http-web Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Conditions: Last Transition Time: 2026-04-01T... Message: None Reason: Programmed Status: True Type: Programmed - Name: https Conditions: Reason: ResolvedRefs Status: True Type: ResolvedRefs # ... Events: Type Reason Age From Message Normal Synced 12m gateway-api-controller Successfully synced Gateway configuration Normal IPAllocated 11m mcp-operator Assigned IP 192.168.1.100 to Gateway Normal ListenerAccepted 10m gateway-api-controller Listener "http-web" accepted Normal Programmed 10m gateway-api-controller Gateway has been successfully programmed # ...-
The
Eventssection of the output can also show port conflicts, problems with yourgatewayClassName:value, missing routes, and a lack of permissions to read secrets.
-
Replace
1.4. Understanding the MCPGatewayExtension custom resource Copy linkLink copied to clipboard!
You can deploy multiple MCP gateway instances within a single cluster by using more than one Gateway object, and an MCPGatewayExtension custom resource (CR) for each defined gateway. Each deployment of the MCP gateway manages its associated MCP servers by using the MCPGatewayExtension controller 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.
Each namespace can only have one MCPGatewayExtension CR. Each Gateway object can have only one MCPGatewayExtension CR. If more than one MCPGatewayExtension CR targets the same Gateway object, the controller marks newer ones as conflicted. The oldest MCPGatewayExtension CR wins.
- Automatic route creation
The
MCPGatewayExtensioncontroller automatically creates anHTTPRouteCR namedmcp-gateway-route. The automatically createdHTTPRouteCR has the following characteristics:-
Routes
/mcptraffic to themcp-gatewaybroker service on port8080 -
Uses the
hostnamefrom theGatewaylistener. Wildcards such as*.example.combecomemcp.example.com -
References the target gateway with the correct
sectionName -
Is owned by the
MCPGatewayExtensioncontroller and is cleaned up automatically if the controller is deleted
-
Routes
- Custom route creation
-
If you require custom route, you can disable automatic
HTTPRouteCR creation by setting thespec.httpRouteManagement:parameter toDisabledin yourMCPGatewayExtensionCR. After you create theMCPGatewayExtensionCR, you can create a customHTTPRouteCR.
1.4.1. Automatically created HTTPRoute example Copy linkLink copied to clipboard!
Applying the MCPGatewayExtension custom resources (CR) generates an automatic HTTPRoute CR. The following is an example of the route.
Example automatically generated HTTPRoute CR
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: mcp-gateway-route
namespace: mcp-gateway-namespace
spec:
parentRefs:
- name: mcp-gateway
namespace: istio-system
sectionName: mcp
rules:
- matches:
- path:
type: PathPrefix
value: /mcp
backendRefs:
- name: mcp-gateway
port: 8080
-
The value of the
spec.parentRefs.name:parameter matches yourGatewayCR name. -
The value of the
spec.parentRefs.namespace:parameter matches yourGatewaynamespace. -
The value of the
spec.parentRefs.sectionName:parameter matches thespec.listeners[*].namevalue of yourGatewayobject listener. -
The value of the
spec.rules.backendRefs.name:is the Kubernetes service for your MCP gateway. -
The value of the
spec.rules.backendRefs.port:is the port that the MCP gateway is listening on.
1.5. Applying a ReferenceGrant custom resource Copy linkLink copied to clipboard!
You can isolate teams within a single cluster by applying team-specific MCPGatewayExtension custom resources (CRs) in individual namespaces that all target a shared Gateway object. When you apply an MCPGatewayExtension CR in a different namespace than the Gateway CR, you must then create a ReferenceGrant in the namespace of the gateway to give access.
Prerequisites
- You installed OpenShift Container Platform.
-
You installed OpenShift CLI (
oc). - You installed the MCP gateway Operator.
- You configured at least one listener.
Procedure
Create a
ReferenceGrantCR by using the following example as a template:Example ReferenceGrant CR
apiVersion: gateway.networking.k8s.io/v1beta1 kind: ReferenceGrant metadata: name: <allow_team_a> namespace: gateway-system spec: from: - group: mcp.kuadrant.io kind: MCPGatewayExtension namespace: <team_a> to: - group: gateway.networking.k8s.io kind: Gateway-
Replace the
metadata.name:value with the name that you want to use. -
Replace the
spec.from.namespace:value with the namespace where theMCPGatewayExtensionCR is applied.
-
Replace the
Apply the CR by running the following command:
$ oc apply -f <allow_team_a>Replace
<allow_team_a>with name you used.
1.6. Applying the MCPGatewayExtension custom resource Copy linkLink copied to clipboard!
To finish your installation of the MCP gateway deployment Operator by using Operator Lifecycle Manager (OLM), create a MCPGatewayExtension custom resources (CR) manually and apply it to complete your initial setup. After the extension is ready, both an HTTPRoute object and an Envoy filter are automatically created.
Each namespace can only have one MCPGatewayExtension CR. Each Gateway object can have only one MCPGatewayExtension CR.
Prerequisites
- You installed OpenShift Container Platform.
-
You installed OpenShift CLI (
oc). - You installed the MCP gateway Operator.
- You configured at least one listener.
-
If you are creating your
MCPGatewayExtensionCR in a different namespace than yourGatewayobject, you have created aReferenceGrantCR.
Procedure
Create an
MCPGatewayExtensionCR by using the following example as a template:Example MCPGatewayExtension CR
apiVersion: mcp.kuadrant.io/v1alpha1 kind: MCPGatewayExtension metadata: name: <mcp_gateway_one> namespace: <mcp_system> spec: targetRef: group: gateway.networking.k8s.io kind: Gateway name: <mcp_gateway> namespace: <gateway_system> sectionName: mcp httpRouteManagement: Enabled-
Replace the
metadata.name:parameter value with the name you want to use. -
Replace the
metadata.namespace:parameter value with the namespace you want to use. -
The
spec.targetRef.sectionName:parameter value must be the same as name of the listener on the gateway. In this example,mcpis used. -
The
spec.targetRef.namespace:value must be the namespace of theGatewayobject where you created your listener. In this example,<gateway_system>is used. -
The value of the
sectionName:parameter must match the listenername:value defined on yourGatewayobject in the<gateway_system>namespace. In this example,mcpis used. -
The default setting of
spec.httpRouteManagement: Enabledmeans automatically maintainedHTTPRouteobjects to ensure that traffic for discovered MCP tools is correctly routed through theGatewayobject. If you require a customized
HTTPRouteCR, set thespec.httpRouteManagement:field value toDisabled.ImportantIn the MCP gateway Technology Preview version,
0.6.0, you must set thespec.httpRouteManagement:field value toDisabledand create a customized managedHTTPRouteCR if you are using OAuth. This is a workaround for a Known Issue. See the Connectivity Link 1.3.3 release notes for details.
-
Replace the
Apply the CR by running the following command:
$ oc apply -f <mcp_gateway_one>Replace
<mcp_gateway_one>with name you used.Wait for the
MCPGatewayExtensioncontroller to be ready by running the following command:$ oc wait --for=condition=Ready mcpgatewayextension/<mcp_gateway_one> -n <mcp_system>-
Replace
<mcp_gateway_one>with name you used. Replace
<mcp_system>with name of your MCP gateway deployment.Example successful output
mcpgatewayextension.mcp.kuadrant.io/mcp-gateway-one condition metExample failure output
error: timed out waiting for the condition on mcpgatewayextensions/mcp-gateway-one
-
Replace
Verify that the automatic
HTTProuteobject is created by running the following command:$ oc get httproute mcp-gateway-route -n mcp-systemExample output
NAME HOSTNAMES AGE mcp-gateway-route ["mcp.example.com"] 5mVerify that the Envoy filter exists in the same namespace as the
Gatewayobject by running the following command:$ oc get envoyfilter -n <gateway_namespace> -l app.kubernetes.io/managed-by=mcp-gateway-controllerReplace
<gateway_namespace>with the name of yourGatewayCR namespace.
1.7. DNS management with the MCP gateway Copy linkLink copied to clipboard!
You can use a variety of options to enable the resolution of hostnames associated within your Gateway object listeners, depending on the operating environment and targeted hostname.
For example, if the hostname is within the DNS zone defined by a dns.config.openshift.io/cluster resource, you can use the OpenShift Cluster Ingress Operator to register the IP address of the Gateway object in the associated cloud DNS provider. You must create the Gateway object in the namespace where the IngressController object is applied.
In environments where OpenShift Container Platform is not connected to a cloud provider, you must take additional steps to manage how the Gateway object is exposed outside the cluster and how traffic is resolved. You can use MetalLB to advertise IP addresses associated with the Gateway object. You can then either perform DNS registration manually, or use automation, such as the ExternalDNS Operator.
When Gateway and MCPGatewayExtension objects are applied in different namespaces, such as openshift-ingress and mcp-system, you must create a ReferenceGrant custom resource for cross-namespace communication.
1.8. Applying a customized HTTPRoute object Copy linkLink copied to clipboard!
In many production environments, you are likely to require a custom HTTPRoute object for your MCP gateway. For example, if any of the following situations apply, use a custom HTTP route:
- An identity provider protects your MCP gateway.
- You have a web-based AI chat interface that requires cross-origin resource sharing (CORS) headers so that one domain can talk to the other.
- You need additional path rules for things such as version switching, health check services, and tool dashboards.
Prerequisites
- You installed OpenShift Container Platform.
-
You installed OpenShift CLI (
oc). - You installed the MCP gateway Operator.
- You configured at least one listener.
-
You created a
MCPGatewayExtensionCR.
Procedure
If you have not already done so, disable automatic route creation on your corresponding
MCPGatewayExtensionobject by running the following command:$ oc patch mcpgatewayextension -n _<mcp_system>_ _<extension_name>_ \ --type merge -p '{"spec":{"httpRouteManagement":"Disabled"}}'Replace
<mcp_system>with the namespace where MCP gateway is installed. Replace<extension_name>with the name of yourMCPGatewayExtensionCR.Create your customized
HTTPRouteCR by using the following template:Example customized HTTPRoute CR
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: <mcp_route_custom> namespace: <mcp_system> spec: parentRefs: - name: <gateway_name> namespace: <gateway_namespace> sectionName: <mcp_gateway_listener> hostnames: - <'mcp.example.com'> rules: - matches: - path: type: PathPrefix value: /mcp filters: - type: ResponseHeaderModifier responseHeaderModifier: add: - name: Access-Control-Allow-Origin value: "*" - name: Access-Control-Allow-Methods value: "GET, POST, PUT, DELETE, OPTIONS, HEAD" - name: Access-Control-Allow-Headers value: "Content-Type, Authorization, Accept, Origin, X-Requested-With" - name: Access-Control-Max-Age value: "3600" - name: Access-Control-Allow-Credentials value: "true" backendRefs: - name: <mcp_gateway> port: 8080 - matches: - path: type: PathPrefix value: </.well_known/oauth_protected_resource> backendRefs: - name: <mcp_gateway> port: 8080-
Replace the
metadata.name:value with the name that you want to use. -
Replace the
metadata.namespace:value with the namespace that you want to use. -
Replace the
spec.targetRef.sectionName:parameter value with the MCPGatewayobject listener. -
Replace the
spec.parentRefs.name:value the name that you want to use. -
Replace
spec.parentRefs.namespace:value with the namespace that you want to use. -
Replace the
spec.hostnames:value or list with the values you want to use. -
Replace the
spec.rules.matches.path.value:value with the URL path where you want to have yourGatewayobject available. -
Replace the
spec.rules.backend.Refs.name:value with the name of your MCP gateway deployment.
-
Replace the
Apply the CR by running the following command:
$ oc apply -f <mcp_route_custom>Replace
<mcp_route_custom>with the name that you used for yourHTTPRouteCR.Delete automatically created
HTTPRouteCRs by running the following command:$ oc delete httproute mcp-gateway-route -n mcp-system --ignore-not-foundImportantIf you do not delete existing
HTTPRouteCRs, the Gateway API chooses one based on aspec-defined precedence chain used when multipleHTTPRouteCRs match the same request.
1.9. Verifying that an MCP endpoint is accessible through your MCP gateway Copy linkLink copied to clipboard!
You can verify that your MCP gateway is reaching your MCP endpoint by running a curl command to check for communication.
Prerequisites
- You completed all of the installation steps.
Procedure
Verify that the MCP endpoint is accessible through your MCP gateway instance by running the following command:
$ curl -X POST http://<mcp.example.com:port/mcp> \ -H "Content-Type: application/json" \ -d '{"jsonrpc": "2.0", "id": 1, "method": "initialize"}'Replace
<mcp.example.com:port/mcp>with your<hostname_value/endpoint_name>.Example output
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-11-25","capabilities":{"tools":{"listChanged":true}},"serverInfo":{"name":"Kuadrant MCP Gateway","version":"0.6.0"}}}