From 00648691c4d8900469dc094c8444e14ca825437c Mon Sep 17 00:00:00 2001 From: Daniel Garnier-Moiroux Date: Fri, 11 Jul 2025 11:06:33 +0200 Subject: [PATCH] McpSyncServer: set immediate execution when in a servlet context Signed-off-by: Daniel Garnier-Moiroux --- .../McpServerAutoConfiguration.java | 7 +++++- .../McpWebMvcServerAutoConfigurationIT.java | 22 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server/src/main/java/org/springframework/ai/mcp/server/autoconfigure/McpServerAutoConfiguration.java b/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server/src/main/java/org/springframework/ai/mcp/server/autoconfigure/McpServerAutoConfiguration.java index 2ba5530f516..eb55da944a5 100644 --- a/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server/src/main/java/org/springframework/ai/mcp/server/autoconfigure/McpServerAutoConfiguration.java +++ b/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server/src/main/java/org/springframework/ai/mcp/server/autoconfigure/McpServerAutoConfiguration.java @@ -55,9 +55,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; +import org.springframework.core.env.Environment; import org.springframework.core.log.LogAccessor; import org.springframework.util.CollectionUtils; import org.springframework.util.MimeType; +import org.springframework.web.context.support.StandardServletEnvironment; /** * {@link EnableAutoConfiguration Auto-configuration} for the Model Context Protocol (MCP) @@ -177,7 +179,7 @@ public McpSyncServer mcpSyncServer(McpServerTransportProvider transportProvider, ObjectProvider> prompts, ObjectProvider> completions, ObjectProvider>> rootsChangeConsumers, - List toolCallbackProvider) { + List toolCallbackProvider, Environment environment) { McpSchema.Implementation serverInfo = new Implementation(serverProperties.getName(), serverProperties.getVersion()); @@ -257,6 +259,9 @@ public McpSyncServer mcpSyncServer(McpServerTransportProvider transportProvider, serverBuilder.instructions(serverProperties.getInstructions()); serverBuilder.requestTimeout(serverProperties.getRequestTimeout()); + if (environment instanceof StandardServletEnvironment) { + serverBuilder.immediateExecution(true); + } return serverBuilder.build(); } diff --git a/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server/src/test/java/org/springframework/ai/mcp/server/autoconfigure/McpWebMvcServerAutoConfigurationIT.java b/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server/src/test/java/org/springframework/ai/mcp/server/autoconfigure/McpWebMvcServerAutoConfigurationIT.java index 5f0e5fc4baa..1075e602aca 100644 --- a/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server/src/test/java/org/springframework/ai/mcp/server/autoconfigure/McpWebMvcServerAutoConfigurationIT.java +++ b/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server/src/test/java/org/springframework/ai/mcp/server/autoconfigure/McpWebMvcServerAutoConfigurationIT.java @@ -17,11 +17,16 @@ package org.springframework.ai.mcp.server.autoconfigure; import com.fasterxml.jackson.databind.ObjectMapper; +import io.modelcontextprotocol.server.McpSyncServer; import io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.util.ReflectionUtils; +import org.springframework.web.context.support.StandardServletEnvironment; import org.springframework.web.servlet.function.RouterFunction; import static org.assertj.core.api.Assertions.assertThat; @@ -68,4 +73,21 @@ void serverBaseUrlConfiguration() { .isEqualTo("/test")); } + @Test + void servletEnvironmentConfiguration() { + new ApplicationContextRunner(() -> new AnnotationConfigApplicationContext() { + @Override + public ConfigurableEnvironment getEnvironment() { + return new StandardServletEnvironment(); + } + }).withConfiguration( + AutoConfigurations.of(McpWebMvcServerAutoConfiguration.class, McpServerAutoConfiguration.class)) + .run(context -> { + var mcpSyncServer = context.getBean(McpSyncServer.class); + var field = ReflectionUtils.findField(McpSyncServer.class, "immediateExecution"); + field.setAccessible(true); + assertThat(field.getBoolean(mcpSyncServer)).isTrue(); + }); + } + }