Skip to content

Commit a91aa55

Browse files
committed
feat(mcp): Refactor MCP server API to use Specification pattern
- Rename Registration classes to Specification (SyncToolRegistration → SyncToolSpecification) - Update transport classes to use Provider suffix (WebFluxSseServerTransport → WebFluxSseServerTransportProvider) - Add exchange parameter to handler methods for better context passing - Introduce McpBackwardCompatibility class to maintain backward compatibility - Update MCP Server documentation to reflect new API patterns - Add tests for backward compatibility The changes align with the MCP specification evolution while maintaining backward compatibility through deprecated APIs. Signed-off-by: Christian Tzolov <[email protected]>
1 parent 29002df commit a91aa55

File tree

12 files changed

+1065
-213
lines changed

12 files changed

+1065
-213
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright 2025 - 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.ai.autoconfigure.mcp.server;
17+
18+
import java.util.List;
19+
import java.util.function.BiConsumer;
20+
import java.util.function.Consumer;
21+
import java.util.stream.Collectors;
22+
23+
import io.modelcontextprotocol.server.McpServerFeatures;
24+
import io.modelcontextprotocol.server.McpSyncServerExchange;
25+
import io.modelcontextprotocol.spec.McpSchema;
26+
27+
import org.springframework.beans.factory.ObjectProvider;
28+
import org.springframework.context.annotation.Bean;
29+
import org.springframework.context.annotation.Configuration;
30+
import org.springframework.util.CollectionUtils;
31+
32+
/**
33+
* @author Christian Tzolov
34+
*/
35+
@Deprecated
36+
@Configuration
37+
public class McpBackwardCompatibility {
38+
39+
@Bean
40+
public List<BiConsumer<McpSyncServerExchange, List<McpSchema.Root>>> syncRootsChangeConsumerToHandler(
41+
List<Consumer<List<McpSchema.Root>>> rootsChangeConsumers) {
42+
43+
if (CollectionUtils.isEmpty(rootsChangeConsumers)) {
44+
return List.of();
45+
}
46+
47+
return rootsChangeConsumers.stream().map(c -> new BiConsumer<McpSyncServerExchange, List<McpSchema.Root>>() {
48+
@Override
49+
public void accept(McpSyncServerExchange exchange, List<McpSchema.Root> roots) {
50+
c.accept(roots);
51+
}
52+
}).collect(Collectors.toList());
53+
}
54+
55+
@Bean
56+
public List<McpServerFeatures.SyncToolSpecification> syncToolsRegistrationToSpecificaiton(
57+
ObjectProvider<List<McpServerFeatures.SyncToolRegistration>> toolRegistrations) {
58+
59+
return toolRegistrations.stream()
60+
.flatMap(List::stream)
61+
.map(McpServerFeatures.SyncToolRegistration::toSpecification)
62+
.toList();
63+
}
64+
65+
@Bean
66+
public List<McpServerFeatures.SyncResourceSpecification> syncResourceRegistrationToSpecificaiton(
67+
ObjectProvider<List<McpServerFeatures.SyncResourceRegistration>> resourceRegistrations) {
68+
69+
return resourceRegistrations.stream()
70+
.flatMap(List::stream)
71+
.map(McpServerFeatures.SyncResourceRegistration::toSpecification)
72+
.toList();
73+
}
74+
75+
@Bean
76+
public List<McpServerFeatures.SyncPromptSpecification> syncPromptRegistrationToSpecificaiton(
77+
ObjectProvider<List<McpServerFeatures.SyncPromptRegistration>> promptRegistrations) {
78+
79+
return promptRegistrations.stream()
80+
.flatMap(List::stream)
81+
.map(McpServerFeatures.SyncPromptRegistration::toSpecification)
82+
.toList();
83+
}
84+
85+
// Async
86+
@Bean
87+
public List<McpServerFeatures.AsyncToolSpecification> asyncToolsRegistrationToSpecificaiton(
88+
ObjectProvider<List<McpServerFeatures.AsyncToolRegistration>> toolRegistrations) {
89+
90+
return toolRegistrations.stream()
91+
.flatMap(List::stream)
92+
.map(McpServerFeatures.AsyncToolRegistration::toSpecification)
93+
.toList();
94+
}
95+
96+
@Bean
97+
public List<McpServerFeatures.AsyncResourceSpecification> asyncResourceRegistrationToSpecificaiton(
98+
ObjectProvider<List<McpServerFeatures.AsyncResourceRegistration>> resourceRegistrations) {
99+
100+
return resourceRegistrations.stream()
101+
.flatMap(List::stream)
102+
.map(McpServerFeatures.AsyncResourceRegistration::toSpecification)
103+
.toList();
104+
}
105+
106+
@Bean
107+
public List<McpServerFeatures.AsyncPromptSpecification> asyncPromptRegistrationToSpecificaiton(
108+
ObjectProvider<List<McpServerFeatures.AsyncPromptRegistration>> promptRegistrations) {
109+
110+
return promptRegistrations.stream()
111+
.flatMap(List::stream)
112+
.map(McpServerFeatures.AsyncPromptRegistration::toSpecification)
113+
.toList();
114+
}
115+
116+
}

0 commit comments

Comments
 (0)