From a7cd4c0ad64d785b3fbff90a2a8371841dc8ba0a Mon Sep 17 00:00:00 2001 From: hellocn9 Date: Thu, 16 Oct 2025 15:36:05 +0800 Subject: [PATCH] feat(ingress): support custom parameter names for MCP SSE stateful sessions (#3008) --- pkg/ingress/config/ingress_config.go | 10 +++++----- pkg/ingress/kube/annotations/loadbalance.go | 17 +++++++++++++---- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/pkg/ingress/config/ingress_config.go b/pkg/ingress/config/ingress_config.go index 7a4363eac..c211246de 100644 --- a/pkg/ingress/config/ingress_config.go +++ b/pkg/ingress/config/ingress_config.go @@ -653,7 +653,7 @@ func (m *IngressConfig) convertEnvoyFilter(convertOptions *common.ConvertOptions loadBalance := route.WrapperConfig.AnnotationsConfig.LoadBalance if loadBalance != nil && loadBalance.McpSseStateful { IngressLog.Infof("Found MCP SSE stateful session for route %s", route.HTTPRoute.Name) - envoyFilter, err := m.constructMcpSseStatefulSessionEnvoyFilter(route, m.namespace, initMcpSseGlobalFilter) + envoyFilter, err := m.constructMcpSseStatefulSessionEnvoyFilter(route, m.namespace, initMcpSseGlobalFilter, loadBalance.McpSseStatefulKey) if err != nil { IngressLog.Errorf("Construct MCP SSE stateful session EnvoyFilter error %v", err) } else { @@ -1956,7 +1956,7 @@ func (m *IngressConfig) Delete(config.GroupVersionKind, string, string, *string) return common.ErrUnsupportedOp } -func (m *IngressConfig) constructMcpSseStatefulSessionEnvoyFilter(route *common.WrapperHTTPRoute, namespace string, initGlobalFilter bool) (*config.Config, error) { +func (m *IngressConfig) constructMcpSseStatefulSessionEnvoyFilter(route *common.WrapperHTTPRoute, namespace string, initGlobalFilter bool, mcpSseStatefulKey string) (*config.Config, error) { httpRoute := route.HTTPRoute var configPatches []*networking.EnvoyFilter_EnvoyConfigObjectPatch @@ -2010,7 +2010,7 @@ func (m *IngressConfig) constructMcpSseStatefulSessionEnvoyFilter(route *common. }, Patch: &networking.EnvoyFilter_Patch{ Operation: networking.EnvoyFilter_Patch_MERGE, - Value: buildPatchStruct(`{ + Value: buildPatchStruct(fmt.Sprintf(`{ "typed_per_filter_config": { "envoy.filters.http.mcp_sse_stateful_session": { "@type": "type.googleapis.com/udpa.type.v1.TypedStruct", @@ -2023,7 +2023,7 @@ func (m *IngressConfig) constructMcpSseStatefulSessionEnvoyFilter(route *common. "@type": "type.googleapis.com/udpa.type.v1.TypedStruct", "type_url": "type.googleapis.com/envoy.extensions.http.mcp_sse_stateful_session.envelope.v3alpha.EnvelopeSessionState", "value": { - "param_name": "sessionId", + "param_name": "%s", "chunk_end_patterns": ["\r\n\r\n", "\n\n", "\r\r"] } } @@ -2033,7 +2033,7 @@ func (m *IngressConfig) constructMcpSseStatefulSessionEnvoyFilter(route *common. } } } - }`), + }`, mcpSseStatefulKey)), }, }) diff --git a/pkg/ingress/kube/annotations/loadbalance.go b/pkg/ingress/kube/annotations/loadbalance.go index 93a4e3cc5..6cc088cc8 100644 --- a/pkg/ingress/kube/annotations/loadbalance.go +++ b/pkg/ingress/kube/annotations/loadbalance.go @@ -41,6 +41,9 @@ const ( defaultAffinityCookieName = "INGRESSCOOKIE" defaultAffinityCookiePath = "/" + + mcpSseStatefulKey = "mcp-sse-stateful-param-name" + defaultMcpSseStatefulKey = "sessionId" ) var ( @@ -66,10 +69,11 @@ type consistentHashByCookie struct { } type LoadBalanceConfig struct { - simple networking.LoadBalancerSettings_SimpleLB - other *consistentHashByOther - cookie *consistentHashByCookie - McpSseStateful bool + simple networking.LoadBalancerSettings_SimpleLB + other *consistentHashByOther + cookie *consistentHashByCookie + McpSseStateful bool + McpSseStatefulKey string } type loadBalance struct{} @@ -139,6 +143,11 @@ func (l loadBalance) Parse(annotations Annotations, config *Ingress, _ *GlobalCo lb = strings.ToUpper(lb) if lb == "MCP-SSE" { loadBalanceConfig.McpSseStateful = true + if key, err := annotations.ParseStringASAP(mcpSseStatefulKey); err == nil { + loadBalanceConfig.McpSseStatefulKey = key + } else { + loadBalanceConfig.McpSseStatefulKey = defaultMcpSseStatefulKey + } } else { loadBalanceConfig.simple = networking.LoadBalancerSettings_SimpleLB(networking.LoadBalancerSettings_SimpleLB_value[lb]) }