Skip to content

fix: accept logging/setLevel and ping before initialized notification#730

Open
DaleSeo wants to merge 2 commits intomainfrom
fix/server-accept-pre-init-requests
Open

fix: accept logging/setLevel and ping before initialized notification#730
DaleSeo wants to merge 2 commits intomainfrom
fix/server-accept-pre-init-requests

Conversation

@DaleSeo
Copy link
Member

@DaleSeo DaleSeo commented Mar 7, 2026

Fixes #704

Motivation and Context

VS Code's MCP client sends a logging/setLevel request right after the server responds to initialize, but before the initialized notification. The server expects a notification at that moment and errors out on any other message, which causes the entire handshake to fail.

The MCP lifecycle spec states: "The server SHOULD NOT send requests other than pings and logging before receiving the initialized notification." This means the server can send log messages during initialization, so it's reasonable for a client to set log levels before sending initialized. The client side of this codebase already handles the symmetric case with a loop, and this fix aligns the server with that same approach.

// Server could send logging messages before handshake
ServerJsonRpcMessage::Notification(mut notification) => {
let ServerNotification::LoggingMessageNotification(logging) =
&mut notification.notification
else {
tracing::warn!(?notification, "Received unexpected message");
continue;
};
let mut context = NotificationContext {
peer: peer.clone(),
meta: Meta::default(),
extensions: Extensions::default(),
};
if let Some(meta) = logging.extensions.get_mut::<Meta>() {
std::mem::swap(&mut context.meta, meta);
}
std::mem::swap(&mut context.extensions, &mut logging.extensions);
if let Err(error) = service
.handle_notification(notification.notification, context)
.await
{
tracing::warn!(?error, "Handle logging before handshake failed.");
}
}
// Server could send pings before handshake
ServerJsonRpcMessage::Request(ref request)
if matches!(request.request, ServerRequest::PingRequest(_)) =>
{
tracing::trace!("Received ping request. Ignored.")
}
// Server SHOULD NOT send any other messages before handshake. We ignore them anyway
_ => tracing::warn!(?message, "Received unexpected message"),
}
}

How Has This Been Tested?

Added integration tests. I also manually verified the fix on VSCode.

2026-03-07 at 10 18 39

Breaking Changes

None. The change only relaxes what the server accepts during initialization; the error path for truly unexpected messages is unchanged.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

@DaleSeo DaleSeo self-assigned this Mar 7, 2026
@github-actions github-actions bot added T-core Core library changes T-service Service layer changes labels Mar 7, 2026
@DaleSeo DaleSeo marked this pull request as ready for review March 7, 2026 15:25
@DaleSeo DaleSeo requested a review from a team as a code owner March 7, 2026 15:25
@github-actions github-actions bot added the T-test Testing related changes label Mar 7, 2026
@DaleSeo DaleSeo force-pushed the fix/server-accept-pre-init-requests branch from 43dcf28 to 397e9ac Compare March 7, 2026 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-core Core library changes T-service Service layer changes T-test Testing related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Server initialization fails with VS Code: rejects logging/setLevel request before initialized notification

1 participant