Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ public McpSchema.InitializeResult currentInitializationResult() {
* @param t The exception to handle
*/
public void handleException(Throwable t) {
logger.warn("Handling exception", t);
if (t instanceof McpTransportSessionNotFoundException) {
DefaultInitialization previous = this.initializationRef.getAndSet(null);
if (previous != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -484,9 +484,7 @@ public Mono<Void> addRoot(Root root) {
if (this.isInitialized()) {
return this.rootsListChangedNotification();
}
else {
logger.warn("Client is not initialized, ignore sending a roots list changed notification");
}
logger.debug("Client is not initialized, ignore sending a roots list changed notification");
}
return Mono.empty();
}
Expand Down Expand Up @@ -514,10 +512,7 @@ public Mono<Void> removeRoot(String rootUri) {
if (this.isInitialized()) {
return this.rootsListChangedNotification();
}
else {
logger.warn("Client is not initialized, ignore sending a roots list changed notification");
}

logger.debug("Client is not initialized, ignore sending a roots list changed notification");
}
return Mono.empty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.IntStream;

import io.modelcontextprotocol.json.TypeRef;
import io.modelcontextprotocol.json.McpJsonMapper;
Expand Down Expand Up @@ -41,6 +44,15 @@ public class StdioClientTransport implements McpClientTransport {

private static final Logger logger = LoggerFactory.getLogger(StdioClientTransport.class);

// @formatter:off
private static final Set<Integer> EXIT_SUCCESS_CODES = Set.of(
0, // success
130, // interrupted (SIGINT)
141, // pipeline shortcut (SIGPIPE)
143 // graceful termination (SIGTERM)
);
// @formatter:on

private final Sinks.Many<JSONRPCMessage> inboundSink;

private final Sinks.Many<JSONRPCMessage> outboundSink;
Expand Down Expand Up @@ -356,11 +368,12 @@ public Mono<Void> closeGracefully() {
return Mono.<Process>empty();
}
})).doOnNext(process -> {
if (process.exitValue() != 0) {
logger.warn("Process terminated with code {}", process.exitValue());
int exitValue = process.exitValue();
if (EXIT_SUCCESS_CODES.contains(exitValue)) {
logger.info("MCP server completed successfully with code {}", exitValue);
}
else {
logger.info("MCP server process stopped");
logger.warn("MCP server process failed with code {}", exitValue);
}
}).then(Mono.fromRunnable(() -> {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -513,14 +513,13 @@ public Mono<Void> removeTool(String toolName) {

return Mono.defer(() -> {
if (this.tools.removeIf(toolSpecification -> toolSpecification.tool().name().equals(toolName))) {

logger.debug("Removed tool handler: {}", toolName);
if (this.serverCapabilities.tools().listChanged()) {
return notifyToolsListChanged();
}
}
else {
logger.warn("Ignore as a Tool with name '{}' not found", toolName);
logger.warn("Failed to remove tool with name '{}' (not found)", toolName);
}

return Mono.empty();
Expand Down Expand Up @@ -637,7 +636,7 @@ public Mono<Void> removeResource(String resourceUri) {
return Mono.empty();
}
else {
logger.warn("Ignore as a Resource with URI '{}' not found", resourceUri);
logger.warn("Failed to remove resource with URI '{}' (not found)", resourceUri);
}
return Mono.empty();
});
Expand Down Expand Up @@ -701,7 +700,7 @@ public Mono<Void> removeResourceTemplate(String uriTemplate) {
logger.debug("Removed resource template: {}", uriTemplate);
}
else {
logger.warn("Ignore as a Resource Template with URI '{}' not found", uriTemplate);
logger.warn("Failed to remove a resource template with URI '{}' (not found)", uriTemplate);
}
return Mono.empty();
});
Expand Down Expand Up @@ -907,7 +906,7 @@ public Mono<Void> removePrompt(String promptName) {
return Mono.empty();
}
else {
logger.warn("Ignore as a Prompt with name '{}' not found", promptName);
logger.warn("Failed to remove a prompt with name '{}' (not found)", promptName);
}
return Mono.empty();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ public Mono<Void> removeTool(String toolName) {
logger.debug("Removed tool handler: {}", toolName);
}
else {
logger.warn("Ignore as a Tool with name '{}' not found", toolName);
logger.warn("Failed to remove a tool with name '{}' (not found)", toolName);
}

return Mono.empty();
Expand Down Expand Up @@ -492,7 +492,7 @@ public Mono<Void> removeResource(String resourceUri) {
logger.debug("Removed resource handler: {}", resourceUri);
}
else {
logger.warn("Resource with URI '{}' not found", resourceUri);
logger.warn("Failed to remove a resource with URI '{}' (not found)", resourceUri);
}
return Mono.empty();
});
Expand Down Expand Up @@ -554,7 +554,7 @@ public Mono<Void> removeResourceTemplate(String uriTemplate) {
logger.debug("Removed resource template: {}", uriTemplate);
}
else {
logger.warn("Ignore as a Resource Template with URI '{}' not found", uriTemplate);
logger.warn("Failed to remove a resource template with URI '{}' (not found)", uriTemplate);
}
return Mono.empty();
});
Expand Down Expand Up @@ -677,7 +677,7 @@ public Mono<Void> removePrompt(String promptName) {
return Mono.empty();
}
else {
logger.warn("Ignore as a Prompt with name '{}' not found", promptName);
logger.warn("Failed to remove a prompt with name '{}' (not found)", promptName);
}

