SSE: Add support for SSE handler options (#508)

mcp/sse: add support to provide for options for SSE transport

- Add SSEOptions struct to define SSE handler options.
- Update Signature of NewSSEHandler to accept SSEOptions [braking
change]
- Update unit test
- Update example test

Fixes https://github.com/modelcontextprotocol/go-sdk/issues/507,
https://github.com/modelcontextprotocol/go-sdk/issues/503
This commit is contained in:
Suraj Bobade 2025-09-19 22:31:57 +05:30 • committed by GitHub
commit 8c42b69817
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 17 additions and 7 deletions

View file

@ -65,6 +65,6 @@ func main() {
default: default:
return nil return nil
} }
}) }, nil)
log.Fatal(http.ListenAndServe(addr, handler)) log.Fatal(http.ListenAndServe(addr, handler))
} }

View file

@ -43,12 +43,18 @@ import (
// [2024-11-05 version]: https://modelcontextprotocol.io/specification/2024-11-05/basic/transports // [2024-11-05 version]: https://modelcontextprotocol.io/specification/2024-11-05/basic/transports
type SSEHandler struct { type SSEHandler struct {
getServer func(request *http.Request) *Server getServer func(request *http.Request) *Server
opts SSEOptions
onConnection func(*ServerSession) // for testing; must not block onConnection func(*ServerSession) // for testing; must not block
mu sync.Mutex mu sync.Mutex
sessions map[string]*SSEServerTransport sessions map[string]*SSEServerTransport
} }
// SSEOptions specifies options for an [SSEHandler].
// for now, it is empty, but may be extended in future.
// https://github.com/modelcontextprotocol/go-sdk/issues/507
type SSEOptions struct{}
// NewSSEHandler returns a new [SSEHandler] that creates and manages MCP // NewSSEHandler returns a new [SSEHandler] that creates and manages MCP
// sessions created via incoming HTTP requests. // sessions created via incoming HTTP requests.
// //
@ -62,13 +68,17 @@ type SSEHandler struct {
// The getServer function may return a distinct [Server] for each new // The getServer function may return a distinct [Server] for each new
// request, or reuse an existing server. If it returns nil, the handler // request, or reuse an existing server. If it returns nil, the handler
// will return a 400 Bad Request. // will return a 400 Bad Request.
// func NewSSEHandler(getServer func(request *http.Request) *Server, opts *SSEOptions) *SSEHandler {
// TODO(rfindley): add options. s := &SSEHandler{
func NewSSEHandler(getServer func(request *http.Request) *Server) *SSEHandler {
return &SSEHandler{
getServer: getServer, getServer: getServer,
sessions: make(map[string]*SSEServerTransport), sessions: make(map[string]*SSEServerTransport),
} }
if opts != nil {
s.opts = *opts
}
return s
} }
// A SSEServerTransport is a logical SSE session created through a hanging GET // A SSEServerTransport is a logical SSE session created through a hanging GET

View file

@ -31,7 +31,7 @@ func ExampleSSEHandler() {
server := mcp.NewServer(&mcp.Implementation{Name: "adder", Version: "v0.0.1"}, nil) server := mcp.NewServer(&mcp.Implementation{Name: "adder", Version: "v0.0.1"}, nil)
mcp.AddTool(server, &mcp.Tool{Name: "add", Description: "add two numbers"}, Add) mcp.AddTool(server, &mcp.Tool{Name: "add", Description: "add two numbers"}, Add)
handler := mcp.NewSSEHandler(func(*http.Request) *mcp.Server { return server }) handler := mcp.NewSSEHandler(func(*http.Request) *mcp.Server { return server }, nil)
httpServer := httptest.NewServer(handler) httpServer := httptest.NewServer(handler)
defer httpServer.Close() defer httpServer.Close()

View file

@ -24,7 +24,7 @@ func TestSSEServer(t *testing.T) {
server := NewServer(testImpl, nil) server := NewServer(testImpl, nil)
AddTool(server, &Tool{Name: "greet"}, sayHi) AddTool(server, &Tool{Name: "greet"}, sayHi)
sseHandler := NewSSEHandler(func(*http.Request) *Server { return server }) sseHandler := NewSSEHandler(func(*http.Request) *Server { return server }, nil)
serverSessions := make(chan *ServerSession, 1) serverSessions := make(chan *ServerSession, 1)
sseHandler.onConnection = func(ss *ServerSession) { sseHandler.onConnection = func(ss *ServerSession) {