You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
MCP requires specific kotlinx.serialization.json.Json settings (explicitNulls = false, encodeDefaults = true, classDiscriminatorMode = NONE), currently bundled as McpJson. The Ktor server must install ContentNegotiation with this exact configuration:
Conflicts with application-wide JSON configuration. Users may need different Json settings for non-MCP routes (e.g., encodeDefaults = false, prettyPrint = true, custom naming strategies). Because Ktor's ContentNegotiation applies a single Json instance globally, there is no way to use one configuration for MCP endpoints and another for the rest of the application.
Proposal
Inline the required serialization behavior into MCP schema classes (DTOs) using kotlinx.serialization annotations, so they serialize correctly regardless of the global Json configuration.
Class-level settings override global settings, so users would be free to configure ContentNegotiation however they need:
install(ContentNegotiation) {
json() // any configuration — MCP classes carry their own settings
}
Problem
Caused by #664.
MCP requires specific
kotlinx.serialization.json.Jsonsettings (explicitNulls = false,encodeDefaults = true,classDiscriminatorMode = NONE), currently bundled asMcpJson. The Ktor server must installContentNegotiationwith this exact configuration:This creates two problems:
Easy to forget. Users who omit
McpJsonget silent serialization failures at runtime (e.g., explicitnullfields in JSON-RPC responses). Partially addressed by auto-installation in feat(server): auto-install ContentNegotiation with McpJson (#664) #665.Conflicts with application-wide JSON configuration. Users may need different
Jsonsettings for non-MCP routes (e.g.,encodeDefaults = false,prettyPrint = true, custom naming strategies). Because Ktor'sContentNegotiationapplies a singleJsoninstance globally, there is no way to use one configuration for MCP endpoints and another for the rest of the application.Proposal
Inline the required serialization behavior into MCP schema classes (DTOs) using
kotlinx.serializationannotations, so they serialize correctly regardless of the globalJsonconfiguration.Class-level settings override global settings, so users would be free to configure
ContentNegotiationhowever they need: