Skip to content

SetLogLevel not recognized and SetLoggingRequest deserialization error #97

Closed
@maschnetwork

Description

@maschnetwork

Bug description

When using MCP Client with setLogLevel the Server can't find the suitable handler:

DEBUG io.modelcontextprotocol.spec.McpSchema - Received JSON message: {"jsonrpc":"2.0","method":"logging/setLevel","params":{"level":"info"}}

DEBUG io.modelcontextprotocol.spec.McpServerSession - Received notification: JSONRPCNotification[jsonrpc=2.0, method=logging/setLevel, params={level=info}]

ERROR io.modelcontextprotocol.spec.McpServerSession - No handler registered for notification method: logging/setLevel

According to the spec setLogLevel should be a request rather than a notification since it contains an id:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "logging/setLevel",
  "params": {
    "level": "info"
  }
}

After changing this to a request there was another problem when deserializing the params since it currently tries to map the above params directly to a LoggingLevel enum:

//Currently tries to map to this
public enum LoggingLevel {// @formatter:off
	@JsonProperty("debug") DEBUG(0),
	@JsonProperty("info") INFO(1)
        //....
}

Would work when using Logging Level in a separate object as outlined in the official json schema:

// This would properly deserialize it
@JsonIgnoreProperties(ignoreUnknown = true)
public record SetLevelRequest(@JsonProperty("level") LoggingLevel level) {
} 

I have a working version ready and can provide a PR for fixing both issues shortly.

Environment

Java version: 17
MCP: 0.8.1

Steps to reproduce

Create a minimal MCP client with StdioTransport and setLoggingLevel. Create a minimal Stdio server that enables logging (See sample below).

Expected behavior
MCP Server should use the existing setLoggerRequestHandler and set the log level properly.

Minimal Complete Reproducible example

Create an MCP Client that leverages setLoggingLevel

public static void main( String[] args ) {
    var transport = new StdioClientTransport(getServerParams());
    try (var mcpClientSync = McpClient.sync(transport).loggingConsumer(loggingConsumer()).build()) {

        mcpClientSync.initialize();
        mcpClientSync.setLoggingLevel(McpSchema.LoggingLevel.INFO);
    }
}

public static ServerParameters getServerParams(){
    return ServerParameters.builder("java").
            args("-jar", "/Users/XXXX/java-mcp-server/target/java-mcp-server-1.0-SNAPSHOT.jar").
            build();
}

private static Consumer<McpSchema.LoggingMessageNotification> loggingConsumer(){
  return loggingMessageNotification -> {
      switch (loggingMessageNotification.level()) {
          case ERROR -> customLogger.error("{}: {}", loggingMessageNotification.logger(), loggingMessageNotification.data());
          case WARNING -> customLogger.warn("{}: {}", loggingMessageNotification.logger(), loggingMessageNotification.data());
          default -> customLogger.info("{}: {}", loggingMessageNotification.logger(), loggingMessageNotification.data());
      }
  };
}

Create an MCP Server with Logging enabled

var transportProvider = new StdioServerTransportProvider();
var mcpServer = McpServer.sync(transportProvider)
        .serverInfo("StandardJavaMCPServer", "1.0.0")
        .capabilities(McpSchema.ServerCapabilities.builder().
                logging().
                build())
        .build();
try {
    while(true) {
        //Do nothing
    }
} catch (Exception e) {
    mcpServer.close();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions