From bd2a2eaaf3500896262e397553d81a0603179b02 Mon Sep 17 00:00:00 2001 From: Avichay Marciano Date: Mon, 9 Feb 2026 16:40:57 +0200 Subject: [PATCH] [FLINK-AGENTS] Fix MCPTool Jackson deserialization by ignoring unknown properties MCPTool deserialization fails with UnrecognizedPropertyException when a default ObjectMapper encounters the 'name' and 'description' fields serialized from the parent Tool class. These fields are not declared in MCPTool's @JsonCreator constructor. This breaks checkpoint/restore and any JSON round-trip of MCPTool. Add @JsonIgnoreProperties(ignoreUnknown = true) to MCPTool and a regression test that uses a default ObjectMapper (the existing test masked the bug by disabling FAIL_ON_UNKNOWN_PROPERTIES globally). --- .../agents/integrations/mcp/MCPTool.java | 2 ++ .../agents/integrations/mcp/MCPToolTest.java | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/integrations/mcp/src/main/java/org/apache/flink/agents/integrations/mcp/MCPTool.java b/integrations/mcp/src/main/java/org/apache/flink/agents/integrations/mcp/MCPTool.java index 286fb2d44..726c1f198 100644 --- a/integrations/mcp/src/main/java/org/apache/flink/agents/integrations/mcp/MCPTool.java +++ b/integrations/mcp/src/main/java/org/apache/flink/agents/integrations/mcp/MCPTool.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.flink.agents.api.tools.Tool; import org.apache.flink.agents.api.tools.ToolMetadata; @@ -38,6 +39,7 @@ *

This represents a single tool from an MCP server. It extends the base Tool class and delegates * actual execution to the MCP server. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class MCPTool extends Tool { private static final String FIELD_MCP_SERVER = "mcpServer"; diff --git a/integrations/mcp/src/test/java/org/apache/flink/agents/integrations/mcp/MCPToolTest.java b/integrations/mcp/src/test/java/org/apache/flink/agents/integrations/mcp/MCPToolTest.java index 2d89cb4da..b3328caab 100644 --- a/integrations/mcp/src/test/java/org/apache/flink/agents/integrations/mcp/MCPToolTest.java +++ b/integrations/mcp/src/test/java/org/apache/flink/agents/integrations/mcp/MCPToolTest.java @@ -34,6 +34,27 @@ class MCPToolTest { private static final String DEFAULT_ENDPOINT = "http://localhost:8000/mcp"; + @Test + @DisabledOnJre(JRE.JAVA_11) + @DisplayName("JSON deserialization works with default ObjectMapper (no FAIL_ON_UNKNOWN_PROPERTIES override)") + void testJsonDeserializationWithDefaultMapper() throws Exception { + ToolMetadata metadata = + new ToolMetadata("add", "Add two numbers", "{\"type\":\"object\"}"); + MCPServer server = new MCPServer(DEFAULT_ENDPOINT); + MCPTool original = new MCPTool(metadata, server); + + // Use a default ObjectMapper — this would fail without @JsonIgnoreProperties + // because Tool.getName()/getDescription() are serialized but MCPTool's + // @JsonCreator only accepts metadata + mcpServer. + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(original); + MCPTool deserialized = mapper.readValue(json, MCPTool.class); + + assertThat(deserialized.getName()).isEqualTo("add"); + assertThat(deserialized.getMetadata()).isEqualTo(metadata); + assertThat(deserialized.getMcpServer()).isEqualTo(server); + } + @Test @DisabledOnJre(JRE.JAVA_11) @DisplayName("Create MCPTool with metadata and server")