@@ -53,18 +53,20 @@ var _ ClientSession = (*sseSession)(nil)
53
53
// SSEServer implements a Server-Sent Events (SSE) based MCP server.
54
54
// It provides real-time communication capabilities over HTTP using the SSE protocol.
55
55
type SSEServer struct {
56
- server * MCPServer
57
- baseURL string
58
- basePath string
59
- useFullURLForMessageEndpoint bool
60
- messageEndpoint string
61
- sseEndpoint string
62
- sessions sync.Map
63
- srv * http.Server
64
- contextFunc SSEContextFunc
56
+ server * MCPServer
57
+ baseURL string
58
+ basePath string
59
+ useFullURLForMessageEndpoint bool
60
+ messageEndpoint string
61
+ sseEndpoint string
62
+ sessions sync.Map
63
+ srv * http.Server
64
+ contextFunc SSEContextFunc
65
65
66
66
keepAlive bool
67
67
keepAliveInterval time.Duration
68
+
69
+ appendQueryToMessageEndpoint bool
68
70
}
69
71
70
72
// SSEOption defines a function type for configuring SSEServer
@@ -111,6 +113,17 @@ func WithMessageEndpoint(endpoint string) SSEOption {
111
113
}
112
114
}
113
115
116
+ // WithAppendQueryToMessageEndpoint configures the SSE server to append the original request's
117
+ // query parameters to the message endpoint URL that is sent to clients during the SSE connection
118
+ // initialization. This is useful when you need to preserve query parameters from the initial
119
+ // SSE connection request and carry them over to subsequent message requests, maintaining
120
+ // context or authentication details across the communication channel.
121
+ func WithAppendQueryToMessageEndpoint () SSEOption {
122
+ return func (s * SSEServer ) {
123
+ s .appendQueryToMessageEndpoint = true
124
+ }
125
+ }
126
+
114
127
// WithUseFullURLForMessageEndpoint controls whether the SSE server returns a complete URL (including baseURL)
115
128
// or just the path portion for the message endpoint. Set to false when clients will concatenate
116
129
// the baseURL themselves to avoid malformed URLs like "http://localhost/mcphttp://localhost/mcp/message".
@@ -158,12 +171,12 @@ func WithSSEContextFunc(fn SSEContextFunc) SSEOption {
158
171
// NewSSEServer creates a new SSE server instance with the given MCP server and options.
159
172
func NewSSEServer (server * MCPServer , opts ... SSEOption ) * SSEServer {
160
173
s := & SSEServer {
161
- server : server ,
162
- sseEndpoint : "/sse" ,
163
- messageEndpoint : "/message" ,
164
- useFullURLForMessageEndpoint : true ,
165
- keepAlive : false ,
166
- keepAliveInterval : 10 * time .Second ,
174
+ server : server ,
175
+ sseEndpoint : "/sse" ,
176
+ messageEndpoint : "/message" ,
177
+ useFullURLForMessageEndpoint : true ,
178
+ keepAlive : false ,
179
+ keepAliveInterval : 10 * time .Second ,
167
180
}
168
181
169
182
// Apply all options
@@ -293,9 +306,12 @@ func (s *SSEServer) handleSSE(w http.ResponseWriter, r *http.Request) {
293
306
}()
294
307
}
295
308
296
-
297
309
// Send the initial endpoint event
298
- fmt .Fprintf (w , "event: endpoint\n data: %s\r \n \r \n " , s .GetMessageEndpointForClient (sessionID ))
310
+ endpoint := s .GetMessageEndpointForClient (sessionID )
311
+ if s .appendQueryToMessageEndpoint && len (r .URL .RawQuery ) > 0 {
312
+ endpoint += "&" + r .URL .RawQuery
313
+ }
314
+ fmt .Fprintf (w , "event: endpoint\n data: %s\r \n \r \n " , endpoint )
299
315
flusher .Flush ()
300
316
301
317
// Main event loop - this runs in the HTTP handler goroutine
0 commit comments