return Mono.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ public Mono<Void> notifyClients(String method, Object params) {
session.sendNotification(method, params).block();
}
catch (Exception e) {
logger.error("Failed to send message to session {}: {}", session.getId(), e.getMessage());
logger.info("Failed to send message to session {}: {}", session.getId(), e.getMessage());
}
});
});
Expand Down Expand Up @@ -233,12 +233,11 @@ public Mono<Void> closeGracefully() {
session.closeGracefully().block();
}
catch (Exception e) {
logger.error("Failed to close session {}: {}", session.getId(), e.getMessage());
logger.warn("Failed to close session {}: {}", session.getId(), e.getMessage());
}
});

this.sessions.clear();
logger.debug("Graceful shutdown completed");
}).then().doOnSuccess(v -> {
sessions.clear();
logger.debug("Graceful shutdown completed");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public McpClientSession(Duration requestTimeout, McpClientTransport transport,

private void dismissPendingResponses() {
this.pendingResponses.forEach((id, sink) -> {
logger.warn("Abruptly terminating exchange for request {}", id);
logger.info("Abruptly terminating exchange for request {}", id);
sink.error(new RuntimeException("MCP session with server terminated"));
});
this.pendingResponses.clear();
Expand Down Expand Up @@ -257,7 +257,8 @@ public <T> Mono<T> sendRequest(String method, Object requestParams, TypeRef<T> t
});
})).timeout(this.requestTimeout).handle((jsonRpcResponse, deliveredResponseSink) -> {
if (jsonRpcResponse.error() != null) {
logger.error("Error handling request: {}", jsonRpcResponse.error());
logger.info("Server returned a JSON-RPC error when calling method {}: {}", method,
jsonRpcResponse.error());
deliveredResponseSink.error(new McpError(jsonRpcResponse.error()));
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,8 @@ else if (message instanceof McpSchema.JSONRPCNotification notification) {
// happening first
logger.debug("Received notification: {}", notification);
// TODO: in case of error, should the POST request be signalled?
return handleIncomingNotification(notification, transportContext)
.doOnError(error -> logger.error("Error handling notification: {}", error.getMessage()));
return handleIncomingNotification(notification, transportContext).doOnError(
error -> logger.warn("Error handling notification {}: {}", notification, error.getMessage()));
}
else {
logger.warn("Received unknown message type: {}", message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,9 @@ public ValidationResponse validate(Map<String, Object> schema, Object structured

}
catch (JsonProcessingException e) {
logger.error("Failed to validate CallToolResult: Error parsing schema: {}", e);
return ValidationResponse.asInvalid("Error parsing tool JSON Schema: " + e.getMessage());
}
catch (Exception e) {
logger.error("Failed to validate CallToolResult: Unexpected error: {}", e);
return ValidationResponse.asInvalid("Unexpected validation error: " + e.getMessage());
}
}
Expand All @@ -113,7 +111,6 @@ public ValidationResponse validateSchema(Map<String, Object> schema) {
return ValidationResponse.asValid(null);
}
catch (Exception e) {
logger.error("Failed to validate schema definition: {}", e.getMessage());
return ValidationResponse.asInvalid("Failed to validate schema definition: " + e.getMessage());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,9 @@ public ValidationResponse validate(Map<String, Object> schema, Object structured

}
catch (JacksonException e) {
logger.error("Failed to validate CallToolResult: Error parsing schema: {}", e);
return ValidationResponse.asInvalid("Error parsing tool JSON Schema: " + e.getMessage());
}
catch (Exception e) {
logger.error("Failed to validate CallToolResult: Unexpected error: {}", e);
return ValidationResponse.asInvalid("Unexpected validation error: " + e.getMessage());
}
}
Expand All @@ -112,7 +110,6 @@ public ValidationResponse validateSchema(Map<String, Object> schema) {
return ValidationResponse.asValid(null);
}
catch (Exception e) {
logger.error("Failed to validate schema definition: {}", e.getMessage());
return ValidationResponse.asInvalid("Failed to validate schema definition: " + e.getMessage());
}
}
Expand Down
37 changes: 37 additions & 0 deletions mcp-test/src/test/resources/logback-test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>

<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<appender name="DOCKER" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level [DOCKER] %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<!-- Testcontainers framework -->
<logger name="org.testcontainers" level="INFO" additivity="false">
<appender-ref ref="DOCKER"/>
</logger>

<!-- Docker Java client -->
<logger name="com.github.dockerjava" level="INFO" additivity="false">
<appender-ref ref="DOCKER"/>
</logger>

<!-- Container output (tc.<image-name> format used by Testcontainers) -->
<logger name="tc" level="INFO" additivity="false">
<appender-ref ref="DOCKER"/>
</logger>

<logger name="io.modelcontextprotocol" level="INFO"/>

<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
Loading