|
16 | 16 |
|
17 | 17 | package org.springframework.ai.mcp.server.autoconfigure; |
18 | 18 |
|
| 19 | +import java.util.HashMap; |
| 20 | +import java.util.Map; |
| 21 | + |
19 | 22 | import com.fasterxml.jackson.databind.ObjectMapper; |
| 23 | +import io.modelcontextprotocol.common.McpTransportContext; |
20 | 24 | import io.modelcontextprotocol.json.jackson.JacksonMcpJsonMapper; |
21 | 25 | import io.modelcontextprotocol.server.transport.WebMvcStreamableServerTransportProvider; |
22 | 26 | import io.modelcontextprotocol.spec.McpSchema; |
|
33 | 37 | import org.springframework.context.annotation.Bean; |
34 | 38 | import org.springframework.context.annotation.Conditional; |
35 | 39 | import org.springframework.web.servlet.function.RouterFunction; |
| 40 | +import org.springframework.web.servlet.function.ServerRequest; |
36 | 41 | import org.springframework.web.servlet.function.ServerResponse; |
37 | 42 |
|
38 | 43 | /** |
|
41 | 46 | */ |
42 | 47 | @AutoConfiguration(before = McpServerAutoConfiguration.class) |
43 | 48 | @ConditionalOnClass(McpSchema.class) |
44 | | -@EnableConfigurationProperties({ McpServerProperties.class, McpServerStreamableHttpProperties.class }) |
| 49 | +@EnableConfigurationProperties({ McpServerProperties.class, |
| 50 | + McpServerStreamableHttpProperties.class }) |
45 | 51 | @Conditional({ McpServerStdioDisabledCondition.class, |
46 | 52 | McpServerAutoConfiguration.EnabledStreamableServerCondition.class }) |
47 | 53 | public class McpServerStreamableHttpWebMvcAutoConfiguration { |
48 | 54 |
|
| 55 | + /** |
| 56 | + * Creates a WebMvc streamable server transport provider. |
| 57 | + * @param objectMapperProvider the object mapper provider |
| 58 | + * @param serverProperties the server properties |
| 59 | + * @return the transport provider |
| 60 | + */ |
49 | 61 | @Bean |
50 | 62 | @ConditionalOnMissingBean |
51 | 63 | public WebMvcStreamableServerTransportProvider webMvcStreamableServerTransportProvider( |
52 | | - ObjectProvider<ObjectMapper> objectMapperProvider, McpServerStreamableHttpProperties serverProperties) { |
| 64 | + final ObjectProvider<ObjectMapper> objectMapperProvider, |
| 65 | + final McpServerStreamableHttpProperties serverProperties) { |
53 | 66 |
|
54 | | - ObjectMapper objectMapper = objectMapperProvider.getIfAvailable(ObjectMapper::new); |
| 67 | + ObjectMapper objectMapper = objectMapperProvider |
| 68 | + .getIfAvailable(ObjectMapper::new); |
55 | 69 |
|
56 | 70 | return WebMvcStreamableServerTransportProvider.builder() |
57 | 71 | .jsonMapper(new JacksonMcpJsonMapper(objectMapper)) |
58 | 72 | .mcpEndpoint(serverProperties.getMcpEndpoint()) |
59 | 73 | .keepAliveInterval(serverProperties.getKeepAliveInterval()) |
60 | 74 | .disallowDelete(serverProperties.isDisallowDelete()) |
| 75 | + .contextExtractor(this::extractContextFromRequest) |
61 | 76 | .build(); |
62 | 77 | } |
63 | 78 |
|
64 | | - // Router function for streamable http transport used by Spring WebFlux to start an |
65 | | - // HTTP server. |
| 79 | + private McpTransportContext extractContextFromRequest( |
| 80 | + final ServerRequest serverRequest) { |
| 81 | + Map<String, Object> headersMap = new HashMap<>(); |
| 82 | + serverRequest.headers() |
| 83 | + .asHttpHeaders() |
| 84 | + .forEach((headerName, headerValues) -> { |
| 85 | + if (!headerValues.isEmpty()) { |
| 86 | + headersMap.put(headerName, headerValues.get(0)); |
| 87 | + } |
| 88 | + }); |
| 89 | + return McpTransportContext.create(headersMap); |
| 90 | + } |
| 91 | + |
| 92 | + /** |
| 93 | + * Creates a router function for the streamable server transport. |
| 94 | + * @param webMvcProvider the transport provider |
| 95 | + * @return the router function |
| 96 | + */ |
66 | 97 | @Bean |
67 | 98 | @ConditionalOnMissingBean(name = "webMvcStreamableServerRouterFunction") |
68 | 99 | public RouterFunction<ServerResponse> webMvcStreamableServerRouterFunction( |
69 | | - WebMvcStreamableServerTransportProvider webMvcProvider) { |
| 100 | + final WebMvcStreamableServerTransportProvider webMvcProvider) { |
70 | 101 | return webMvcProvider.getRouterFunction(); |
71 | 102 | } |
72 | 103 |
|
|
0 commit comments