mcp: reject requests with bad IDs (#202)

Add an isRequest field to methodInfo, used it to reject non-notification
requests that lack a valid ID. Furthermore, lift this validation to the
transport layer for HTTP server transports, so that we can preemptively
reject bad HTTP requests.

Fixes #194
Fixes #197
This commit is contained in:
Robert Findley 2025-07-30 12:26:40 -04:00 • committed by GitHub
commit 64493be392
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -280,7 +280,7 @@ func TestStreamableServerTransport(t *testing.T) {
}
// Predefined steps, to avoid repetition below.
initReq := req(1, "initialize", &InitializeParams{})
initReq := req(1, methodInitialize, &InitializeParams{})
initResp := resp(1, &InitializeResult{
Capabilities: &serverCapabilities{
Completions: &completionCapabilities{},
@ -290,7 +290,7 @@ func TestStreamableServerTransport(t *testing.T) {
ProtocolVersion: latestProtocolVersion,
ServerInfo: &Implementation{Name: "testServer", Version: "v1.0.0"},
}, nil)
initializedMsg := req(0, "initialized", &InitializedParams{})
initializedMsg := req(0, notificationInitialized, &InitializedParams{})
initialize := step{
Method: "POST",
Send: []jsonrpc.Message{initReq},
@ -438,6 +438,16 @@ func TestStreamableServerTransport(t *testing.T) {
Method: "DELETE",
StatusCode: http.StatusBadRequest,
},
{
Method: "POST",
Send: []jsonrpc.Message{req(1, "notamethod", nil)},
StatusCode: http.StatusBadRequest, // notamethod is an invalid method
},
{
Method: "POST",
Send: []jsonrpc.Message{req(0, "tools/call", &CallToolParams{Name: "tool"})},
StatusCode: http.StatusBadRequest, // tools/call must have an ID
},
{
Method: "POST",
Send: []jsonrpc.Message{req(2, "tools/call", &CallToolParams{Name: "tool"})},