Skip to content

Commit 77b5d6b

Browse files
Loi Nguyenlntutor
authored andcommitted
Fix invalid initialize request handling
1 parent 155f619 commit 77b5d6b

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

src/ModelContextProtocol.AspNetCore/StreamableHttpHandler.cs

Lines changed: 23 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;
@@ -145,6 +146,28 @@ await WriteJsonRpcErrorAsync(context,
145146
return;
146147
}
147148

149+
if (message is JsonRpcRequest { Method: RequestMethods.Initialize } initializeRequest)
150+
{
151+
try
152+
{
153+
var initializeParams = JsonSerializer.Deserialize(initializeRequest.Params, s_initializeRequestParamsTypeInfo);
154+
if (initializeParams is null)
155+
{
156+
await WriteJsonRpcErrorAsync(context,
157+
"Bad Request: The initialize request parameters were invalid.",
158+
StatusCodes.Status400BadRequest, (int)McpErrorCode.InvalidParams, requestId);
159+
return;
160+
}
161+
}
162+
catch (JsonException ex)
163+
{
164+
await WriteJsonRpcErrorAsync(context,
165+
$"Bad Request: The initialize request parameters were invalid. {ex.Message}",
166+
StatusCodes.Status400BadRequest, (int)McpErrorCode.InvalidParams, requestId);
167+
return;
168+
}
169+
}
170+
148171
var session = await GetOrCreateSessionAsync(context, message, requestId);
149172
if (session is null)
150173
{

tests/ModelContextProtocol.AspNetCore.Tests/StreamableHttpServerConformanceTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,40 @@ public async Task PostMalformedJson_Returns400_InvalidRequest_WithNullId()
318318
Assert.Equal((int)McpErrorCode.InvalidRequest, doc.RootElement.GetProperty("error").GetProperty("code").GetInt32());
319319
}
320320

321+
[Fact]
322+
public async Task InitializeWithMissingClientVersion_Returns400_InvalidParams_WithRequestId()
323+
{
324+
await StartAsync();
325+
326+
const string request = """
327+
{"jsonrpc":"2.0","id":7,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"IntegrationTestClient"}}}
328+
""";
329+
330+
using var response = await HttpClient.PostAsync("", JsonContent(request), TestContext.Current.CancellationToken);
331+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
332+
Assert.False(response.Headers.Contains("mcp-session-id"));
333+
334+
using var doc = JsonDocument.Parse(await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken));
335+
Assert.Equal(7, doc.RootElement.GetProperty("id").GetInt64());
336+
Assert.Equal((int)McpErrorCode.InvalidParams, doc.RootElement.GetProperty("error").GetProperty("code").GetInt32());
337+
Assert.Contains("version", doc.RootElement.GetProperty("error").GetProperty("message").GetString(), StringComparison.OrdinalIgnoreCase);
338+
}
339+
340+
[Theory]
341+
[InlineData("{\"jsonrpc\":\"2.0\",\"id\":8,\"method\":\"initialize\"}")]
342+
[InlineData("{\"jsonrpc\":\"2.0\",\"id\":9,\"method\":\"initialize\",\"params\":null}")]
343+
public async Task InitializeWithMissingOrNullParams_Returns400_InvalidParams_WithoutCreatingSession(string request)
344+
{
345+
await StartAsync();
346+
347+
using var response = await HttpClient.PostAsync("", JsonContent(request), TestContext.Current.CancellationToken);
348+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
349+
Assert.False(response.Headers.Contains("mcp-session-id"));
350+
351+
using var doc = JsonDocument.Parse(await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken));
352+
Assert.Equal((int)McpErrorCode.InvalidParams, doc.RootElement.GetProperty("error").GetProperty("code").GetInt32());
353+
}
354+
321355
[Fact]
322356
public async Task PostRequestWithExplicitNullId_Returns400_InvalidRequest_WithNullId()
323357
{

0 commit comments

Comments
 (0)