Skip to content

Commit 2028ea5

Browse files
committed
Report malformed request bodies as 400 INVALID_REQUEST with jackson3
Fixes #1166 Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
1 parent 88863fc commit 2028ea5

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

‎mcp-json-jackson3/src/main/java/io/modelcontextprotocol/json/jackson3/JacksonMcpJsonMapper.java‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,23 @@ public <T> T readValue(byte[] content, TypeRef<T> type) throws IOException {
8787

8888
@Override
8989
public <T> T convertValue(Object fromValue, Class<T> type) {
90-
return jsonMapper.convertValue(fromValue, type);
90+
try {
91+
return jsonMapper.convertValue(fromValue, type);
92+
}
93+
catch (JacksonException ex) {
94+
throw new IllegalArgumentException(ex);
95+
}
9196
}
9297

9398
@Override
9499
public <T> T convertValue(Object fromValue, TypeRef<T> type) {
95100
JavaType javaType = jsonMapper.getTypeFactory().constructType(type.getType());
96-
return jsonMapper.convertValue(fromValue, javaType);
101+
try {
102+
return jsonMapper.convertValue(fromValue, javaType);
103+
}
104+
catch (JacksonException ex) {
105+
throw new IllegalArgumentException(ex);
106+
}
97107
}
98108

99109
@Override

‎mcp-test/src/test/java/io/modelcontextprotocol/server/HttpServletStatelessIntegrationTests.java‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,26 @@ void rejectsNonJsonContentType(String contentType) throws Exception {
951951
assertThat(toolCalled).isFalse();
952952
}
953953

954+
@Test
955+
void rejectsMalformedMessageAsInvalidRequest() throws Exception {
956+
McpServer.sync(mcpStatelessServerTransport).build();
957+
958+
// Valid JSON, but "jsonrpc" is an object instead of a string, so it cannot be
959+
// converted into a JSONRPCRequest
960+
var request = HttpRequest.newBuilder()
961+
.uri(URI.create("http://localhost:" + PORT + CUSTOM_MESSAGE_ENDPOINT))
962+
.header("Content-Type", APPLICATION_JSON)
963+
.header("Accept", APPLICATION_JSON + ", " + TEXT_EVENT_STREAM)
964+
.POST(HttpRequest.BodyPublishers.ofString("""
965+
{"jsonrpc":{"a":1},"id":1,"method":"tools/list"}"""))
966+
.build();
967+
968+
var response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
969+
970+
assertThat(response.statusCode()).isEqualTo(HttpServletResponse.SC_BAD_REQUEST);
971+
assertThatJson(response.body()).inPath("message").isEqualTo("Invalid message format");
972+
}
973+
954974
private double evaluateExpression(String expression) {
955975
// Simple expression evaluator for testing
956976
return switch (expression) {

0 commit comments

Comments
 (0)