feat: update draft specs to 2026-07-28 (#3699)
This PR updates draft to `2026-07-28`. The `enable-draft-specs` flag will now have no effects towards the server. `DRAFT-2026-v1` will now resolve to unsupported protocol version error. --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
@@ -20,6 +20,7 @@ The Toolbox SDKs can be combined with MCP clients in many cases.
|
||||
|
||||
Toolbox currently supports the following versions of MCP specification:
|
||||
|
||||
* [2026-07-28](https://modelcontextprotocol.io/specification/2026-07-28)
|
||||
* [2025-11-25](https://modelcontextprotocol.io/specification/2025-11-25)
|
||||
* [2025-06-18](https://modelcontextprotocol.io/specification/2025-06-18)
|
||||
* [2025-03-26](https://modelcontextprotocol.io/specification/2025-03-26)
|
||||
|
||||
@@ -770,6 +770,7 @@ Toolbox is fully compatible with the Model Context Protocol (MCP) and maintains
|
||||
### Stable Releases
|
||||
The following official MCP specification versions are currently supported for production use:
|
||||
|
||||
* `2026-07-28`
|
||||
* `2025-11-25`
|
||||
* `2025-06-18`
|
||||
* `2025-03-26`
|
||||
@@ -788,7 +789,7 @@ test these forthcoming revisions before their official release using the
|
||||
|
||||
To test these draft specifications, enable the startup flag and use this version
|
||||
string during negotiation:
|
||||
* `DRAFT-2026-v1`
|
||||
* No supported draft right now
|
||||
|
||||
Description: Enables experimental support for upcoming draft MCP specifications,
|
||||
allowing you to test new schema standards and transport adjustments before they
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
v20250326 "github.com/googleapis/mcp-toolbox/internal/server/mcp/v20250326"
|
||||
v20250618 "github.com/googleapis/mcp-toolbox/internal/server/mcp/v20250618"
|
||||
v20251125 "github.com/googleapis/mcp-toolbox/internal/server/mcp/v20251125"
|
||||
vdraft "github.com/googleapis/mcp-toolbox/internal/server/mcp/vdraft"
|
||||
v20260728 "github.com/googleapis/mcp-toolbox/internal/server/mcp/v20260728"
|
||||
"github.com/googleapis/mcp-toolbox/internal/server/primitives"
|
||||
"github.com/googleapis/mcp-toolbox/internal/util"
|
||||
)
|
||||
@@ -53,11 +53,8 @@ func ProcessMethod(ctx context.Context, mcpVersion string, id jsonrpc.RequestId,
|
||||
return jsonrpc.NewError(id, jsonrpc.INTERNAL_ERROR, err.Error(), nil), err
|
||||
}
|
||||
switch mcpVersion {
|
||||
case mcputil.VERSION_DRAFT:
|
||||
if enableDraft {
|
||||
return vdraft.ProcessMethod(ctx, id, method, g, primitiveMgr, body, header)
|
||||
}
|
||||
return jsonrpc.NewUnsupportedProtocolVersionError(id, mcpVersion, enableDraft)
|
||||
case mcputil.VERSION_20260728:
|
||||
return v20260728.ProcessMethod(ctx, id, method, g, primitiveMgr, body, header)
|
||||
case mcputil.VERSION_20251125:
|
||||
return v20251125.ProcessMethod(ctx, id, method, g, primitiveMgr, body, header)
|
||||
case mcputil.VERSION_20250618:
|
||||
|
||||
@@ -19,7 +19,7 @@ const (
|
||||
VERSION_20250326 = "2025-03-26"
|
||||
VERSION_20250618 = "2025-06-18"
|
||||
VERSION_20251125 = "2025-11-25"
|
||||
VERSION_DRAFT = "DRAFT-2026-v1"
|
||||
VERSION_20260728 = "2026-07-28"
|
||||
)
|
||||
|
||||
// LATEST_PROTOCOL_VERSION is the latest version of the MCP protocol supported.
|
||||
@@ -28,7 +28,7 @@ const LATEST_PROTOCOL_VERSION = VERSION_20251125
|
||||
|
||||
// LATEST_PROTOCOL_VERSION_NONSTABLE is the latest version of the MCP protocol
|
||||
// supported that includes non-stable version
|
||||
const LATEST_PROTOCOL_VERSION_NONSTABLE = VERSION_DRAFT
|
||||
const LATEST_PROTOCOL_VERSION_NONSTABLE = VERSION_20260728
|
||||
|
||||
// SUPPORTED_PROTOCOL_VERSIONS is the MCP protocol versions that are supported.
|
||||
var SUPPORTED_PROTOCOL_VERSIONS = []string{
|
||||
@@ -36,11 +36,10 @@ var SUPPORTED_PROTOCOL_VERSIONS = []string{
|
||||
VERSION_20250326,
|
||||
VERSION_20250618,
|
||||
VERSION_20251125,
|
||||
VERSION_20260728,
|
||||
}
|
||||
|
||||
var SUPPORTED_PROTOCOL_VERSIONS_NONSTABLE = []string{
|
||||
VERSION_DRAFT,
|
||||
}
|
||||
var SUPPORTED_PROTOCOL_VERSIONS_NONSTABLE = []string{}
|
||||
|
||||
func GetSupportedVersions(enableDraft bool) []string {
|
||||
if enableDraft {
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vdraft
|
||||
package v20260728
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vdraft
|
||||
package v20260728
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vdraft
|
||||
package v20260728
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vdraft
|
||||
package v20260728
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vdraft
|
||||
package v20260728
|
||||
|
||||
import (
|
||||
"github.com/googleapis/mcp-toolbox/internal/server/mcp/jsonrpc"
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
const SERVER_NAME = "Toolbox"
|
||||
|
||||
// PROTOCOL_VERSION is the version of the MCP protocol in this package.
|
||||
const PROTOCOL_VERSION = util.VERSION_DRAFT
|
||||
const PROTOCOL_VERSION = util.VERSION_20260728
|
||||
|
||||
// methods that are supported.
|
||||
const (
|
||||
@@ -48,7 +48,7 @@ const protocolVersion20241105 = "2024-11-05"
|
||||
const protocolVersion20250326 = "2025-03-26"
|
||||
const protocolVersion20250618 = "2025-06-18"
|
||||
const protocolVersion20251125 = "2025-11-25"
|
||||
const protocolVersionDraft = "DRAFT-2026-v1"
|
||||
const protocolVersion20260728 = "2026-07-28"
|
||||
const serverName = "Toolbox"
|
||||
|
||||
var basicInputSchema = map[string]any{
|
||||
@@ -562,13 +562,13 @@ func TestMcpEndpoint(t *testing.T) {
|
||||
invalidMethods: []string{"server/discover"},
|
||||
},
|
||||
{
|
||||
name: "version DRAFT",
|
||||
protocol: protocolVersionDraft,
|
||||
name: "version 2026-07-28",
|
||||
protocol: protocolVersion20260728,
|
||||
idHeader: false,
|
||||
reqHeader: []string{"Mcp-Protocol-Version", "Mcp-Method", "Mcp-Name"},
|
||||
invalidMethods: []string{"ping"},
|
||||
meta: map[string]any{
|
||||
"io.modelcontextprotocol/protocolVersion": protocolVersionDraft,
|
||||
"io.modelcontextprotocol/protocolVersion": protocolVersion20260728,
|
||||
"io.modelcontextprotocol/clientInfo": map[string]any{
|
||||
"version": "client-temp-version",
|
||||
"name": "client-name",
|
||||
@@ -845,7 +845,7 @@ func TestMcpEndpoint(t *testing.T) {
|
||||
"id": "server-discover",
|
||||
"result": map[string]any{
|
||||
"resultType": "complete",
|
||||
"supportedVersions": []any{"2024-11-05", "2025-03-26", "2025-06-18", "2025-11-25", "DRAFT-2026-v1"},
|
||||
"supportedVersions": []any{"2024-11-05", "2025-03-26", "2025-06-18", "2025-11-25", "2026-07-28"},
|
||||
"capabilities": map[string]any{
|
||||
"tools": map[string]any{"listChanged": false},
|
||||
"prompts": map[string]any{"listChanged": false},
|
||||
@@ -1396,9 +1396,9 @@ func TestMcpEndpointWithoutEnablingDraftSpecs(t *testing.T) {
|
||||
ts := runServer(r, false)
|
||||
defer ts.Close()
|
||||
|
||||
protocol := protocolVersionDraft
|
||||
protocol := "DRAFT"
|
||||
meta := map[string]any{
|
||||
"io.modelcontextprotocol/protocolVersion": protocolVersionDraft,
|
||||
"io.modelcontextprotocol/protocolVersion": protocol,
|
||||
"io.modelcontextprotocol/clientInfo": map[string]any{
|
||||
"version": "client-temp-version",
|
||||
"name": "client-name",
|
||||
@@ -1422,8 +1422,8 @@ func TestMcpEndpointWithoutEnablingDraftSpecs(t *testing.T) {
|
||||
"error": map[string]interface{}{
|
||||
"code": float64(-32022),
|
||||
"data": map[string]interface{}{
|
||||
"requested": "DRAFT-2026-v1",
|
||||
"supported": []interface{}{"2024-11-05", "2025-03-26", "2025-06-18", "2025-11-25"},
|
||||
"requested": "DRAFT",
|
||||
"supported": []interface{}{"2024-11-05", "2025-03-26", "2025-06-18", "2025-11-25", "2026-07-28"},
|
||||
},
|
||||
"message": "unsupported protocol version",
|
||||
},
|
||||
|
||||
@@ -175,7 +175,7 @@ func TestMcpAuth(t *testing.T) {
|
||||
token string
|
||||
method string
|
||||
url string
|
||||
body []byte
|
||||
body map[string]any
|
||||
wantStatusCode int
|
||||
checkWWWAuth func(t *testing.T, authHeader string)
|
||||
}{
|
||||
@@ -219,20 +219,17 @@ func TestMcpAuth(t *testing.T) {
|
||||
token: tokenOnlyReadStr,
|
||||
method: http.MethodPost,
|
||||
url: apiMCP,
|
||||
body: func() []byte {
|
||||
b, _ := json.Marshal(map[string]any{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"method": "tools/call",
|
||||
"params": map[string]any{
|
||||
"name": "my-tool",
|
||||
"arguments": map[string]any{
|
||||
"sql": "SELECT 1;",
|
||||
},
|
||||
body: map[string]any{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"method": "tools/call",
|
||||
"params": map[string]any{
|
||||
"name": "my-tool",
|
||||
"arguments": map[string]any{
|
||||
"sql": "SELECT 1;",
|
||||
},
|
||||
})
|
||||
return b
|
||||
}(),
|
||||
},
|
||||
},
|
||||
wantStatusCode: http.StatusForbidden,
|
||||
checkWWWAuth: func(t *testing.T, authHeader string) {
|
||||
if !strings.Contains(authHeader, `error="insufficient_scope"`) || !strings.Contains(authHeader, `scope="execute:sql"`) {
|
||||
@@ -245,20 +242,17 @@ func TestMcpAuth(t *testing.T) {
|
||||
token: tokenBothStr,
|
||||
method: http.MethodPost,
|
||||
url: apiMCP,
|
||||
body: func() []byte {
|
||||
b, _ := json.Marshal(map[string]any{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"method": "tools/call",
|
||||
"params": map[string]any{
|
||||
"name": "my-tool",
|
||||
"arguments": map[string]any{
|
||||
"sql": "SELECT 1;",
|
||||
},
|
||||
body: map[string]any{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"method": "tools/call",
|
||||
"params": map[string]any{
|
||||
"name": "my-tool",
|
||||
"arguments": map[string]any{
|
||||
"sql": "SELECT 1;",
|
||||
},
|
||||
})
|
||||
return b
|
||||
}(),
|
||||
},
|
||||
},
|
||||
wantStatusCode: http.StatusOK,
|
||||
},
|
||||
}
|
||||
@@ -277,7 +271,23 @@ func TestMcpAuth(t *testing.T) {
|
||||
runTest := func(t *testing.T, protocolVersion string) {
|
||||
var body io.Reader
|
||||
if tc.body != nil {
|
||||
body = bytes.NewBuffer(tc.body)
|
||||
if protocolVersion == "2026-07-28" {
|
||||
if params, ok := tc.body["params"].(map[string]any); ok {
|
||||
params["_meta"] = map[string]any{
|
||||
"io.modelcontextprotocol/protocolVersion": protocolVersion,
|
||||
"io.modelcontextprotocol/clientInfo": map[string]string{
|
||||
"name": "testClient",
|
||||
"version": "0.0.0",
|
||||
},
|
||||
"io.modelcontextprotocol/clientCapabilities": struct{}{},
|
||||
}
|
||||
}
|
||||
}
|
||||
b, err := json.Marshal(tc.body)
|
||||
if err != nil {
|
||||
t.Fatalf("error marshaling body: %s", err)
|
||||
}
|
||||
body = bytes.NewBuffer(b)
|
||||
}
|
||||
req, _ := http.NewRequest(method, url, body)
|
||||
if tc.token != "" {
|
||||
@@ -288,6 +298,10 @@ func TestMcpAuth(t *testing.T) {
|
||||
if protocolVersion != "" {
|
||||
req.Header.Set("MCP-Protocol-Version", protocolVersion)
|
||||
}
|
||||
if protocolVersion == "2026-07-28" {
|
||||
req.Header.Set("Mcp-Method", "tools/call")
|
||||
req.Header.Set("Mcp-Name", "my-tool")
|
||||
}
|
||||
}
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
@@ -307,7 +321,7 @@ func TestMcpAuth(t *testing.T) {
|
||||
}
|
||||
|
||||
if method == http.MethodPost {
|
||||
versions := []string{"2024-11-05", "2025-03-26", "2025-06-18", "2025-11-25"}
|
||||
versions := []string{"2024-11-05", "2025-03-26", "2025-06-18", "2025-11-25", "2026-07-28"}
|
||||
for _, v := range versions {
|
||||
t.Run("version_"+v, func(t *testing.T) {
|
||||
runTest(t, v)
|
||||
|
||||
Reference in New Issue
Block a user