[tools] internal/mcp: dynamically determine the mcp server based on URL

3 views
Skip to first unread message

Gopher Robot (Gerrit)

unread,
Apr 28, 2025, 3:16:56 PM4/28/25
to Hongxiang Jiang, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Go LUCI, Robert Findley, Madeline Kalil, golang-co...@googlegroups.com

Gopher Robot submitted the change with unreviewed changes

Unreviewed changes

6 is the latest approved patch-set.
The change was submitted with unreviewed changes in the following files:

```
The name of the file: internal/mcp/examples/hello/main.go
Insertions: 1, Deletions: 1.

@@ -33,7 +33,7 @@
server.AddTools(mcp.MakeTool("greet", "say hi", SayHi))

if *httpAddr != "" {
- handler := mcp.NewSSEHandler(func(string) *mcp.Server {
+ handler := mcp.NewSSEHandler(func(*http.Request) *mcp.Server {
return server
})
http.ListenAndServe(*httpAddr, handler)
```
```
The name of the file: internal/mcp/sse_test.go
Insertions: 2, Deletions: 1.

@@ -7,6 +7,7 @@
import (
"context"
"fmt"
+ "net/http"
"net/http/httptest"
"testing"

@@ -20,7 +21,7 @@
server := NewServer("testServer", "v1.0.0", nil)
server.AddTools(MakeTool("greet", "say hi", sayHi))

- sseHandler := NewSSEHandler(func(string) *Server { return server })
+ sseHandler := NewSSEHandler(func(*http.Request) *Server { return server })

clients := make(chan *ClientConnection, 1)
sseHandler.onClient = func(cc *ClientConnection) {
```
```
The name of the file: internal/mcp/examples/sse/main.go
Insertions: 2, Deletions: 1.

@@ -39,7 +39,8 @@
server2.AddTools(mcp.MakeTool("greet2", "say hello", SayHi))

log.Printf("MCP servers serving at %s\n", *httpAddr)
- handler := mcp.NewSSEHandler(func(url string) *mcp.Server {
+ handler := mcp.NewSSEHandler(func(request *http.Request) *mcp.Server {
+ url := request.URL.Path
log.Printf("Handling request for URL %s\n", url)
switch url {
case "/greeter1":
```
```
The name of the file: internal/mcp/sse.go
Insertions: 3, Deletions: 3.

@@ -53,7 +53,7 @@
// defined by version 2024-11-05 of the MCP spec:
// https://modelcontextprotocol.io/specification/2024-11-05/basic/transports
type SSEHandler struct {
- getServer func(string) *Server
+ getServer func(request *http.Request) *Server
onClient func(*ClientConnection) // for testing; must not block

mu sync.Mutex
@@ -64,7 +64,7 @@
//
// The getServer function is used to bind created servers for new sessions. It
// is OK for getServer to return the same server multiple times.
-func NewSSEHandler(getServer func(URL string) *Server) *SSEHandler {
+func NewSSEHandler(getServer func(request *http.Request) *Server) *SSEHandler {
return &SSEHandler{
getServer: getServer,
sessions: make(map[string]*sseSession),
@@ -159,7 +159,7 @@
}()

// TODO(hxjiang): getServer returns nil will panic.
- server := h.getServer(req.URL.Path)
+ server := h.getServer(req)
cc, err := server.Connect(req.Context(), session, nil)
if err != nil {
http.Error(w, "connection failed", http.StatusInternalServerError)
```

Change information

Commit message:
internal/mcp: dynamically determine the mcp server based on URL

Based on my understanding, the getServer function is used to determine
which MCP server should be serving the session.

User might want to dynamically determine which MCP server to serve when
a new request comes in. In mcp/examples, two MCP servers are created
serving at the same port but under different URL "/greeter1",
"/greeter2". The MCP client will reach out to different URLs for
different MCP servers.

As a TODO, if the getServer() returns nil, the program will crash when
handing MCP request.
Change-Id: I4431266666e9ea28118e827a94eb1359b1fb3a81
Reviewed-by: Robert Findley <rfin...@google.com>
Auto-Submit: Hongxiang Jiang <hxj...@golang.org>
Files:
  • M internal/mcp/examples/hello/main.go
  • A internal/mcp/examples/sse/main.go
  • M internal/mcp/sse.go
  • M internal/mcp/sse_test.go
Change size: M
Delta: 4 files changed, 63 insertions(+), 6 deletions(-)
Branch: refs/heads/master
Submit Requirements:
  • requirement satisfiedCode-Review: +2 by Robert Findley
  • requirement satisfiedTryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
Open in Gerrit
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: merged
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: I4431266666e9ea28118e827a94eb1359b1fb3a81
Gerrit-Change-Number: 668535
Gerrit-PatchSet: 8
Gerrit-Owner: Hongxiang Jiang <hxj...@golang.org>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Hongxiang Jiang <hxj...@golang.org>
Gerrit-Reviewer: Robert Findley <rfin...@google.com>
Gerrit-CC: Madeline Kalil <mka...@google.com>
open
diffy
satisfied_requirement
Reply all
Reply to author
Forward
0 new messages