Describe the bug
The logging/setLevel handler accepts level values that are not defined by the LoggingLevel enum. In both tested SDK versions, the server stores the invalid value and returns a successful empty result. When the stored value is used in severity comparisons, unknown levels map to debug.
The 2025-11-25 schema defines LoggingLevel as a closed enum:
"LoggingLevel": {
"enum": ["alert", "critical", "debug", "emergency", "error", "info", "notice", "warning"],
"type": "string"
}
And SetLevelRequestParams.level is required and typed as LoggingLevel.
Environment tested:
- Stable release:
v1.6.1 (d454bba)
- Prerelease: v1.7.0-pre.2 (
b426fbf)
- Server used:
conformance/everything-server
- Transports: stdio, stateful/stateless HTTP (all reproduce)
To Reproduce
Steps to reproduce the behavior:
- Start the Go SDK server.
- Initialize a session using protocol version 2025-11-25.
- Send a
logging/setLevel request with an invalid level value:
{"jsonrpc":"2.0","id":1001,"method":"logging/setLevel","params":{"level":"not_a_valid_level"}}
- Observe that the server returns a successful result.
Expected behavior
The server should reject the request with -32602 Invalid params, because "not_a_valid_level" is not one of the eight LoggingLevel enum values.
Logs
The server accepts the invalid level and returns {"jsonrpc":"2.0","id":1001,"result":{}}.
This behavior reproduces in both tested SDK versions across all three transports.
Additional context
In mcp/server.go, setLevel stores params.Level unconditionally:
func (ss *ServerSession) setLevel(_ context.Context, params *SetLoggingLevelParams) (*emptyResult, error) {
ss.updateState(func(state *ServerSessionState) {
state.LogLevel = params.Level
})
ss.server.opts.Logger.Info("client log level set", "level", params.Level)
return &emptyResult{}, nil
}
LoggingLevel is type LoggingLevel string in mcp/protocol.go, so Go's type system does not enforce the enum constraint.
In mcp/logging.go, mcpLevelToSlog defaults unknown levels to LevelDebug:
func mcpLevelToSlog(ll LoggingLevel) slog.Level {
if sl, ok := mcpToSlog[ll]; ok {
return sl
}
return LevelDebug
}
As a result, an invalid level is treated as the debug threshold during severity comparisons rather than being rejected by logging/setLevel.
The logging feature is marked deprecated (SEP-2577), but it remains functional during the deprecation window.
Describe the bug
The
logging/setLevelhandler acceptslevelvalues that are not defined by theLoggingLevelenum. In both tested SDK versions, the server stores the invalid value and returns a successful empty result. When the stored value is used in severity comparisons, unknown levels map todebug.The 2025-11-25 schema defines
LoggingLevelas a closed enum:And
SetLevelRequestParams.levelis required and typed asLoggingLevel.Environment tested:
v1.6.1(d454bba)b426fbf)conformance/everything-serverTo Reproduce
Steps to reproduce the behavior:
logging/setLevelrequest with an invalid level value:{"jsonrpc":"2.0","id":1001,"method":"logging/setLevel","params":{"level":"not_a_valid_level"}}Expected behavior
The server should reject the request with
-32602 Invalid params, because"not_a_valid_level"is not one of the eightLoggingLevelenum values.Logs
The server accepts the invalid level and returns
{"jsonrpc":"2.0","id":1001,"result":{}}.This behavior reproduces in both tested SDK versions across all three transports.
Additional context
In
mcp/server.go,setLevelstoresparams.Levelunconditionally:LoggingLevelistype LoggingLevel stringinmcp/protocol.go, so Go's type system does not enforce the enum constraint.In
mcp/logging.go,mcpLevelToSlogdefaults unknown levels toLevelDebug:As a result, an invalid level is treated as the debug threshold during severity comparisons rather than being rejected by logging/setLevel.
The logging feature is marked deprecated (SEP-2577), but it remains functional during the deprecation window.