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:
Yuan Teoh
2026-07-27 16:55:28 -07:00
committed by GitHub
parent 8903cbe87a
commit cf128ff94c
11 changed files with 68 additions and 56 deletions
@@ -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)
+2 -1
View File
@@ -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
+3 -6
View File
@@ -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:
+4 -5
View File
@@ -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 {
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package vdraft
package v20260728
import (
"fmt"
@@ -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"
@@ -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 (
+9 -9
View File
@@ -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",
},
+43 -29
View File
@@ -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)