@@ -10,6 +10,7 @@ import (
1010 "strings"
1111 "sync"
1212 "sync/atomic"
13+ "time"
1314
1415 "github.com/google/uuid"
1516 "github.com/mark3labs/mcp-go/mcp"
@@ -633,8 +634,17 @@ func (s *StreamableHTTPServer) handleSSEResponse(w http.ResponseWriter, r *http.
633634 fmt .Fprintf (w , "data: %s\n \n " , data )
634635 }
635636 w .(http.Flusher ).Flush ()
637+
638+ // According to the MCP specification, the server SHOULD close the SSE stream
639+ // after all JSON-RPC responses have been sent.
640+ // Since we've sent the response, we can close the stream now.
641+ return
636642 }
637643
644+ // If there's no response (which shouldn't happen in normal operation),
645+ // we'll keep the stream open for a short time to handle any notifications
646+ // that might come in, then close it.
647+
638648 // Create a channel to pass notifications from the goroutine to the main handler
639649 notificationCh := make (chan struct {
640650 eventID string
@@ -683,8 +693,9 @@ func (s *StreamableHTTPServer) handleSSEResponse(w http.ResponseWriter, r *http.
683693 }
684694 }()
685695
686- // Create a context with cancellation
687- ctx , cancel := context .WithCancel (r .Context ())
696+ // Create a context with cancellation and a timeout
697+ // We'll only keep the stream open for a short time if there's no response
698+ ctx , cancel := context .WithTimeout (r .Context (), 5 * time .Second )
688699 defer cancel ()
689700
690701 // Process notifications in the main handler goroutine
@@ -699,7 +710,7 @@ func (s *StreamableHTTPServer) handleSSEResponse(w http.ResponseWriter, r *http.
699710 }
700711 w .(http.Flusher ).Flush ()
701712 case <- ctx .Done ():
702- // Request context is done, exit the loop
713+ // Request context is done or timeout reached , exit the loop
703714 return
704715 }
705716 }
@@ -784,8 +795,11 @@ func (s *StreamableHTTPServer) handleGet(w http.ResponseWriter, r *http.Request)
784795 }
785796 }()
786797
787- // Wait for the request context to be done
788- <- r .Context ().Done ()
798+ // Create a context with cancellation
799+ // For standalone SSE streams, we'll keep the connection open until the client disconnects
800+ // or the context is canceled
801+ ctx := r .Context ()
802+ <- ctx .Done ()
789803}
790804
791805// handleDelete processes DELETE requests to the MCP endpoint (for session termination)
0 commit comments