diff --git a/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/server/transport/WebFluxSseServerTransport.java b/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/server/transport/WebFluxSseServerTransport.java
index 2dbc929..bed7293 100644
--- a/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/server/transport/WebFluxSseServerTransport.java
+++ b/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/server/transport/WebFluxSseServerTransport.java
@@ -251,7 +251,7 @@ public class WebFluxSseServerTransport implements ServerMcpTransport {
.then(Mono.fromRunnable(() -> sessions.remove(sessionId)));
}).toList()))
.timeout(Duration.ofSeconds(5))
- .doOnSuccess(v -> logger.info("Graceful shutdown completed"))
+ .doOnSuccess(v -> logger.debug("Graceful shutdown completed"))
.doOnError(e -> logger.error("Error during graceful shutdown: {}", e.getMessage()));
}
diff --git a/mcp-spring/mcp-spring-webmvc/src/main/java/io/modelcontextprotocol/server/transport/WebMvcSseServerTransport.java b/mcp-spring/mcp-spring-webmvc/src/main/java/io/modelcontextprotocol/server/transport/WebMvcSseServerTransport.java
index 7339311..f2d1d3e 100644
--- a/mcp-spring/mcp-spring-webmvc/src/main/java/io/modelcontextprotocol/server/transport/WebMvcSseServerTransport.java
+++ b/mcp-spring/mcp-spring-webmvc/src/main/java/io/modelcontextprotocol/server/transport/WebMvcSseServerTransport.java
@@ -353,7 +353,7 @@ public class WebMvcSseServerTransport implements ServerMcpTransport {
sessions.remove(sessionId);
});
- logger.info("Graceful shutdown completed");
+ logger.debug("Graceful shutdown completed");
});
}
diff --git a/mcp/src/main/java/io/modelcontextprotocol/client/McpAsyncClient.java b/mcp/src/main/java/io/modelcontextprotocol/client/McpAsyncClient.java
index 31d3175..a49ad7f 100644
--- a/mcp/src/main/java/io/modelcontextprotocol/client/McpAsyncClient.java
+++ b/mcp/src/main/java/io/modelcontextprotocol/client/McpAsyncClient.java
@@ -173,7 +173,7 @@ public class McpAsyncClient {
// Tools Change Notification
List, Mono>> toolsChangeConsumersFinal = new ArrayList<>();
toolsChangeConsumersFinal
- .add((notification) -> Mono.fromRunnable(() -> logger.info("Tools changed: {}", notification)));
+ .add((notification) -> Mono.fromRunnable(() -> logger.debug("Tools changed: {}", notification)));
if (!Utils.isEmpty(features.toolsChangeConsumers())) {
toolsChangeConsumersFinal.addAll(features.toolsChangeConsumers());
@@ -184,7 +184,7 @@ public class McpAsyncClient {
// Resources Change Notification
List, Mono>> resourcesChangeConsumersFinal = new ArrayList<>();
resourcesChangeConsumersFinal
- .add((notification) -> Mono.fromRunnable(() -> logger.info("Resources changed: {}", notification)));
+ .add((notification) -> Mono.fromRunnable(() -> logger.debug("Resources changed: {}", notification)));
if (!Utils.isEmpty(features.resourcesChangeConsumers())) {
resourcesChangeConsumersFinal.addAll(features.resourcesChangeConsumers());
@@ -196,7 +196,7 @@ public class McpAsyncClient {
// Prompts Change Notification
List, Mono>> promptsChangeConsumersFinal = new ArrayList<>();
promptsChangeConsumersFinal
- .add((notification) -> Mono.fromRunnable(() -> logger.info("Prompts changed: {}", notification)));
+ .add((notification) -> Mono.fromRunnable(() -> logger.debug("Prompts changed: {}", notification)));
if (!Utils.isEmpty(features.promptsChangeConsumers())) {
promptsChangeConsumersFinal.addAll(features.promptsChangeConsumers());
}
@@ -205,7 +205,7 @@ public class McpAsyncClient {
// Utility Logging Notification
List>> loggingConsumersFinal = new ArrayList<>();
- loggingConsumersFinal.add((notification) -> Mono.fromRunnable(() -> logger.info("Logging: {}", notification)));
+ loggingConsumersFinal.add((notification) -> Mono.fromRunnable(() -> logger.debug("Logging: {}", notification)));
if (!Utils.isEmpty(features.loggingConsumers())) {
loggingConsumersFinal.addAll(features.loggingConsumers());
}
@@ -364,7 +364,7 @@ public class McpAsyncClient {
this.roots.put(root.uri(), root);
- logger.info("Added root: {}", root);
+ logger.debug("Added root: {}", root);
if (this.clientCapabilities.roots().listChanged()) {
return this.rootsListChangedNotification();
@@ -390,7 +390,7 @@ public class McpAsyncClient {
Root removed = this.roots.remove(rootUri);
if (removed != null) {
- logger.info("Removed Root: {}", rootUri);
+ logger.debug("Removed Root: {}", rootUri);
if (this.clientCapabilities.roots().listChanged()) {
return this.rootsListChangedNotification();
}
diff --git a/mcp/src/main/java/io/modelcontextprotocol/client/transport/StdioClientTransport.java b/mcp/src/main/java/io/modelcontextprotocol/client/transport/StdioClientTransport.java
index 462837b..614c651 100644
--- a/mcp/src/main/java/io/modelcontextprotocol/client/transport/StdioClientTransport.java
+++ b/mcp/src/main/java/io/modelcontextprotocol/client/transport/StdioClientTransport.java
@@ -68,7 +68,7 @@ public class StdioClientTransport implements ClientMcpTransport {
private volatile boolean isClosing = false;
// visible for tests
- private Consumer errorHandler = error -> logger.error("Error received: {}", error);
+ private Consumer stdErrorHandler = error -> logger.info("STDERR Message received: {}", error);
/**
* Creates a new StdioClientTransport with the specified parameters and default
@@ -164,8 +164,8 @@ public class StdioClientTransport implements ClientMcpTransport {
*
* @param errorHandler a consumer that processes error messages
*/
- public void setErrorHandler(Consumer errorHandler) {
- this.errorHandler = errorHandler;
+ public void setStdErrorHandler(Consumer errorHandler) {
+ this.stdErrorHandler = errorHandler;
}
/**
@@ -192,7 +192,6 @@ public class StdioClientTransport implements ClientMcpTransport {
String line;
while (!isClosing && (line = processErrorReader.readLine()) != null) {
try {
- logger.error("Received error line: {}", line);
if (!this.errorSink.tryEmitNext(line).isSuccess()) {
if (!isClosing) {
logger.error("Failed to emit error message");
@@ -230,7 +229,7 @@ public class StdioClientTransport implements ClientMcpTransport {
private void handleIncomingErrors() {
this.errorSink.asFlux().subscribe(e -> {
- this.errorHandler.accept(e);
+ this.stdErrorHandler.accept(e);
});
}
@@ -355,7 +354,7 @@ public class StdioClientTransport implements ClientMcpTransport {
// Give a short time for any pending messages to be processed
return Mono.delay(Duration.ofMillis(100));
})).then(Mono.fromFuture(() -> {
- logger.info("Sending TERM to process");
+ logger.debug("Sending TERM to process");
if (this.process != null) {
this.process.destroy();
return process.onExit();
@@ -375,7 +374,7 @@ public class StdioClientTransport implements ClientMcpTransport {
errorScheduler.dispose();
outboundScheduler.dispose();
- logger.info("Graceful shutdown completed");
+ logger.debug("Graceful shutdown completed");
}
catch (Exception e) {
logger.error("Error during graceful shutdown", e);
diff --git a/mcp/src/main/java/io/modelcontextprotocol/server/McpAsyncServer.java b/mcp/src/main/java/io/modelcontextprotocol/server/McpAsyncServer.java
index a6c9475..5fbc676 100644
--- a/mcp/src/main/java/io/modelcontextprotocol/server/McpAsyncServer.java
+++ b/mcp/src/main/java/io/modelcontextprotocol/server/McpAsyncServer.java
@@ -318,7 +318,7 @@ public class McpAsyncServer {
}
this.tools.add(toolRegistration);
- logger.info("Added tool handler: {}", toolRegistration.tool().name());
+ logger.debug("Added tool handler: {}", toolRegistration.tool().name());
if (this.serverCapabilities.tools().listChanged()) {
return notifyToolsListChanged();
@@ -343,7 +343,7 @@ public class McpAsyncServer {
return Mono.defer(() -> {
boolean removed = this.tools.removeIf(toolRegistration -> toolRegistration.tool().name().equals(toolName));
if (removed) {
- logger.info("Removed tool handler: {}", toolName);
+ logger.debug("Removed tool handler: {}", toolName);
if (this.serverCapabilities.tools().listChanged()) {
return notifyToolsListChanged();
}
@@ -411,7 +411,7 @@ public class McpAsyncServer {
return Mono
.error(new McpError("Resource with URI '" + resourceHandler.resource().uri() + "' already exists"));
}
- logger.info("Added resource handler: {}", resourceHandler.resource().uri());
+ logger.debug("Added resource handler: {}", resourceHandler.resource().uri());
if (this.serverCapabilities.resources().listChanged()) {
return notifyResourcesListChanged();
}
@@ -435,7 +435,7 @@ public class McpAsyncServer {
return Mono.defer(() -> {
McpServerFeatures.AsyncResourceRegistration removed = this.resources.remove(resourceUri);
if (removed != null) {
- logger.info("Removed resource handler: {}", resourceUri);
+ logger.debug("Removed resource handler: {}", resourceUri);
if (this.serverCapabilities.resources().listChanged()) {
return notifyResourcesListChanged();
}
@@ -507,7 +507,7 @@ public class McpAsyncServer {
new McpError("Prompt with name '" + promptRegistration.prompt().name() + "' already exists"));
}
- logger.info("Added prompt handler: {}", promptRegistration.prompt().name());
+ logger.debug("Added prompt handler: {}", promptRegistration.prompt().name());
// Servers that declared the listChanged capability SHOULD send a
// notification,
@@ -536,7 +536,7 @@ public class McpAsyncServer {
McpServerFeatures.AsyncPromptRegistration removed = this.prompts.remove(promptName);
if (removed != null) {
- logger.info("Removed prompt handler: {}", promptName);
+ logger.debug("Removed prompt handler: {}", promptName);
// Servers that declared the listChanged capability SHOULD send a
// notification, when the list of available prompts changes
if (this.serverCapabilities.prompts().listChanged()) {
diff --git a/mcp/src/main/java/io/modelcontextprotocol/server/transport/StdioServerTransport.java b/mcp/src/main/java/io/modelcontextprotocol/server/transport/StdioServerTransport.java
index 818aa28..e375cd1 100644
--- a/mcp/src/main/java/io/modelcontextprotocol/server/transport/StdioServerTransport.java
+++ b/mcp/src/main/java/io/modelcontextprotocol/server/transport/StdioServerTransport.java
@@ -141,6 +141,8 @@ public class StdioServerTransport implements ServerMcpTransport {
break;
}
+ logger.debug("Received JSON message: {}", line);
+
try {
JSONRPCMessage message = McpSchema.deserializeJsonRpcMessage(this.objectMapper, line);
if (!this.inboundSink.tryEmitNext(message).isSuccess()) {
@@ -229,7 +231,7 @@ public class StdioServerTransport implements ServerMcpTransport {
// Completing the inbound causes the outbound to be completed as well, so
// we only close the inbound.
inboundSink.tryEmitComplete();
- logger.info("Graceful shutdown complete");
+ logger.debug("Graceful shutdown complete");
return Mono.empty();
}).subscribeOn(Schedulers.boundedElastic());
}
diff --git a/mcp/src/main/java/io/modelcontextprotocol/spec/DefaultMcpSession.java b/mcp/src/main/java/io/modelcontextprotocol/spec/DefaultMcpSession.java
index eb7ce49..e2d354f 100644
--- a/mcp/src/main/java/io/modelcontextprotocol/spec/DefaultMcpSession.java
+++ b/mcp/src/main/java/io/modelcontextprotocol/spec/DefaultMcpSession.java
@@ -124,7 +124,7 @@ public class DefaultMcpSession implements McpSession {
// consumer
this.connection = this.transport.connect(mono -> mono.doOnNext(message -> {
if (message instanceof McpSchema.JSONRPCResponse response) {
- logger.info("Received Response: {}", response);
+ logger.debug("Received Response: {}", response);
var sink = pendingResponses.remove(response.id());
if (sink == null) {
logger.warn("Unexpected response for unkown id {}", response.id());
@@ -134,7 +134,7 @@ public class DefaultMcpSession implements McpSession {
}
}
else if (message instanceof McpSchema.JSONRPCRequest request) {
- logger.info("Received request: {}", request);
+ logger.debug("Received request: {}", request);
handleIncomingRequest(request).subscribe(response -> transport.sendMessage(response).subscribe(),
error -> {
var errorResponse = new McpSchema.JSONRPCResponse(McpSchema.JSONRPC_VERSION, request.id(),
@@ -144,7 +144,7 @@ public class DefaultMcpSession implements McpSession {
});
}
else if (message instanceof McpSchema.JSONRPCNotification notification) {
- logger.info("Received notification: {}", notification);
+ logger.debug("Received notification: {}", notification);
handleIncomingNotification(notification).subscribe(null,
error -> logger.error("Error handling notification: {}", error.getMessage()));
}
diff --git a/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java b/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java
index 1c6bb61..e721468 100644
--- a/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java
+++ b/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java
@@ -17,6 +17,8 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Based on the JSON-RPC 2.0
@@ -28,6 +30,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
*/
public final class McpSchema {
+ private static final Logger logger = LoggerFactory.getLogger(McpSchema.class);
+
private McpSchema() {
}
@@ -144,6 +148,8 @@ public final class McpSchema {
public static JSONRPCMessage deserializeJsonRpcMessage(ObjectMapper objectMapper, String jsonText)
throws IOException {
+ logger.debug("Received JSON message: {}", jsonText);
+
var map = objectMapper.readValue(jsonText, MAP_TYPE_REF);
// Determine message type based on specific JSON structure
@@ -662,8 +668,8 @@ public final class McpSchema {
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
record JsonSchema( // @formatter:off
- @JsonProperty("type") String type,
- @JsonProperty("properties") Map properties,
+ @JsonProperty("type") String type,
+ @JsonProperty("properties") Map properties,
@JsonProperty("required") List required,
@JsonProperty("additionalProperties") Boolean additionalProperties) {
} // @formatter:on
diff --git a/mcp/src/test/java/io/modelcontextprotocol/client/StdioMcpSyncClientTests.java b/mcp/src/test/java/io/modelcontextprotocol/client/StdioMcpSyncClientTests.java
index 9f2bc4a..7ae6525 100644
--- a/mcp/src/test/java/io/modelcontextprotocol/client/StdioMcpSyncClientTests.java
+++ b/mcp/src/test/java/io/modelcontextprotocol/client/StdioMcpSyncClientTests.java
@@ -36,7 +36,7 @@ class StdioMcpSyncClientTests extends AbstractMcpSyncClientTests {
void customErrorHandlerShouldReceiveErrors() {
AtomicReference receivedError = new AtomicReference<>();
- ((StdioClientTransport) mcpTransport).setErrorHandler(error -> receivedError.set(error));
+ ((StdioClientTransport) mcpTransport).setStdErrorHandler(error -> receivedError.set(error));
String errorMessage = "Test error";
((StdioClientTransport) mcpTransport).getErrorSink().tryEmitNext(errorMessage);