Skip to content

Commit 4aa82f0

Browse files
committed
refactor(spring-ai-mcp-server): enhance MCP server auto-configuration
- 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 <[email protected]>
1 parent 690d242 commit 4aa82f0

File tree

4 files changed

+87
-3
lines changed

4 files changed

+87
-3
lines changed

auto-configurations/spring-ai-mcp-server/src/main/java/org/springframework/ai/autoconfigure/mcp/server/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.WebFluxSseServerTransport;
2121
import io.modelcontextprotocol.spec.ServerMcpTransport;
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;
@@ -72,8 +73,10 @@ public class McpWebFluxServerAutoConfiguration {
7273

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

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

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import io.modelcontextprotocol.server.transport.WebMvcSseServerTransport;
2121
import io.modelcontextprotocol.spec.ServerMcpTransport;
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 WebMvcSseServerTransport webMvcSseServerTransport(ObjectMapper objectMapper,
72+
public WebMvcSseServerTransport webMvcSseServerTransport(ObjectProvider<ObjectMapper> objectMapperProvider,
7273
McpServerProperties serverProperties) {
74+
ObjectMapper objectMapper = objectMapperProvider.getIfAvailable(ObjectMapper::new);
7375
return new WebMvcSseServerTransport(objectMapper, serverProperties.getSseMessageEndpoint());
7476
}
7577

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

0 commit comments

Comments
 (0)