diff --git a/trueref-adapters/src/main/java/com/trueref/adapter/in/rest/JacksonConfig.java b/trueref-adapters/src/main/java/com/trueref/adapter/in/rest/JacksonConfig.java new file mode 100644 index 0000000..850a7d6 --- /dev/null +++ b/trueref-adapters/src/main/java/com/trueref/adapter/in/rest/JacksonConfig.java @@ -0,0 +1,35 @@ +package com.trueref.adapter.in.rest; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.modelcontextprotocol.spec.McpError; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Hardens HTTP JSON serialization for SDK-owned MCP transport errors. + * + *

{@link McpError} extends {@link RuntimeException}. The Streamable HTTP transport returns + * instances of that type directly for malformed requests (for example, missing session headers). + * Without a mixin, Spring MVC serializes inherited {@link Throwable} properties such as + * {@code stackTrace} and {@code cause}, which leaks internal details to clients. + */ +@Configuration +public class JacksonConfig { + + @Bean + public Jackson2ObjectMapperBuilderCustomizer hardenMcpErrorSerialization() { + return builder -> builder.mixIn(McpError.class, McpErrorMixin.class); + } + + @JsonInclude(JsonInclude.Include.NON_NULL) + @JsonIgnoreProperties({ + "cause", + "jsonRpcError", + "localizedMessage", + "stackTrace", + "suppressed" + }) + private abstract static class McpErrorMixin {} +} \ No newline at end of file