Relax legacy request metadata validation (#1852)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Tarek Mahmoud Sayed <10833894+tarekgh@users.noreply.github.com>
This commit is contained in:
Stephen Halter 2026-09-13 16:30:42 -07:00 • committed by GitHub
commit 324ccd83c3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -289,11 +289,20 @@ public class McpServerTests : LoggedTest
Assert.Equal(expectedAssemblyName.Version?.ToString() ?? "1.0.0", result.ServerInfo.Version);
Assert.Equal("2024-11-05", result.ProtocolVersion);
Assert.Equal("2024-11-05", server.NegotiatedProtocolVersion);
Assert.True(Assert.IsType<JsonObject>(response)["capabilities"]!.AsObject().ContainsKey("logging"));
});
}
[Fact]
public async Task RejectedReservedPerRequestMetadata_DoesNotEstablishProtocolVersion()
[Theory]
[InlineData("2025-11-25", "\"2025-03-26\"", null)]
[InlineData("2025-11-25", "\"2026-07-28\"", null)]
[InlineData("2025-11-25", "{}", null)]
[InlineData("2026-07-28", "\"2025-11-25\"", McpErrorCode.HeaderMismatch)]
[InlineData("2026-07-28", "\"9999-99-99\"", McpErrorCode.HeaderMismatch)]
[InlineData("2026-07-28", "{}", McpErrorCode.InvalidParams)]
[InlineData("9999-99-99", "{}", McpErrorCode.UnsupportedProtocolVersion)]
public async Task TransportProtocolVersion_IsValidatedBeforeBodyMetadata(
string transportVersion, string metadataVersionJson, McpErrorCode? expectedError)
{
var ct = TestContext.Current.CancellationToken;
await using var transport = new TestServerTransport();
@ -303,71 +312,44 @@ public class McpServerTests : LoggedTest
await using var server = McpServer.Create(transport, options, LoggerFactory);
var runTask = server.RunAsync(ct);
var rejectedResponse = new TaskCompletionSource<JsonRpcError>(TaskCreationOptions.RunContinuationsAsynchronously);
var acceptedResponse = new TaskCompletionSource<JsonRpcMessage>(TaskCreationOptions.RunContinuationsAsynchronously);
var response = new TaskCompletionSource<JsonRpcMessage>(TaskCreationOptions.RunContinuationsAsynchronously);
transport.OnMessageSent = message =>
{
if (message is JsonRpcError { Id: var errorId } error && errorId.ToString() == "1")
if (message is JsonRpcMessageWithId { Id: var responseId } && responseId.ToString() == "1")
{
rejectedResponse.TrySetResult(error);
}
else if (message is JsonRpcMessageWithId { Id: var responseId } && responseId.ToString() == "2")
{
acceptedResponse.TrySetResult(message);
response.TrySetResult(message);
}
};
await transport.SendClientMessageAsync(new JsonRpcRequest
{
Id = new RequestId(1),
Method = RequestMethods.ToolsList,
Method = RequestMethods.Ping,
Params = new JsonObject
{
["_meta"] = new JsonObject
{
[MetaKeys.ClientInfo] = new JsonObject
{
["name"] = "test-client",
["version"] = "1.0.0",
},
[MetaKeys.ProtocolVersion] = JsonNode.Parse(metadataVersionJson),
},
},
Context = new JsonRpcMessageContext
{
ProtocolVersion = McpProtocolVersions.November2025ProtocolVersion,
ProtocolVersion = transportVersion,
ClientInfo = new Implementation { Name = "test-client", Version = "1.0.0" },
},
}, ct);
var error = await rejectedResponse.Task.WaitAsync(TestConstants.DefaultTimeout, ct);
Assert.Equal((int)McpErrorCode.InvalidRequest, error.Error.Code);
Assert.Null(server.NegotiatedProtocolVersion);
var clientInfo = new Implementation { Name = "test-client", Version = "1.0.0" };
var clientCapabilities = new ClientCapabilities();
await transport.SendClientMessageAsync(new JsonRpcRequest
var message = await response.Task.WaitAsync(TestConstants.DefaultTimeout, ct);
if (expectedError is { } errorCode)
{
Id = new RequestId(2),
Method = RequestMethods.ToolsList,
Params = new JsonObject
{
["_meta"] = new JsonObject
{
[MetaKeys.ProtocolVersion] = McpProtocolVersions.July2026ProtocolVersion,
[MetaKeys.ClientInfo] = JsonSerializer.SerializeToNode(clientInfo, McpJsonUtilities.DefaultOptions),
[MetaKeys.ClientCapabilities] = new JsonObject(),
},
},
Context = new JsonRpcMessageContext
{
ProtocolVersion = McpProtocolVersions.July2026ProtocolVersion,
ClientInfo = clientInfo,
ClientCapabilities = clientCapabilities,
},
}, ct);
await acceptedResponse.Task.WaitAsync(TestConstants.DefaultTimeout, ct);
Assert.Equal(McpProtocolVersions.July2026ProtocolVersion, server.NegotiatedProtocolVersion);
Assert.Equal((int)errorCode, Assert.IsType<JsonRpcError>(message).Error.Code);
Assert.Null(server.NegotiatedProtocolVersion);
}
else
{
Assert.IsType<JsonRpcResponse>(message);
Assert.Equal(transportVersion, server.NegotiatedProtocolVersion);
}
await transport.DisposeAsync();
await runTask;