Skip to content

Commit 405644e

Browse files
Ahoo-Wangtzolov
authored andcommitted
refactor(spring-ai-mcp-server): enhance MCP server auto-configuration (#2477)
- Update WebFlux and WebMvc server configurations to use ObjectProvider for ObjectMapper - Add integration tests for MCP server auto-configurations - Improve conditional checks for stdio configuration Signed-off-by: Ahoo Wang <ahoowang@qq.com>
1 parent 2e6d6ea commit 405644e

File tree

4 files changed

+91
-4
lines changed

4 files changed

+91
-4
lines changed

auto-configurations/mcp/spring-ai-autoconfigure-mcp-server/src/main/java/org/springframework/ai/mcp/server/autoconfigure/McpWebFluxServerAutoConfiguration.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import io.modelcontextprotocol.server.transport.WebFluxSseServerTransportProvider;
2121
import io.modelcontextprotocol.spec.McpServerTransportProvider;
2222

23+
import org.springframework.beans.factory.ObjectProvider;
2324
import org.springframework.boot.autoconfigure.AutoConfiguration;
2425
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2526
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -73,8 +74,10 @@ public class McpWebFluxServerAutoConfiguration {
7374

7475
@Bean
7576
@ConditionalOnMissingBean
76-
public WebFluxSseServerTransportProvider webFluxTransport(McpServerProperties serverProperties) {
77-
return new WebFluxSseServerTransportProvider(new ObjectMapper(), serverProperties.getSseMessageEndpoint());
77+
public WebFluxSseServerTransportProvider webFluxTransport(ObjectProvider<ObjectMapper> objectMapperProvider,
78+
McpServerProperties serverProperties) {
79+
ObjectMapper objectMapper = objectMapperProvider.getIfAvailable(ObjectMapper::new);
80+
return new WebFluxSseServerTransportProvider(objectMapper, serverProperties.getSseMessageEndpoint());
7881
}
7982

8083
// Router function for SSE transport used by Spring WebFlux to start an HTTP server.

auto-configurations/mcp/spring-ai-autoconfigure-mcp-server/src/main/java/org/springframework/ai/mcp/server/autoconfigure/McpWebMvcServerAutoConfiguration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider;
2121
import io.modelcontextprotocol.spec.McpServerTransportProvider;
2222

23+
import org.springframework.beans.factory.ObjectProvider;
2324
import org.springframework.boot.autoconfigure.AutoConfiguration;
2425
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2526
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -68,8 +69,9 @@ public class McpWebMvcServerAutoConfiguration {
6869

6970
@Bean
7071
@ConditionalOnMissingBean
71-
public WebMvcSseServerTransportProvider webMvcSseServerTransportProvider(ObjectMapper objectMapper,
72-
McpServerProperties serverProperties) {
72+
public WebMvcSseServerTransportProvider webMvcSseServerTransportProvider(
73+
ObjectProvider<ObjectMapper> objectMapperProvider, McpServerProperties serverProperties) {
74+
ObjectMapper objectMapper = objectMapperProvider.getIfAvailable(ObjectMapper::new);
7375
return new WebMvcSseServerTransportProvider(objectMapper, serverProperties.getSseMessageEndpoint());
7476
}
7577

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package org.springframework.ai.mcp.server.autoconfigure;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import io.modelcontextprotocol.server.transport.WebFluxSseServerTransportProvider;
5+
import org.junit.jupiter.api.Test;
6+
7+
import org.springframework.boot.autoconfigure.AutoConfigurations;
8+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
9+
import org.springframework.web.reactive.function.server.RouterFunction;
10+
11+
import static org.assertj.core.api.Assertions.assertThat;
12+
13+
class McpWebFluxServerAutoConfigurationIT {
14+
15+
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(
16+
AutoConfigurations.of(McpWebFluxServerAutoConfiguration.class, McpServerAutoConfiguration.class));
17+
18+
@Test
19+
void defaultConfiguration() {
20+
this.contextRunner.run(context -> {
21+
assertThat(context).hasSingleBean(WebFluxSseServerTransportProvider.class);
22+
assertThat(context).hasSingleBean(RouterFunction.class);
23+
});
24+
}
25+
26+
@Test
27+
void objectMapperConfiguration() {
28+
this.contextRunner.withBean(ObjectMapper.class, ObjectMapper::new).run(context -> {
29+
assertThat(context).hasSingleBean(WebFluxSseServerTransportProvider.class);
30+
assertThat(context).hasSingleBean(RouterFunction.class);
31+
});
32+
}
33+
34+
@Test
35+
void stdioEnabledConfiguration() {
36+
this.contextRunner.withPropertyValues("spring.ai.mcp.server.stdio=true").run(context -> {
37+
assertThat(context).doesNotHaveBean(WebFluxSseServerTransportProvider.class);
38+
});
39+
}
40+
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package org.springframework.ai.mcp.server.autoconfigure;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider;
5+
import org.junit.jupiter.api.Test;
6+
7+
import org.springframework.boot.autoconfigure.AutoConfigurations;
8+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
9+
import org.springframework.web.servlet.function.RouterFunction;
10+
11+
import static org.assertj.core.api.Assertions.assertThat;
12+
13+
class McpWebMvcServerAutoConfigurationTest {
14+
15+
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(
16+
AutoConfigurations.of(McpWebMvcServerAutoConfiguration.class, McpServerAutoConfiguration.class));
17+
18+
@Test
19+
void defaultConfiguration() {
20+
this.contextRunner.run(context -> {
21+
assertThat(context).hasSingleBean(WebMvcSseServerTransportProvider.class);
22+
assertThat(context).hasSingleBean(RouterFunction.class);
23+
});
24+
}
25+
26+
@Test
27+
void objectMapperConfiguration() {
28+
this.contextRunner.withBean(ObjectMapper.class, ObjectMapper::new).run(context -> {
29+
assertThat(context).hasSingleBean(WebMvcSseServerTransportProvider.class);
30+
assertThat(context).hasSingleBean(RouterFunction.class);
31+
});
32+
}
33+
34+
@Test
35+
void stdioEnabledConfiguration() {
36+
this.contextRunner.withPropertyValues("spring.ai.mcp.server.stdio=true").run(context -> {
37+
assertThat(context).doesNotHaveBean(WebMvcSseServerTransportProvider.class);
38+
});
39+
}
40+
41+
}

0 commit comments

Comments
 (0)