--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.20.0 creationTimestamp: "2026-10-30T12:40:17Z" generation: 1 labels: app.kubernetes.io/managed-by: kuadrant-operator managedFields: - apiVersion: apiextensions.k8s.io/v1 fieldsType: FieldsV1 fieldsV1: f:metadata: f:annotations: f:controller-gen.kubebuilder.io/version: {} f:labels: f:app.kubernetes.io/managed-by: {} f:spec: f:group: {} f:names: f:kind: {} f:listKind: {} f:plural: {} f:shortNames: {} f:singular: {} f:scope: {} f:versions: {} manager: kuadrant-operator operation: Apply time: "2026-10-30T12:40:17Z" - apiVersion: apiextensions.k8s.io/v1 fieldsType: FieldsV1 fieldsV1: f:status: f:acceptedNames: f:kind: {} f:listKind: {} f:plural: {} f:shortNames: {} f:singular: {} f:conditions: k:{"type":"Established"}: .: {} f:lastTransitionTime: {} f:message: {} f:reason: {} f:status: {} f:type: {} k:{"type":"NamesAccepted"}: .: {} f:lastTransitionTime: {} f:message: {} f:reason: {} f:status: {} f:type: {} manager: kube-apiserver operation: Update subresource: status time: "2026-10-30T12:40:17Z" name: mcpgatewayextensions.mcp.kuadrant.io resourceVersion: "12425" uid: 0957b13e-40bd-42dd-a4c4-196a232a4188 spec: conversion: strategy: None group: mcp.kuadrant.io names: kind: MCPGatewayExtension listKind: MCPGatewayExtensionList plural: mcpgatewayextensions shortNames: - mcpge singular: mcpgatewayextension scope: Namespaced versions: - additionalPrinterColumns: - description: Ready status jsonPath: .status.conditions[?(@.type=='Ready')].status name: Ready type: string - jsonPath: .metadata.creationTimestamp name: Age type: date name: v1 schema: openAPIV3Schema: description: |- MCPGatewayExtension extends a Gateway API Gateway to handle the Model Context Protocol (MCP). When created, the controller will: - Deploy a broker-router Deployment and Service in the MCPGatewayExtension's namespace - Create an EnvoyFilter in the Gateway's namespace to route MCP traffic to the broker - Configure the Envoy proxy to use the external processor for MCP request handling The broker aggregates tools from upstream MCP servers registered via MCPServerRegistration resources, while the router handles MCP protocol parsing and request routing. Cross-namespace references to Gateways require a ReferenceGrant in the Gateway's namespace. properties: apiVersion: description: |- APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: description: |- Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object spec: description: spec defines the desired state of MCPGatewayExtension properties: backendPingIntervalSeconds: default: 60 description: backendPingIntervalSeconds specifies how often the broker pings upstream MCP servers. format: int32 maximum: 7200 minimum: 10 type: integer caCertBundleRef: description: |- caCertBundleRef references a Secret containing a PEM-encoded CA certificate bundle used as the base trust pool for: - broker connections to all upstream MCP servers (per-server caCertSecretRef appends) - 2025-11-25 protocol hairpin requests to the gateway HTTPS listener 2026-07-28 MCP calls do not hairpin and do not use this bundle for gateway TLS. Include both the gateway listener CA and upstream CAs when they differ. The Secret must have the label mcp.kuadrant.io/secret=true. properties: key: default: ca.crt description: |- key is the key within the Secret that contains the CA bundle PEM data. If not specified, defaults to "ca.crt". type: string name: description: name is the name of the Secret resource. minLength: 1 type: string required: - name type: object httpRouteManagement: default: Enabled description: |- httpRouteManagement controls whether the operator manages the gateway HTTPRoute. Enabled: creates and manages the HTTPRoute (default). Disabled: does not create an HTTPRoute. enum: - Enabled - Disabled type: string logLevel: description: |- logLevel controls the broker-router log verbosity. Maps to the broker's --log-level flag: debug=-4, info=0, warn=4, error=8. When unset, the operator-wide BROKER_ROUTER_LOG_LEVEL default (if configured) is used. enum: - debug - info - warn - error type: string maxBodyBytes: default: 5242880 description: |- maxBodyBytes caps the size of any body the router buffers, in bytes. Applies to request/response prefix stripping and guardrails checks. format: int32 minimum: 1 type: integer oauthProtectedResource: description: |- oauthProtectedResource configures the OAuth protected resource metadata served at /.well-known/oauth-protected-resource. When set, the controller injects the corresponding OAUTH_* env vars into the broker-router deployment. properties: authorizationServers: description: authorizationServers lists the OAuth authorization server URLs. items: pattern: ^https?://[^,]+$ type: string maxItems: 10 minItems: 1 type: array x-kubernetes-list-type: atomic bearerMethodsSupported: description: |- bearerMethodsSupported lists the supported bearer token methods. Defaults to ["header"]. items: type: string maxItems: 10 type: array x-kubernetes-list-type: atomic resource: description: |- resource is the URI of the protected resource. Defaults to https:///mcp. maxLength: 2048 type: string resourceName: description: |- resourceName is the human-readable name for this resource. Defaults to "MCP Server". maxLength: 253 type: string scopesSupported: description: |- scopesSupported lists the supported OAuth scopes. Defaults to ["basic"]. items: type: string maxItems: 50 type: array x-kubernetes-list-type: atomic required: - authorizationServers type: object privateHost: description: |- privateHost overrides the internal host used for hair-pinning requests back through the gateway. Defaults to -..svc.cluster.local:, with an https:// scheme prefix when the targeted Gateway listener uses the HTTPS protocol. The value supplied here is honoured verbatim, so an operator can include a scheme (e.g. "https://my-gw:443") or pin to a different port. type: string publicHost: description: |- publicHost overrides the public host derived from the listener hostname. Use when the listener has a wildcard and you need a specific host. type: string sessionStore: description: |- sessionStore references a secret for redis-based session storage. The secret must exist in the MCPGatewayExtension namespace and contain a CACHE_CONNECTION_STRING key. The value is injected as CACHE_CONNECTION_STRING into the broker-router deployment. When not set, in-memory session storage is used. properties: secretName: description: |- secretName is the name of the secret containing the CACHE_CONNECTION_STRING key. The value should be a redis connection string: redis://:@:/ minLength: 1 type: string required: - secretName type: object targetRef: description: |- targetRef specifies the Gateway to extend with MCP protocol support. The controller will create an EnvoyFilter targeting this Gateway's Envoy proxy. properties: group: default: gateway.networking.k8s.io description: group is the group of the target resource. enum: - gateway.networking.k8s.io type: string kind: default: Gateway description: kind is the kind of the target resource. enum: - Gateway type: string name: description: name is the name of the target resource. minLength: 1 type: string namespace: description: namespace of the target resource (optional, defaults to same namespace) type: string sectionName: description: |- sectionName is the name of a listener on the target Gateway. The controller will read the listener's port and hostname to configure the MCP Gateway instance. Only one MCPGatewayExtension is allowed per namespace. MCPGatewayExtensions in different namespaces may target different listeners on the same Gateway, provided those listeners use different ports. maxLength: 253 minLength: 1 type: string required: - name - sectionName type: object trustedHeadersKey: description: |- trustedHeadersKey configures trusted-header key pair for JWT-based tool filtering. When set, the public key secret is wired into the broker deployment. properties: generate: default: Disabled description: |- generate controls whether the operator generates an ECDSA P-256 key pair. Enabled: creates (public key) and -private (private key) in the MCPGatewayExtension namespace with owner references. Disabled: the secret must already exist (default). Changing this field requires deleting the existing secrets first to ensure the public and private keys are a matching pair. enum: - Enabled - Disabled type: string secretName: description: |- secretName is the name of the secret containing the public key used by the broker to verify trusted-header JWTs. The secret must have a data entry with key "key" containing the PEM-encoded public key. When Generate is Enabled, the operator creates this secret. When Generate is Disabled, this secret must already exist in the namespace. minLength: 1 type: string required: - secretName type: object urlElicitation: default: Disabled description: |- urlElicitation controls whether URL-based token elicitation is enabled. Enabled: creates a separate /tokens HTTPRoute and passes --enable-url-elicitation to the broker. Disabled: no /tokens route is created (default). enum: - Enabled - Disabled type: string required: - targetRef type: object status: description: status defines the observed state of MCPGatewayExtension properties: conditions: description: |- conditions represent the current state of the MCPGatewayExtension. The Ready condition indicates whether the broker-router deployment is running and the EnvoyFilter has been successfully applied to the target Gateway. items: description: Condition contains details for one aspect of the current state of this API Resource. properties: lastTransitionTime: description: |- lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: description: |- message is a human readable message indicating details about the transition. This may be an empty string. maxLength: 32768 type: string observedGeneration: description: |- observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: description: |- reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ type: string status: description: status of the condition, one of True, False, Unknown. enum: - "True" - "False" - Unknown type: string type: description: type of condition in CamelCase or in foo.example.com/CamelCase. maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - lastTransitionTime - message - reason - status - type type: object type: array x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map type: object required: - spec type: object served: true storage: true subresources: status: {} - additionalPrinterColumns: - description: Ready status jsonPath: .status.conditions[?(@.type=='Ready')].status name: Ready type: string - jsonPath: .metadata.creationTimestamp name: Age type: date deprecated: true deprecationWarning: mcp.kuadrant.io/v1alpha1 MCPGatewayExtension is deprecated; migrate to mcp.kuadrant.io/v1 name: v1alpha1 schema: openAPIV3Schema: description: |- MCPGatewayExtension extends a Gateway API Gateway to handle the Model Context Protocol (MCP). When created, the controller will: - Deploy a broker-router Deployment and Service in the MCPGatewayExtension's namespace - Create an EnvoyFilter in the Gateway's namespace to route MCP traffic to the broker - Configure the Envoy proxy to use the external processor for MCP request handling The broker aggregates tools from upstream MCP servers registered via MCPServerRegistration resources, while the router handles MCP protocol parsing and request routing. Cross-namespace references to Gateways require a ReferenceGrant in the Gateway's namespace. properties: apiVersion: description: |- APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: description: |- Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object spec: description: spec defines the desired state of MCPGatewayExtension properties: backendPingIntervalSeconds: default: 60 description: backendPingIntervalSeconds specifies how often the broker pings upstream MCP servers. format: int32 maximum: 7200 minimum: 10 type: integer caCertBundleRef: description: |- caCertBundleRef references a Secret containing a PEM-encoded CA certificate bundle used as the base trust pool for: - broker connections to all upstream MCP servers (per-server caCertSecretRef appends) - 2025-11-25 protocol hairpin requests to the gateway HTTPS listener 2026-07-28 MCP calls do not hairpin and do not use this bundle for gateway TLS. Include both the gateway listener CA and upstream CAs when they differ. The Secret must have the label mcp.kuadrant.io/secret=true. properties: key: default: ca.crt description: |- key is the key within the Secret that contains the CA bundle PEM data. If not specified, defaults to "ca.crt". type: string name: description: name is the name of the Secret resource. minLength: 1 type: string required: - name type: object httpRouteManagement: default: Enabled description: |- httpRouteManagement controls whether the operator manages the gateway HTTPRoute. Enabled: creates and manages the HTTPRoute (default). Disabled: does not create an HTTPRoute. enum: - Enabled - Disabled type: string logLevel: description: |- logLevel controls the broker-router log verbosity. Maps to the broker's --log-level flag: debug=-4, info=0, warn=4, error=8. When unset, the operator-wide BROKER_ROUTER_LOG_LEVEL default (if configured) is used. enum: - debug - info - warn - error type: string oauthProtectedResource: description: |- oauthProtectedResource configures the OAuth protected resource metadata served at /.well-known/oauth-protected-resource. When set, the controller injects the corresponding OAUTH_* env vars into the broker-router deployment. properties: authorizationServers: description: authorizationServers lists the OAuth authorization server URLs. items: pattern: ^https?://[^,]+$ type: string maxItems: 10 minItems: 1 type: array x-kubernetes-list-type: atomic bearerMethodsSupported: description: |- bearerMethodsSupported lists the supported bearer token methods. Defaults to ["header"]. items: type: string maxItems: 10 type: array x-kubernetes-list-type: atomic resource: description: |- resource is the URI of the protected resource. Defaults to https:///mcp. maxLength: 2048 type: string resourceName: description: |- resourceName is the human-readable name for this resource. Defaults to "MCP Server". maxLength: 253 type: string scopesSupported: description: |- scopesSupported lists the supported OAuth scopes. Defaults to ["basic"]. items: type: string maxItems: 50 type: array x-kubernetes-list-type: atomic required: - authorizationServers type: object privateHost: description: |- privateHost overrides the internal host used for hair-pinning requests back through the gateway. Defaults to -..svc.cluster.local:, with an https:// scheme prefix when the targeted Gateway listener uses the HTTPS protocol. The value supplied here is honoured verbatim, so an operator can include a scheme (e.g. "https://my-gw:443") or pin to a different port. type: string publicHost: description: |- publicHost overrides the public host derived from the listener hostname. Use when the listener has a wildcard and you need a specific host. type: string sessionStore: description: |- sessionStore references a secret for redis-based session storage. The secret must exist in the MCPGatewayExtension namespace and contain a CACHE_CONNECTION_STRING key. The value is injected as CACHE_CONNECTION_STRING into the broker-router deployment. When not set, in-memory session storage is used. properties: secretName: description: |- secretName is the name of the secret containing the CACHE_CONNECTION_STRING key. The value should be a redis connection string: redis://:@:/ minLength: 1 type: string required: - secretName type: object targetRef: description: |- targetRef specifies the Gateway to extend with MCP protocol support. The controller will create an EnvoyFilter targeting this Gateway's Envoy proxy. properties: group: default: gateway.networking.k8s.io description: group is the group of the target resource. enum: - gateway.networking.k8s.io type: string kind: default: Gateway description: kind is the kind of the target resource. enum: - Gateway type: string name: description: name is the name of the target resource. minLength: 1 type: string namespace: description: namespace of the target resource (optional, defaults to same namespace) type: string sectionName: description: |- sectionName is the name of a listener on the target Gateway. The controller will read the listener's port and hostname to configure the MCP Gateway instance. Only one MCPGatewayExtension is allowed per namespace. MCPGatewayExtensions in different namespaces may target different listeners on the same Gateway, provided those listeners use different ports. maxLength: 253 minLength: 1 type: string required: - name - sectionName type: object trustedHeadersKey: description: |- trustedHeadersKey configures trusted-header key pair for JWT-based tool filtering. When set, the public key secret is wired into the broker deployment. properties: generate: default: Disabled description: |- generate controls whether the operator generates an ECDSA P-256 key pair. Enabled: creates (public key) and -private (private key) in the MCPGatewayExtension namespace with owner references. Disabled: the secret must already exist (default). Changing this field requires deleting the existing secrets first to ensure the public and private keys are a matching pair. enum: - Enabled - Disabled type: string secretName: description: |- secretName is the name of the secret containing the public key used by the broker to verify trusted-header JWTs. The secret must have a data entry with key "key" containing the PEM-encoded public key. When Generate is Enabled, the operator creates this secret. When Generate is Disabled, this secret must already exist in the namespace. minLength: 1 type: string required: - secretName type: object urlElicitation: default: Disabled description: |- urlElicitation controls whether URL-based token elicitation is enabled. Enabled: creates a separate /tokens HTTPRoute and passes --enable-url-elicitation to the broker. Disabled: no /tokens route is created (default). enum: - Enabled - Disabled type: string required: - targetRef type: object status: description: status defines the observed state of MCPGatewayExtension properties: conditions: description: |- conditions represent the current state of the MCPGatewayExtension. The Ready condition indicates whether the broker-router deployment is running and the EnvoyFilter has been successfully applied to the target Gateway. items: description: Condition contains details for one aspect of the current state of this API Resource. properties: lastTransitionTime: description: |- lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: description: |- message is a human readable message indicating details about the transition. This may be an empty string. maxLength: 32768 type: string observedGeneration: description: |- observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: description: |- reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ type: string status: description: status of the condition, one of True, False, Unknown. enum: - "True" - "False" - Unknown type: string type: description: type of condition in CamelCase or in foo.example.com/CamelCase. maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - lastTransitionTime - message - reason - status - type type: object type: array x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map type: object required: - spec type: object served: false storage: false subresources: status: {} status: acceptedNames: kind: MCPGatewayExtension listKind: MCPGatewayExtensionList plural: mcpgatewayextensions shortNames: - mcpge singular: mcpgatewayextension conditions: - lastTransitionTime: "2026-10-30T12:40:17Z" message: no conflicts found reason: NoConflicts status: "True" type: NamesAccepted - lastTransitionTime: "2026-10-30T12:40:17Z" message: the initial names have been accepted reason: InitialNamesAccepted status: "True" type: Established storedVersions: - v1