Unreviewed changes
8 is the latest approved patch-set.
The change was submitted with unreviewed changes in the following files:
```
The name of the file: gopls/internal/cmd/mcp.go
Insertions: 4, Deletions: 3.
@@ -14,6 +14,7 @@
"sync"
"time"
+ "github.com/modelcontextprotocol/go-sdk/mcp"
"golang.org/x/tools/gopls/internal/cache"
"golang.org/x/tools/gopls/internal/filewatcher"
internalmcp "golang.org/x/tools/gopls/internal/mcp"
@@ -155,14 +156,14 @@
// goroutine for it because WatchDir performs OS-level filesystem operations
// which can be slow. Blocking this callback would block the MCP server's
// JSON-RPC message loop and stall the entireconnection.
- watchRoots := func(roots []string, err error) {
+ watchRoots := func(res *mcp.ListRootsResult, err error) {
if err != nil {
errHandler(err)
return
}
watchQueueMu.Lock()
- for _, r := range roots {
- watchQueue = append(watchQueue, protocol.DocumentURI(r).Path())
+ for _, r := range res.Roots {
+ watchQueue = append(watchQueue, protocol.DocumentURI(r.URI).Path())
}
watchQueueMu.Unlock()
```
```
The name of the file: gopls/internal/mcp/mcp.go
Insertions: 9, Deletions: 18.
@@ -47,11 +47,11 @@
// caller is responsible for closing. The server runs until the context is
// canceled.
//
-// The rootsHandler callback is invoked immediately after initialization
-// and subsequently whenever the MCP client signals a change to the workspace
-// roots. It is passed the current list of roots returned by the MCP client,
-// or an error if the roots could not be retrieved.
-func Serve(ctx context.Context, address string, sessions Sessions, isDaemon bool, rootsHandler func([]string, error)) error {
+// The rootsHandler callback is invoked immediately after initialization and
+// subsequently whenever the MCP client signals a change to the workspace roots.
+// It is passed the list roots result returned by the MCP client, or an error
+// if the roots could not be retrieved. rootsHandler may be called concurrently.
+func Serve(ctx context.Context, address string, sessions Sessions, isDaemon bool, rootsHandler func(*mcp.ListRootsResult, error)) error {
log.Printf("Gopls MCP server: starting up on http")
listener, err := net.Listen("tcp", address)
if err != nil {
@@ -82,7 +82,7 @@
}
// StartStdIO starts an MCP server over stdio.
-func StartStdIO(ctx context.Context, session *cache.Session, server protocol.Server, rpcLog io.Writer, rootsHandler func([]string, error)) error {
+func StartStdIO(ctx context.Context, session *cache.Session, server protocol.Server, rpcLog io.Writer, rootsHandler func(*mcp.ListRootsResult, error)) error {
s := NewServer(session, server, rootsHandler)
if rpcLog != nil {
return s.Run(ctx, &mcp.LoggingTransport{
@@ -95,7 +95,7 @@
}
-func HTTPHandler(sessions Sessions, isDaemon bool, rootsHandler func([]string, error)) http.Handler {
+func HTTPHandler(sessions Sessions, isDaemon bool, rootsHandler func(*mcp.ListRootsResult, error)) http.Handler {
var (
mu sync.Mutex // lock for mcpHandlers.
mcpHandlers = make(map[string]*mcp.SSEHandler) // map from lsp session ids to MCP sse handlers.
@@ -160,7 +160,7 @@
return mux
}
-func NewServer(session *cache.Session, lspServer protocol.Server, rootsHandler func([]string, error)) *mcp.Server {
+func NewServer(session *cache.Session, lspServer protocol.Server, rootsHandler func(*mcp.ListRootsResult, error)) *mcp.Server {
h := handler{
session: session,
lspServer: lspServer,
@@ -252,16 +252,7 @@
}
roots, err := session.ListRoots(context.Background(), &mcp.ListRootsParams{})
- if err != nil {
- rootsHandler(nil, err)
- return
- }
-
- var uris []string
- for _, v := range roots.Roots {
- uris = append(uris, v.URI)
- }
- rootsHandler(uris, nil)
+ rootsHandler(roots, err)
}()
}
```
```
The name of the file: gopls/internal/mcp/mcp_test.go
Insertions: 5, Deletions: 5.
@@ -77,7 +77,7 @@
var callCount int
- server := internalmcp.NewServer(nil, nil, func(roots []string, err error) {
+ server := internalmcp.NewServer(nil, nil, func(res *mcp.ListRootsResult, err error) {
if err != nil {
foundError <- err
return
@@ -90,13 +90,13 @@
expected := wantRoots[callCount]
- if len(roots) != len(expected) {
- t.Errorf("Phase %d: expected %d roots, got %d", callCount+1, len(expected), len(roots))
+ if len(res.Roots) != len(expected) {
+ t.Errorf("Phase %d: expected %d roots, got %d", callCount+1, len(expected), len(res.Roots))
return
}
- for _, r := range roots {
- if _, ok := expected[r]; !ok {
+ for _, r := range res.Roots {
+ if _, ok := expected[r.URI]; !ok {
t.Errorf("Phase %d: unexpected root %s", callCount+1, r)
}
}
```