@@ -128,13 +128,21 @@ func (i *sessionInfo) stopTimer() {
128128type StreamableHTTPOptions struct {
129129 // Stateless controls whether the session is 'stateless'.
130130 //
131- // A stateless server ignores the Mcp-Session-Id header, and uses a
132- // temporary session with default initialization parameters. Any
131+ // A stateless server does not read or set the Mcp-Session-Id header, and
132+ // uses a temporary session with default initialization parameters for each
133+ // request. [ServerOptions.GetSessionID] is not consulted. Any
133134 // server->client request is rejected immediately as there's no way for the
134135 // client to respond. Server->Client notifications may reach the client if
135136 // they are made in the context of an incoming request, as described in the
136137 // documentation for [StreamableServerTransport].
137- // In Stateless mode DELETE requests will return 405 Method Not Allowed.
138+ // In Stateless mode, GET and DELETE requests return 405 Method Not Allowed.
139+ //
140+ // This mode aligns with the sessionless direction of the MCP spec; see
141+ // [SEP-2567]. The previous behavior, in which stateless servers still
142+ // honored Mcp-Session-Id, can be restored temporarily via the
143+ // MCPGODEBUG compatibility parameter "allowsessionsinstateless=1".
144+ //
145+ // [SEP-2567]: https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2567
138146 Stateless bool
139147
140148 // TODO(#148): support session retention (?)
@@ -1689,11 +1697,13 @@ func init() {
16891697// Connect implements the [Transport] interface.
16901698//
16911699// The resulting [Connection] writes messages via POST requests to the
1692- // transport URL with the Mcp-Session-Id header set, and reads messages from
1693- // hanging requests.
1700+ // transport URL, and reads messages from hanging requests. If the server
1701+ // provides a session ID via the Mcp-Session-Id response header, subsequent
1702+ // requests include it; sessionless servers that omit the header are fully
1703+ // supported.
16941704//
1695- // When closed, the connection issues a DELETE request to terminate the logical
1696- // session.
1705+ // When closed, the connection issues a DELETE request to terminate the
1706+ // session, unless no session was established .
16971707func (t * StreamableClientTransport ) Connect (ctx context.Context ) (Connection , error ) {
16981708 client := t .HTTPClient
16991709 if client == nil {
@@ -2370,6 +2380,9 @@ func (c *streamableClientConn) Close() error {
23702380 c .closeOnce .Do (func () {
23712381 if errors .Is (c .failure (), ErrSessionMissing ) {
23722382 // If the session is missing, no need to delete it.
2383+ } else if c .SessionID () == "" {
2384+ // No session was established (e.g. the server is stateless),
2385+ // so there is nothing to delete.
23732386 } else {
23742387 req , err := http .NewRequestWithContext (c .ctx , http .MethodDelete , c .url , nil )
23752388 if err != nil {
0 commit comments