Skip to content

mcp: batch without MCP-Protocol-Version is accepted when SupportedProtocolVersions excludes 2025-03-26 #1513

Open

Description

@emgeorrk

Checklist

  • I searched the existing issues, and this has not been reported before.
  • This is a real problem that I ran into myself, using the latest release of the SDK.
  • I ran into it in a production system, not in a toy example, a benchmark, or an automated or AI-driven scan of the code.
  • I (a human) examined the relevant SDK code, and wrote or reviewed every line of this report. It is not unreviewed AI output.
  • This report is brief and concise, and sticks to the facts needed to understand the problem.

What happened?

With ServerOptions.SupportedProtocolVersions limited to versions without JSON-RPC batching (2025-06-18 and later), the Streamable HTTP handler still accepts a batch sent without the MCP-Protocol-Version header and runs every call in it. The same batch with MCP-Protocol-Version: 2025-03-26 is rejected as an unsupported version.

servePOST falls back to 2025-03-26 when the header is missing, and the batch check compares only that fallback with 2025-06-18. It does not consider which versions the server supports.

Expected: 400 for the header-less batch when no supported version allows batching, as with the explicit 2025-03-26 header. Single messages without the header (such as initialize) should keep working.

I have a fix with a regression test and would like to send it as a PR if this is assigned to me.

I used Claude Code (AI) to investigate this and draft the report; I reviewed it.

How to reproduce

package main

import (
	"log"
	"net/http"

	"github.com/modelcontextprotocol/go-sdk/mcp"
)

func main() {
	server := mcp.NewServer(&mcp.Implementation{Name: "repro", Version: "v0.0.1"}, &mcp.ServerOptions{
		SupportedProtocolVersions: []string{"2026-07-28", "2025-11-25", "2025-06-18"},
	})
	handler := mcp.NewStreamableHTTPHandler(func(*http.Request) *mcp.Server { return server },
		&mcp.StreamableHTTPOptions{Stateless: true, JSONResponse: true})
	log.Fatal(http.ListenAndServe("127.0.0.1:8080", handler))
}

// BODY='[{"jsonrpc":"2.0","id":1,"method":"ping"},{"jsonrpc":"2.0","id":2,"method":"ping"}]'
// curl -s http://127.0.0.1:8080 -H 'Content-Type: application/json' \
//   -H 'Accept: application/json, text/event-stream' -d "$BODY"
//
// No header:                         200 [{"jsonrpc":"2.0","id":2,"result":{}},{"jsonrpc":"2.0","id":1,"result":{}}]
// MCP-Protocol-Version: 2025-03-26:  400 Bad Request: Unsupported protocol version (supported versions: 2026-07-28,2025-11-25,2025-06-18)
// MCP-Protocol-Version: 2025-06-18:  400 JSON-RPC batching is not supported in 2025-06-18 and later

Where did you hit this?

A public read-only documentation MCP server (stateless Streamable HTTP, JSON responses) where we wanted to stop accepting legacy JSON-RPC batches.

Go MCP SDK version

v1.8.0 (also reproduced on main at 0e849cb)

Go version

go version go1.27.1 darwin/arm64

Logs

No response

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions