diff --git a/go/core/internal/mcp/mcp_handler.go b/go/core/internal/mcp/mcp_handler.go index 8182df6fb3..83543faabc 100644 --- a/go/core/internal/mcp/mcp_handler.go +++ b/go/core/internal/mcp/mcp_handler.go @@ -13,6 +13,7 @@ import ( authimpl "github.com/kagent-dev/kagent/go/core/internal/httpserver/auth" "github.com/kagent-dev/kagent/go/core/internal/version" "github.com/kagent-dev/kagent/go/core/pkg/auth" + "github.com/kagent-dev/kagent/go/core/pkg/env" mcpsdk "github.com/modelcontextprotocol/go-sdk/mcp" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -102,11 +103,15 @@ func NewMCPHandler(kubeClient client.Client, a2aBaseURL string, authenticator au ) // Create HTTP handler + var httpOpts *mcpsdk.StreamableHTTPOptions + if env.KagentMCPStateless.Get() { + httpOpts = &mcpsdk.StreamableHTTPOptions{Stateless: true} + } handler.httpHandler = mcpsdk.NewStreamableHTTPHandler( func(*http.Request) *mcpsdk.Server { return server }, - nil, + httpOpts, ) return handler, nil diff --git a/go/core/pkg/env/kagent.go b/go/core/pkg/env/kagent.go index be8c62d417..5d158b2060 100644 --- a/go/core/pkg/env/kagent.go +++ b/go/core/pkg/env/kagent.go @@ -23,6 +23,16 @@ var ( ComponentController, ) + KagentMCPStateless = RegisterBoolVar( + "KAGENT_MCP_STATELESS", + false, + "When true, the MCP server operates in stateless mode (no session persistence). "+ + "Use when the network path does not provide sticky session routing based on the Mcp-Session-Id header. "+ + "Note: stateless mode disables server-initiated notifications; clients will not receive "+ + "resources/updated events.", + ComponentController, + ) + // Variables injected into agent pods (not read by the controller itself). KagentName = RegisterStringVar(