Skip to content

Configure MCP Gateway Listener and Route

This guide covers adding the required MCP listeners to your existing Gateway. The controller automatically creates an HTTPRoute when the MCPGatewayExtension becomes ready. This guide also covers how to use a custom HTTPRoute if you need CORS headers or additional path rules.

Prerequisites

Step 1: Add MCP Listeners to Gateway

MCP Gateway requires two listeners on your Gateway:

  • mcp: the public-facing listener for MCP client traffic. The hostname must resolve to your Gateway's external address.
  • mcps: an internal listener used for routing to registered MCP servers. MCPServerRegistration HTTPRoutes attach to this listener. The hostname is a wildcard that does not need to be publicly resolvable.

Patch your Gateway to add both listeners:

kubectl patch gateway your-gateway-name -n your-gateway-namespace --type merge -p '
spec:
  listeners:

  - name: mcp
    hostname: "mcp.example.com"
    port: 8080
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All
  - name: mcps
    hostname: "*.mcp.local"
    port: 8080
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All
'

Replace your-gateway-name, your-gateway-namespace, and the mcp hostname with your values. The mcps wildcard hostname (*.mcp.local) is only used for internal cluster routing. You can use any wildcard hostname here (e.g. *.mcp.internal).

Note: The patch above replaces all listeners. To preserve existing listeners, use a JSON patch or edit the Gateway directly with kubectl edit gateway your-gateway-name -n your-gateway-namespace.

Important: If you installed MCP Gateway using Helm, ensure the gateway.publicHost value in your Helm values matches the hostname above. For example:

helm upgrade mcp-gateway oci://ghcr.io/kuadrant/charts/mcp-gateway \
  --set gateway.publicHost=mcp.127-0-0-1.sslip.io

Verify both listeners were added:

kubectl get gateway your-gateway-name -n your-gateway-namespace -o jsonpath='{.spec.listeners[*].name}'

You should see both mcp and mcps in the output.

Step 2: HTTPRoute (Automatic)

The MCPGatewayExtension controller automatically creates an HTTPRoute named mcp-gateway-route when the extension becomes ready. The HTTPRoute:

  • Routes /mcp traffic to the mcp-gateway broker service on port 8080
  • Uses the hostname from the Gateway listener (wildcards like *.example.com become mcp.example.com)
  • References the target Gateway with the correct sectionName
  • Is owned by the MCPGatewayExtension and cleaned up automatically on deletion

Verify the HTTPRoute was created:

kubectl get httproute mcp-gateway-route -n mcp-system

Custom HTTPRoute (Optional)

If you need a custom HTTPRoute (e.g. with CORS headers, additional path rules, or OAuth well-known endpoints), disable automatic creation and manage your own:

  1. Find your MCPGatewayExtension name and set httpRouteManagement: Disabled:

    kubectl get mcpgatewayextension -n mcp-system
    kubectl patch mcpgatewayextension -n mcp-system your-extension-name \
      --type merge -p '{"spec":{"httpRouteManagement":"Disabled"}}'
    

  2. Delete the previously auto-created HTTPRoute if it exists:

    kubectl delete httproute mcp-gateway-route -n mcp-system --ignore-not-found
    

  3. Create your custom HTTPRoute:

    kubectl apply -f - <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: mcp-route
      namespace: mcp-system
    spec:
      parentRefs:
        - name: your-gateway-name
          namespace: your-gateway-namespace
          sectionName: mcp
      hostnames:
        - 'mcp.127-0-0-1.sslip.io'
      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
    EOF
    

Step 3: Verify EnvoyFilter Configuration

The MCP Gateway controller automatically creates the EnvoyFilter when the MCPGatewayExtension is ready. Check that it exists:

# EnvoyFilter is created in the Gateway's namespace
kubectl get envoyfilter -n your-gateway-namespace -l app.kubernetes.io/managed-by=mcp-gateway-controller

If you see the EnvoyFilter, you can proceed to verification. If the EnvoyFilter is missing:

  1. Check that the MCPGatewayExtension is ready:

    kubectl get mcpgatewayextension -n mcp-system
    

  2. Check the controller logs for errors:

    kubectl logs -n mcp-system deployment/mcp-gateway-controller
    

  3. Verify the target Gateway exists and the MCPGatewayExtension has proper permissions (ReferenceGrant if cross-namespace).

Step 4: Verify Configuration

Test that the MCP endpoint is accessible through your Gateway:

curl -X POST http://mcp.127-0-0-1.sslip.io:8001/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "id": 1, "method": "initialize"}'

You should get a response like this:

{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-03-26","capabilities":{"tools":{"listChanged":true}},"serverInfo":{"name":"Kuadrant MCP Gateway","version":"0.0.1"}}}

Next Steps

Now that you have MCP Gateway routing configured, you can connect your MCP servers: