Skip to content

Commit 211d927

Browse files
author
Loi Nguyen
committed
Fix invalid initialize request handling
1 parent 0d34048 commit 211d927

2 files changed

Lines changed: 35 additions & 0 deletions

File tree

src/ModelContextProtocol.AspNetCore/StreamableHttpHandler.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ internal sealed class StreamableHttpHandler(
4545

4646
private static readonly JsonTypeInfo<JsonRpcMessage> s_messageTypeInfo = GetRequiredJsonTypeInfo<JsonRpcMessage>();
4747
private static readonly JsonTypeInfo<JsonRpcError> s_errorTypeInfo = GetRequiredJsonTypeInfo<JsonRpcError>();
48+
private static readonly JsonTypeInfo<InitializeRequestParams> s_initializeRequestParamsTypeInfo = GetRequiredJsonTypeInfo<InitializeRequestParams>();
4849

4950
private static bool AllowNewSessionForNonInitializeRequests { get; } =
5051
AppContext.TryGetSwitch("ModelContextProtocol.AspNetCore.AllowNewSessionForNonInitializeRequests", out var enabled) && enabled;
@@ -116,6 +117,21 @@ await WriteJsonRpcErrorAsync(context,
116117
return;
117118
}
118119

120+
if (message is JsonRpcRequest { Method: RequestMethods.Initialize } initializeRequest)
121+
{
122+
try
123+
{
124+
JsonSerializer.Deserialize(initializeRequest.Params, s_initializeRequestParamsTypeInfo);
125+
}
126+
catch (JsonException ex)
127+
{
128+
await WriteJsonRpcErrorAsync(context,
129+
$"Bad Request: The initialize request parameters were invalid. {ex.Message}",
130+
StatusCodes.Status400BadRequest, (int)McpErrorCode.InvalidParams, requestId);
131+
return;
132+
}
133+
}
134+
119135
var session = await GetOrCreateSessionAsync(context, message, requestId);
120136
if (session is null)
121137
{

tests/ModelContextProtocol.AspNetCore.Tests/StreamableHttpServerConformanceTests.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,25 @@ public async Task PostMalformedJson_Returns400_InvalidRequest_WithNullId()
293293
Assert.Equal((int)McpErrorCode.InvalidRequest, doc.RootElement.GetProperty("error").GetProperty("code").GetInt32());
294294
}
295295

296+
[Fact]
297+
public async Task InitializeWithMissingClientVersion_Returns400_InvalidParams_WithRequestId()
298+
{
299+
await StartAsync();
300+
301+
const string request = """
302+
{"jsonrpc":"2.0","id":7,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"IntegrationTestClient"}}}
303+
""";
304+
305+
using var response = await HttpClient.PostAsync("", JsonContent(request), TestContext.Current.CancellationToken);
306+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
307+
Assert.False(response.Headers.Contains("mcp-session-id"));
308+
309+
using var doc = JsonDocument.Parse(await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken));
310+
Assert.Equal(7, doc.RootElement.GetProperty("id").GetInt64());
311+
Assert.Equal((int)McpErrorCode.InvalidParams, doc.RootElement.GetProperty("error").GetProperty("code").GetInt32());
312+
Assert.Contains("version", doc.RootElement.GetProperty("error").GetProperty("message").GetString(), StringComparison.OrdinalIgnoreCase);
313+
}
314+
296315
[Fact]
297316
public async Task PostRequestWithExplicitNullId_Returns400_InvalidRequest_WithNullId()
298317
{

0 commit comments

Comments
 (0)