internal/mcp: update protocol versions
Update protocol versions to reflect that 2025-03-26 is supported, and add server logic to negotiate the supported version with the client. Update the client to set the protocol version, fixing what was probably a spec violation. +tests Change-Id: I564b591b3daf018dd54f5c7e5d8f2d2b1e4ff502 Reviewed-on: https://go-review.googlesource.com/c/tools/+/682516 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
This commit is contained in:
parent
1fead0ba64
commit
5ae2a9f222
8 changed files with 130 additions and 7 deletions
|
|
@ -101,9 +101,13 @@ func (c *Client) Connect(ctx context.Context, t Transport) (cs *ClientSession, e
|
||||||
}
|
}
|
||||||
|
|
||||||
params := &InitializeParams{
|
params := &InitializeParams{
|
||||||
ClientInfo: &implementation{Name: c.name, Version: c.version},
|
ClientInfo: &implementation{Name: c.name, Version: c.version},
|
||||||
Capabilities: caps,
|
Capabilities: caps,
|
||||||
|
ProtocolVersion: "2025-03-26",
|
||||||
}
|
}
|
||||||
|
// TODO(rfindley): handle protocol negotiation gracefully. If the server
|
||||||
|
// responds with 2024-11-05, surface that failure to the caller of connect,
|
||||||
|
// so that they can choose a different transport.
|
||||||
res, err := handleSend[*InitializeResult](ctx, cs, methodInitialize, params)
|
res, err := handleSend[*InitializeResult](ctx, cs, methodInitialize, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = cs.Close()
|
_ = cs.Close()
|
||||||
|
|
|
||||||
16
mcp/conformance_go124_test.go
Normal file
16
mcp/conformance_go124_test.go
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright 2025 The Go MCP SDK Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.24 && goexperiment.synctest
|
||||||
|
|
||||||
|
package mcp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"testing/synctest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func runSyncTest(t *testing.T, f func(t *testing.T)) {
|
||||||
|
synctest.Run(func() { f(t) })
|
||||||
|
}
|
||||||
16
mcp/conformance_go125_test.go
Normal file
16
mcp/conformance_go125_test.go
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright 2025 The Go MCP SDK Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.25
|
||||||
|
|
||||||
|
package mcp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"testing/synctest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func runSyncTest(t *testing.T, f func(t *testing.T)) {
|
||||||
|
synctest.Test(t, f)
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by an MIT-style
|
// Use of this source code is governed by an MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build go1.24 && goexperiment.synctest
|
//go:build (go1.24 && goexperiment.synctest) || go1.25
|
||||||
|
|
||||||
package mcp
|
package mcp
|
||||||
|
|
||||||
|
|
@ -85,7 +85,7 @@ func TestServerConformance(t *testing.T) {
|
||||||
// By comparison, gopls has a complicated framework based on progress
|
// By comparison, gopls has a complicated framework based on progress
|
||||||
// reporting and careful accounting to detect when all 'expected' work
|
// reporting and careful accounting to detect when all 'expected' work
|
||||||
// on the server is complete.
|
// on the server is complete.
|
||||||
synctest.Run(func() { runServerTest(t, test) })
|
runSyncTest(t, func(t *testing.T) { runServerTest(t, test) })
|
||||||
|
|
||||||
// TODO: in 1.25, use the following instead:
|
// TODO: in 1.25, use the following instead:
|
||||||
// synctest.Test(t, func(t *testing.T) {
|
// synctest.Test(t, func(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -634,9 +634,16 @@ func (ss *ServerSession) initialize(ctx context.Context, params *InitializeParam
|
||||||
ss.mu.Unlock()
|
ss.mu.Unlock()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
version := "2025-03-26" // preferred version
|
||||||
|
switch v := params.ProtocolVersion; v {
|
||||||
|
case "2024-11-05", "2025-03-26":
|
||||||
|
version = v
|
||||||
|
}
|
||||||
|
|
||||||
return &InitializeResult{
|
return &InitializeResult{
|
||||||
// TODO(rfindley): support multiple protocol versions.
|
// TODO(rfindley): alter behavior when falling back to an older version:
|
||||||
ProtocolVersion: "2024-11-05",
|
// reject unsupported features.
|
||||||
|
ProtocolVersion: version,
|
||||||
Capabilities: &serverCapabilities{
|
Capabilities: &serverCapabilities{
|
||||||
Prompts: &promptCapabilities{
|
Prompts: &promptCapabilities{
|
||||||
ListChanged: true,
|
ListChanged: true,
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ func TestStreamableServerTransport(t *testing.T) {
|
||||||
Resources: &resourceCapabilities{ListChanged: true},
|
Resources: &resourceCapabilities{ListChanged: true},
|
||||||
Tools: &toolCapabilities{ListChanged: true},
|
Tools: &toolCapabilities{ListChanged: true},
|
||||||
},
|
},
|
||||||
ProtocolVersion: "2024-11-05",
|
ProtocolVersion: "2025-03-26",
|
||||||
ServerInfo: &implementation{Name: "testServer", Version: "v1.0.0"},
|
ServerInfo: &implementation{Name: "testServer", Version: "v1.0.0"},
|
||||||
}, nil)
|
}, nil)
|
||||||
initializedMsg := req(0, "initialized", &InitializedParams{})
|
initializedMsg := req(0, "initialized", &InitializedParams{})
|
||||||
|
|
|
||||||
40
mcp/testdata/conformance/server/version-latest.txtar
vendored
Normal file
40
mcp/testdata/conformance/server/version-latest.txtar
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
Check that when the client sends an arbitrary later version, the server
|
||||||
|
response with its latest supported version.
|
||||||
|
|
||||||
|
-- client --
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 1,
|
||||||
|
"method": "initialize",
|
||||||
|
"params": {
|
||||||
|
"protocolVersion": "2029-01-01",
|
||||||
|
"capabilities": {},
|
||||||
|
"clientInfo": { "name": "ExampleClient", "version": "1.0.0" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-- server --
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 1,
|
||||||
|
"result": {
|
||||||
|
"_meta": {},
|
||||||
|
"capabilities": {
|
||||||
|
"completions": {},
|
||||||
|
"logging": {},
|
||||||
|
"prompts": {
|
||||||
|
"listChanged": true
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"listChanged": true
|
||||||
|
},
|
||||||
|
"tools": {
|
||||||
|
"listChanged": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"protocolVersion": "2025-03-26",
|
||||||
|
"serverInfo": {
|
||||||
|
"name": "testServer",
|
||||||
|
"version": "v1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
mcp/testdata/conformance/server/version-older.txtar
vendored
Normal file
40
mcp/testdata/conformance/server/version-older.txtar
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
Check that when the client sends an older version, the server indicates
|
||||||
|
support.
|
||||||
|
|
||||||
|
-- client --
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 1,
|
||||||
|
"method": "initialize",
|
||||||
|
"params": {
|
||||||
|
"protocolVersion": "2024-11-05",
|
||||||
|
"capabilities": {},
|
||||||
|
"clientInfo": { "name": "ExampleClient", "version": "1.0.0" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-- server --
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 1,
|
||||||
|
"result": {
|
||||||
|
"_meta": {},
|
||||||
|
"capabilities": {
|
||||||
|
"completions": {},
|
||||||
|
"logging": {},
|
||||||
|
"prompts": {
|
||||||
|
"listChanged": true
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"listChanged": true
|
||||||
|
},
|
||||||
|
"tools": {
|
||||||
|
"listChanged": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"protocolVersion": "2024-11-05",
|
||||||
|
"serverInfo": {
|
||||||
|
"name": "testServer",
|
||||||
|
"version": "v1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue