Skip to content

Commit 5e3acc4

Browse files
authored
Merge branch 'main' into feat/sync-stateless-repositories
2 parents e8a13ef + fd00498 commit 5e3acc4

2 files changed

Lines changed: 81 additions & 4 deletions

File tree

mcp-core/src/main/java/io/modelcontextprotocol/server/McpStatelessAsyncServer.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,26 @@ public class McpStatelessAsyncServer {
152152

153153
this.protocolVersions = new ArrayList<>(mcpTransport.protocolVersions());
154154

155-
McpStatelessServerHandler handler = new DefaultMcpStatelessServerHandler(requestHandlers, Map.of());
155+
Map<String, McpStatelessNotificationHandler> notificationHandlers = prepareNotificationHandlers();
156+
McpStatelessServerHandler handler = new DefaultMcpStatelessServerHandler(requestHandlers, notificationHandlers);
156157
mcpTransport.setMcpHandler(handler);
157158
}
158159

160+
private Map<String, McpStatelessNotificationHandler> prepareNotificationHandlers() {
161+
Map<String, McpStatelessNotificationHandler> notificationHandlers = new HashMap<>();
162+
163+
notificationHandlers.put(McpSchema.METHOD_NOTIFICATION_INITIALIZED, (exchange, params) -> {
164+
logger.debug("Received {}", McpSchema.METHOD_NOTIFICATION_INITIALIZED);
165+
return Mono.empty();
166+
});
167+
notificationHandlers.put(McpSchema.METHOD_NOTIFICATION_ROOTS_LIST_CHANGED, (exchange, params) -> {
168+
logger.debug("Received {}", McpSchema.METHOD_NOTIFICATION_ROOTS_LIST_CHANGED);
169+
return Mono.empty();
170+
});
171+
172+
return notificationHandlers;
173+
}
174+
159175
// ---------------------------------------
160176
// Lifecycle Management
161177
// ---------------------------------------

mcp-test/src/test/java/io/modelcontextprotocol/server/HttpServletStatelessIntegrationTests.java

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
import java.util.function.BiFunction;
1212
import java.util.function.Function;
1313

14+
import ch.qos.logback.classic.Level;
15+
import ch.qos.logback.classic.Logger;
16+
import ch.qos.logback.classic.spi.ILoggingEvent;
17+
import ch.qos.logback.core.read.ListAppender;
1418
import io.modelcontextprotocol.client.McpClient;
1519
import io.modelcontextprotocol.client.transport.HttpClientStreamableHttpTransport;
1620
import io.modelcontextprotocol.common.McpTransportContext;
@@ -42,13 +46,13 @@
4246
import org.junit.jupiter.api.BeforeEach;
4347
import org.junit.jupiter.api.Test;
4448
import org.junit.jupiter.api.Timeout;
49+
import org.slf4j.LoggerFactory;
50+
import reactor.core.publisher.Mono;
51+
import reactor.test.StepVerifier;
4552

4653
import org.springframework.mock.web.MockHttpServletRequest;
4754
import org.springframework.mock.web.MockHttpServletResponse;
4855
import org.springframework.web.client.RestClient;
49-
import reactor.core.publisher.Mono;
50-
import reactor.test.StepVerifier;
51-
5256
import static io.modelcontextprotocol.server.transport.HttpServletStatelessServerTransport.APPLICATION_JSON;
5357
import static io.modelcontextprotocol.server.transport.HttpServletStatelessServerTransport.TEXT_EVENT_STREAM;
5458
import static io.modelcontextprotocol.util.McpJsonMapperUtils.JSON_MAPPER;
@@ -810,6 +814,63 @@ void testMissingHandlerReturnsMethodNotFoundError() {
810814
}
811815
}
812816

817+
@Test
818+
void testInitializedNotificationDoesNotLogWarn() {
819+
Logger handlerLogger = (Logger) LoggerFactory.getLogger(DefaultMcpStatelessServerHandler.class);
820+
ListAppender<ILoggingEvent> logAppender = new ListAppender<>();
821+
logAppender.start();
822+
handlerLogger.addAppender(logAppender);
823+
824+
try {
825+
var mcpServer = McpServer.sync(mcpStatelessServerTransport)
826+
.serverInfo("test-server", "1.0.0")
827+
.capabilities(ServerCapabilities.builder().build())
828+
.build();
829+
830+
try (var mcpClient = clientBuilder.build()) {
831+
mcpClient.initialize(); // automatically sends notifications/initialized
832+
}
833+
finally {
834+
mcpServer.close();
835+
}
836+
}
837+
finally {
838+
handlerLogger.detachAppender(logAppender);
839+
logAppender.stop();
840+
}
841+
842+
assertThat(logAppender.list).noneMatch(event -> event.getLevel() == Level.WARN);
843+
}
844+
845+
@Test
846+
void testRootsListChangedNotificationDoesNotLogWarn() {
847+
Logger handlerLogger = (Logger) LoggerFactory.getLogger(DefaultMcpStatelessServerHandler.class);
848+
ListAppender<ILoggingEvent> logAppender = new ListAppender<>();
849+
logAppender.start();
850+
handlerLogger.addAppender(logAppender);
851+
852+
try {
853+
var mcpServer = McpServer.sync(mcpStatelessServerTransport)
854+
.serverInfo("test-server", "1.0.0")
855+
.capabilities(ServerCapabilities.builder().build())
856+
.build();
857+
858+
try (var mcpClient = clientBuilder.build()) {
859+
mcpClient.initialize();
860+
mcpClient.rootsListChangedNotification();
861+
}
862+
finally {
863+
mcpServer.close();
864+
}
865+
}
866+
finally {
867+
handlerLogger.detachAppender(logAppender);
868+
logAppender.stop();
869+
}
870+
871+
assertThat(logAppender.list).noneMatch(event -> event.getLevel() == Level.WARN);
872+
}
873+
813874
private double evaluateExpression(String expression) {
814875
// Simple expression evaluator for testing
815876
return switch (expression) {

0 commit comments

Comments
 (0)