Improve protocol version handling (#468)

Right now by default, the client and server hardcode the initial spec version, and if there's a mismatch, the request fails.

With this change, by default both client and server are allowed to float to any supported version.
This commit is contained in:
Stephen Toub 2025-06-02 23:03:57 -04:00 • committed by GitHub
commit e0b058f260
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 45 additions and 12 deletions

View file

@ -161,9 +161,20 @@ internal sealed class McpServer : McpEndpoint, IMcpServer
UpdateEndpointNameWithClientInfo();
GetSessionOrThrow().EndpointName = EndpointName;
// Negotiate a protocol version. If the server options provide one, use that.
// Otherwise, try to use whatever the client requested as long as it's supported.
// If it's not supported, fall back to the latest supported version.
string? protocolVersion = options.ProtocolVersion;
if (protocolVersion is null)
{
protocolVersion = request?.ProtocolVersion is string clientProtocolVersion && McpSession.SupportedProtocolVersions.Contains(clientProtocolVersion) ?
clientProtocolVersion :
McpSession.LatestProtocolVersion;
}
return new InitializeResult
{
ProtocolVersion = options.ProtocolVersion,
ProtocolVersion = protocolVersion,
Instructions = options.ServerInstructions,
ServerInfo = options.ServerInfo ?? DefaultImplementation,
Capabilities = ServerCapabilities ?? new(),

View file

@ -32,8 +32,11 @@ public class McpServerOptions
/// <remarks>
/// The protocol version defines which features and message formats this server supports.
/// This uses a date-based versioning scheme in the format "YYYY-MM-DD".
/// If <see langword="null"/>, the server will advertize to the client the version requested
/// by the client if that version is known to be supported, and otherwise will advertize the latest
/// version supported by the server.
/// </remarks>
public string ProtocolVersion { get; set; } = "2024-11-05";
public string? ProtocolVersion { get; set; }
/// <summary>
/// Gets or sets a timeout used for the client-server initialization handshake sequence.