Skip to content

Implement a default SetLevelRequestSchema handler #871

Description

@kentcdodds

Describe the bug

The SDK does not automatically handle the logging/setLevel request, even when the server advertises logging capabilities. This requires every server implementation to manually handle this request, which is not ideal.

To Reproduce

Steps to reproduce the behavior:

  1. Create an MCP server that advertises the "logging" capability.
  2. Do not implement a request handler for the logging/setLevel request.
  3. Attempt to connect to this server using the MCP Inspector.
  4. The connection will fail.

Check modelcontextprotocol/inspector#699 for an example

Expected behavior

The MCP SDK should provide a default handler for the logging/setLevel request when a server advertises logging capabilities. This would prevent connection failures and streamline server development.

Additionally, without this, server writers have to check the log level before sending notifications which is troublesome and something the SDK could handle for us.

Additional context

As a workaround, server developers can implement their own handler for the SetLevelRequestSchema. Here is an example:

server.setRequestHandler(SetLevelRequestSchema, request => {
  console.log(`--- Logging level: ${request.params.level}`);
  return {};
});

Activity

  1. jonathansampson commented on Aug 14, 2025

    @jonathansampson

    I came here to request the same after being bit by this same issue yesterday. I found it odd that the MCP-Server class has a method to sendLoggingMessage, understands the SetLevelRequest schema out of the box, and yet has no inherent handling of the latter.

    It was further curious that the MCP Inspector (presumably quite familiar to the SDK team) would initiate a SetLevelRequest upon initialization, only to fall over due to lack of support by servers built using the SDK and examples.

    In addition to a default handler, it seems sendLoggingMessage could be augmented to check the current requested logging state, and decide whether or not to send messages to the client.

    Regarding the workaround, you could also consider wrapping assertCanSetRequestHandler in a try/catch, as it will throw if there already exists a handler for the method. As a result, if/when a native handler is introduced, our custom handler can silently fall off:

    try {
      // https://github.com/modelcontextprotocol/typescript-sdk/issues/871
      const method = SetLevelRequestSchema.shape.method.value;
      // Throws if the method already has a handler
      server.assertCanSetRequestHandler(method);
      server.setRequestHandler(SetLevelRequestSchema, handleSetLevelRequest);
    } catch (error) {}
  2. kentcdodds commented on Sep 8, 2025

    @kentcdodds
    ContributorAuthor

    This is done now. Thanks @cliffhall!

  3. jonathansampson commented on Sep 9, 2025

    @jonathansampson

    Thanks for filing the initial issue, @kentcdodds.

    For those interested in the change, see 79d11dc.

  4. cliffhall commented on Sep 9, 2025

    @cliffhall
    Member

    @jonathansampson

    I came here to request the same after being bit by this same issue yesterday. I found it odd that the MCP-Server class has a method to sendLoggingMessage, understands the SetLevelRequest schema out of the box, and yet has no inherent handling of the latter.

    With the recent change, all servers support recieving the SetLevelRequest message, but unfortunately STDIO servers do not filter the messages according to level. That was because the initial change tracked log levels by session id, which STDIO servers do not have. This allowed multiple clients connected to the same server to set their own levels. SSE and StreamableHTTP servers have full automatic log level filtering if you use the sendLoggingMessage method.

    I have since created a fix for the overlooked STDIO log level handling which will hopefully be merged and included in this next release.

    It was further curious that the MCP Inspector (presumably quite familiar to the SDK team) would initiate a SetLevelRequest upon initialization, only to fall over due to lack of support by servers built using the SDK and examples.

    There was a good reason for this change in behavior.

    Let's review what happened.

    The spec says that, if a server advertises logging as a capability the client MAY send a setLevel request.

    We previously added a log level dropdown to the client to allow the user to change the log level, but of course client and server must agree on the initial log level for the initial value in that combo box to make sense. Thus, we added code to send the message to any server who says they support logging. That is perfectly within spec.

    We later realized that some servers are operating out-of-spec, advertising support for logging but not listening for this message. And yes, tragically, our examples in the SDK were all offenders. The result was that the server would not connect, and it was not clear why.

    This is a tool for devs to make sure their servers are operating properly, so not sending the message and letting out-of spec behavior slide was not the right course of action. Consequently, I added a toast that detected the situation and explained the problem.

    That left us in a position where a) our examples had problems and triggered this toast, and b) all server developers who advertised logging in their servers would have to implement the same boilerplate code we already had in our 'Everything' reference server.

    Therefore I created the automatic log level handling change to the SDK and fixing all the examples (there was no STDIO example, and that's why it slipped through the cracks). So, it worked for SSE and StreamableHttp but not STDIO, but as mentioned above, there is now a fix on deck for that.

    After the next SDK release, the only thing server developers will have to do to avail themselves of the automatic log level handling will be to simply add logging to their capabilities response, and to call sendLoggingMessage with the parameters of the log message on either the Server or McpServer class rather than creating the full message and using notification. That's it.

  5. kentcdodds commented on Sep 9, 2025

    @kentcdodds
    ContributorAuthor

    👍👍👍 Thank you @cliffhall

  6. cliffhall commented on Sep 9, 2025

    @cliffhall
    Member

    BTW, the fix is in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions