Skip to content

Commit 1ce514b

Browse files
committed
refactor: optimize MCP annotation processing with targeted bean filtering
- Replace getAllAnnotatedBeans() with getBeansByAnnotation() for specific annotation types - Add explicit imports for MCP annotations (McpElicitation, McpLogging, McpProgress, McpSampling, McpComplete, McpPrompt, McpResource, McpTool) - Rename parameter from beanRegistry to beansWithMcpMethodAnnotations for clarity - Remove duplicate test file StreamableMcpAnnotations2IT.java - Clean up manual bean configuration in favor of auto-configuration - Update MCP SDK from 0.12.0-SNAPSHOT to 0.11.3 stable release - Update MCP annotations from 0.2.0-SNAPSHOT to 0.2.0 stable release This change improves performance by filtering beans by specific annotation types rather than processing all annotated beans, making the MCP feature detection more efficient and targeted. Signed-off-by: Christian Tzolov <[email protected]>
1 parent 3851405 commit 1ce514b

File tree

6 files changed

+154
-114
lines changed

6 files changed

+154
-114
lines changed

auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-common/src/main/java/org/springframework/ai/mcp/client/common/autoconfigure/annotations/ClientSpecificationFactoryAutoConfiguration.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818

1919
import java.util.List;
2020

21+
import org.springaicommunity.mcp.annotation.McpElicitation;
22+
import org.springaicommunity.mcp.annotation.McpLogging;
23+
import org.springaicommunity.mcp.annotation.McpProgress;
24+
import org.springaicommunity.mcp.annotation.McpSampling;
2125
import org.springaicommunity.mcp.method.elicitation.AsyncElicitationSpecification;
2226
import org.springaicommunity.mcp.method.elicitation.SyncElicitationSpecification;
2327
import org.springaicommunity.mcp.method.logging.AsyncLoggingSpecification;
@@ -49,23 +53,27 @@ public class ClientSpecificationFactoryAutoConfiguration {
4953
static class SyncClientSpecificationConfiguration {
5054

5155
@Bean
52-
List<SyncLoggingSpecification> loggingSpecs(ClientMcpAnnotatedBeans beanRegistry) {
53-
return SyncMcpAnnotationProviders.loggingSpecifications(beanRegistry.getAllAnnotatedBeans());
56+
List<SyncLoggingSpecification> loggingSpecs(ClientMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
57+
return SyncMcpAnnotationProviders
58+
.loggingSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpLogging.class));
5459
}
5560

5661
@Bean
57-
List<SyncSamplingSpecification> samplingSpecs(ClientMcpAnnotatedBeans beanRegistry) {
58-
return SyncMcpAnnotationProviders.samplingSpecifications(beanRegistry.getAllAnnotatedBeans());
62+
List<SyncSamplingSpecification> samplingSpecs(ClientMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
63+
return SyncMcpAnnotationProviders
64+
.samplingSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpSampling.class));
5965
}
6066

6167
@Bean
62-
List<SyncElicitationSpecification> elicitationSpecs(ClientMcpAnnotatedBeans beanRegistry) {
63-
return SyncMcpAnnotationProviders.elicitationSpecifications(beanRegistry.getAllAnnotatedBeans());
68+
List<SyncElicitationSpecification> elicitationSpecs(ClientMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
69+
return SyncMcpAnnotationProviders
70+
.elicitationSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpElicitation.class));
6471
}
6572

6673
@Bean
67-
List<SyncProgressSpecification> progressSpecs(ClientMcpAnnotatedBeans beanRegistry) {
68-
return SyncMcpAnnotationProviders.progressSpecifications(beanRegistry.getAllAnnotatedBeans());
74+
List<SyncProgressSpecification> progressSpecs(ClientMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
75+
return SyncMcpAnnotationProviders
76+
.progressSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpProgress.class));
6977
}
7078

7179
}

auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common/src/main/java/org/springframework/ai/mcp/server/common/autoconfigure/annotations/ServerSpecificationFactoryAutoConfiguration.java

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818

1919
import java.util.List;
2020

21+
import org.springaicommunity.mcp.annotation.McpComplete;
22+
import org.springaicommunity.mcp.annotation.McpPrompt;
23+
import org.springaicommunity.mcp.annotation.McpResource;
24+
import org.springaicommunity.mcp.annotation.McpTool;
2125
import org.springframework.ai.mcp.annotation.spring.AsyncMcpAnnotationProviders;
2226
import org.springframework.ai.mcp.annotation.spring.SyncMcpAnnotationProviders;
2327
import org.springframework.ai.mcp.server.common.autoconfigure.McpServerAutoConfiguration;
@@ -46,24 +50,31 @@ public class ServerSpecificationFactoryAutoConfiguration {
4650
static class SyncServerSpecificationConfiguration {
4751

4852
@Bean
49-
public List<McpServerFeatures.SyncResourceSpecification> resourceSpecs(ServerMcpAnnotatedBeans beanRegistry) {
50-
return SyncMcpAnnotationProviders.resourceSpecifications(beanRegistry.getAllAnnotatedBeans());
53+
public List<McpServerFeatures.SyncResourceSpecification> resourceSpecs(
54+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
55+
return SyncMcpAnnotationProviders
56+
.resourceSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpResource.class));
5157
}
5258

5359
@Bean
54-
public List<McpServerFeatures.SyncPromptSpecification> promptSpecs(ServerMcpAnnotatedBeans beanRegistry) {
55-
return SyncMcpAnnotationProviders.promptSpecifications(beanRegistry.getAllAnnotatedBeans());
60+
public List<McpServerFeatures.SyncPromptSpecification> promptSpecs(
61+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
62+
return SyncMcpAnnotationProviders
63+
.promptSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpPrompt.class));
5664
}
5765

5866
@Bean
5967
public List<McpServerFeatures.SyncCompletionSpecification> completionSpecs(
60-
ServerMcpAnnotatedBeans beanRegistry) {
61-
return SyncMcpAnnotationProviders.completeSpecifications(beanRegistry.getAllAnnotatedBeans());
68+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
69+
return SyncMcpAnnotationProviders
70+
.completeSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpComplete.class));
6271
}
6372

6473
@Bean
65-
public List<McpServerFeatures.SyncToolSpecification> toolSpecs(ServerMcpAnnotatedBeans beanRegistry) {
66-
return SyncMcpAnnotationProviders.toolSpecifications(beanRegistry.getAllAnnotatedBeans());
74+
public List<McpServerFeatures.SyncToolSpecification> toolSpecs(
75+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
76+
return SyncMcpAnnotationProviders
77+
.toolSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpTool.class));
6778
}
6879

6980
}
@@ -73,24 +84,31 @@ public List<McpServerFeatures.SyncToolSpecification> toolSpecs(ServerMcpAnnotate
7384
static class AsyncServerSpecificationConfiguration {
7485

7586
@Bean
76-
public List<McpServerFeatures.AsyncResourceSpecification> resourceSpecs(ServerMcpAnnotatedBeans beanRegistry) {
77-
return AsyncMcpAnnotationProviders.resourceSpecifications(beanRegistry.getAllAnnotatedBeans());
87+
public List<McpServerFeatures.AsyncResourceSpecification> resourceSpecs(
88+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
89+
return AsyncMcpAnnotationProviders
90+
.resourceSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpResource.class));
7891
}
7992

8093
@Bean
81-
public List<McpServerFeatures.AsyncPromptSpecification> promptSpecs(ServerMcpAnnotatedBeans beanRegistry) {
82-
return AsyncMcpAnnotationProviders.promptSpecifications(beanRegistry.getAllAnnotatedBeans());
94+
public List<McpServerFeatures.AsyncPromptSpecification> promptSpecs(
95+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
96+
return AsyncMcpAnnotationProviders
97+
.promptSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpPrompt.class));
8398
}
8499

85100
@Bean
86101
public List<McpServerFeatures.AsyncCompletionSpecification> completionSpecs(
87-
ServerMcpAnnotatedBeans beanRegistry) {
88-
return AsyncMcpAnnotationProviders.completeSpecifications(beanRegistry.getAllAnnotatedBeans());
102+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
103+
return AsyncMcpAnnotationProviders
104+
.completeSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpComplete.class));
89105
}
90106

91107
@Bean
92-
public List<McpServerFeatures.AsyncToolSpecification> toolSpecs(ServerMcpAnnotatedBeans beanRegistry) {
93-
return AsyncMcpAnnotationProviders.toolSpecifications(beanRegistry.getAllAnnotatedBeans());
108+
public List<McpServerFeatures.AsyncToolSpecification> toolSpecs(
109+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
110+
return AsyncMcpAnnotationProviders
111+
.toolSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpTool.class));
94112
}
95113

96114
}

auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common/src/main/java/org/springframework/ai/mcp/server/common/autoconfigure/annotations/StatelessServerSpecificationFactoryAutoConfiguration.java

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818

1919
import java.util.List;
2020

21+
import org.springaicommunity.mcp.annotation.McpComplete;
22+
import org.springaicommunity.mcp.annotation.McpPrompt;
23+
import org.springaicommunity.mcp.annotation.McpResource;
24+
import org.springaicommunity.mcp.annotation.McpTool;
2125
import org.springframework.ai.mcp.annotation.spring.AsyncMcpAnnotationProviders;
2226
import org.springframework.ai.mcp.annotation.spring.SyncMcpAnnotationProviders;
2327
import org.springframework.ai.mcp.server.common.autoconfigure.McpServerStatelessAutoConfiguration;
@@ -52,25 +56,30 @@ static class SyncStatelessServerSpecificationConfiguration {
5256

5357
@Bean
5458
public List<McpStatelessServerFeatures.SyncResourceSpecification> resourceSpecs(
55-
ServerMcpAnnotatedBeans beanRegistry) {
56-
return SyncMcpAnnotationProviders.statelessResourceSpecifications(beanRegistry.getAllAnnotatedBeans());
59+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
60+
return SyncMcpAnnotationProviders
61+
.statelessResourceSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpResource.class));
5762
}
5863

5964
@Bean
6065
public List<McpStatelessServerFeatures.SyncPromptSpecification> promptSpecs(
61-
ServerMcpAnnotatedBeans beanRegistry) {
62-
return SyncMcpAnnotationProviders.statelessPromptSpecifications(beanRegistry.getAllAnnotatedBeans());
66+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
67+
return SyncMcpAnnotationProviders
68+
.statelessPromptSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpPrompt.class));
6369
}
6470

6571
@Bean
6672
public List<McpStatelessServerFeatures.SyncCompletionSpecification> completionSpecs(
67-
ServerMcpAnnotatedBeans beanRegistry) {
68-
return SyncMcpAnnotationProviders.statelessCompleteSpecifications(beanRegistry.getAllAnnotatedBeans());
73+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
74+
return SyncMcpAnnotationProviders
75+
.statelessCompleteSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpComplete.class));
6976
}
7077

7178
@Bean
72-
public List<McpServerFeatures.SyncToolSpecification> toolSpecs(ServerMcpAnnotatedBeans beanRegistry) {
73-
return SyncMcpAnnotationProviders.toolSpecifications(beanRegistry.getAllAnnotatedBeans());
79+
public List<McpServerFeatures.SyncToolSpecification> toolSpecs(
80+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
81+
return SyncMcpAnnotationProviders
82+
.toolSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpTool.class));
7483
}
7584

7685
}
@@ -81,25 +90,30 @@ static class AsyncStatelessServerSpecificationConfiguration {
8190

8291
@Bean
8392
public List<McpStatelessServerFeatures.AsyncResourceSpecification> resourceSpecs(
84-
ServerMcpAnnotatedBeans beanRegistry) {
85-
return AsyncMcpAnnotationProviders.statelessResourceSpecifications(beanRegistry.getAllAnnotatedBeans());
93+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
94+
return AsyncMcpAnnotationProviders
95+
.statelessResourceSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpResource.class));
8696
}
8797

8898
@Bean
8999
public List<McpStatelessServerFeatures.AsyncPromptSpecification> promptSpecs(
90-
ServerMcpAnnotatedBeans beanRegistry) {
91-
return AsyncMcpAnnotationProviders.statelessPromptSpecifications(beanRegistry.getAllAnnotatedBeans());
100+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
101+
return AsyncMcpAnnotationProviders
102+
.statelessPromptSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpPrompt.class));
92103
}
93104

94105
@Bean
95106
public List<McpStatelessServerFeatures.AsyncCompletionSpecification> completionSpecs(
96-
ServerMcpAnnotatedBeans beanRegistry) {
97-
return AsyncMcpAnnotationProviders.statelessCompleteSpecifications(beanRegistry.getAllAnnotatedBeans());
107+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
108+
return AsyncMcpAnnotationProviders
109+
.statelessCompleteSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpComplete.class));
98110
}
99111

100112
@Bean
101-
public List<McpStatelessServerFeatures.AsyncToolSpecification> toolSpecs(ServerMcpAnnotatedBeans beanRegistry) {
102-
return AsyncMcpAnnotationProviders.statelessToolSpecifications(beanRegistry.getAllAnnotatedBeans());
113+
public List<McpStatelessServerFeatures.AsyncToolSpecification> toolSpecs(
114+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
115+
return AsyncMcpAnnotationProviders
116+
.statelessToolSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpTool.class));
103117
}
104118

105119
}

auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-webflux/src/test/java/org/springframework/ai/mcp/server/autoconfigure/StreamableMcpAnnotationsIT.java

Lines changed: 16 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,15 @@
4444
import org.springaicommunity.mcp.annotation.McpSampling;
4545
import org.springaicommunity.mcp.annotation.McpTool;
4646
import org.springaicommunity.mcp.annotation.McpToolParam;
47-
import org.springaicommunity.mcp.method.elicitation.SyncElicitationSpecification;
48-
import org.springaicommunity.mcp.method.logging.SyncLoggingSpecification;
49-
import org.springaicommunity.mcp.method.progress.SyncProgressSpecification;
50-
import org.springaicommunity.mcp.method.sampling.SyncSamplingSpecification;
51-
import org.springframework.ai.mcp.annotation.spring.SyncMcpAnnotationProviders;
5247
import org.springframework.ai.mcp.client.common.autoconfigure.McpClientAutoConfiguration;
5348
import org.springframework.ai.mcp.client.common.autoconfigure.McpToolCallbackAutoConfiguration;
49+
import org.springframework.ai.mcp.client.common.autoconfigure.annotations.ClientAnnotationScannerAutoConfiguration;
50+
import org.springframework.ai.mcp.client.common.autoconfigure.annotations.ClientSpecificationFactoryAutoConfiguration;
5451
import org.springframework.ai.mcp.client.webflux.autoconfigure.StreamableHttpWebFluxTransportAutoConfiguration;
5552
import org.springframework.ai.mcp.server.common.autoconfigure.McpServerAutoConfiguration;
5653
import org.springframework.ai.mcp.server.common.autoconfigure.ToolCallbackConverterAutoConfiguration;
54+
import org.springframework.ai.mcp.server.common.autoconfigure.annotations.ServerAnnotationScannerAutoConfiguration;
55+
import org.springframework.ai.mcp.server.common.autoconfigure.annotations.ServerSpecificationFactoryAutoConfiguration;
5756
import org.springframework.ai.mcp.server.common.autoconfigure.properties.McpServerProperties;
5857
import org.springframework.ai.mcp.server.common.autoconfigure.properties.McpServerStreamableHttpProperties;
5958
import org.springframework.beans.factory.ObjectProvider;
@@ -71,7 +70,6 @@
7170
import com.fasterxml.jackson.databind.ObjectMapper;
7271

7372
import io.modelcontextprotocol.client.McpSyncClient;
74-
import io.modelcontextprotocol.server.McpServerFeatures;
7573
import io.modelcontextprotocol.server.McpSyncServer;
7674
import io.modelcontextprotocol.server.McpSyncServerExchange;
7775
import io.modelcontextprotocol.server.transport.WebFluxStreamableServerTransportProvider;
@@ -104,11 +102,13 @@ public class StreamableMcpAnnotationsIT {
104102
private final ApplicationContextRunner serverContextRunner = new ApplicationContextRunner()
105103
.withPropertyValues("spring.ai.mcp.server.protocol=STREAMABLE")
106104
.withConfiguration(AutoConfigurations.of(McpServerAutoConfiguration.class,
107-
ToolCallbackConverterAutoConfiguration.class, McpServerStreamableHttpWebFluxAutoConfiguration.class));
105+
ToolCallbackConverterAutoConfiguration.class, McpServerStreamableHttpWebFluxAutoConfiguration.class,
106+
ServerAnnotationScannerAutoConfiguration.class, ServerSpecificationFactoryAutoConfiguration.class));
108107

109108
private final ApplicationContextRunner clientApplicationContext = new ApplicationContextRunner()
110109
.withConfiguration(AutoConfigurations.of(McpToolCallbackAutoConfiguration.class,
111-
McpClientAutoConfiguration.class, StreamableHttpWebFluxTransportAutoConfiguration.class));
110+
McpClientAutoConfiguration.class, StreamableHttpWebFluxTransportAutoConfiguration.class,
111+
ClientAnnotationScannerAutoConfiguration.class, ClientSpecificationFactoryAutoConfiguration.class));
112112

113113
@Test
114114
void clientServerCapabilities() {
@@ -118,6 +118,8 @@ void clientServerCapabilities() {
118118
this.serverContextRunner.withUserConfiguration(TestMcpServerConfiguration.class)
119119
.withPropertyValues(// @formatter:off
120120
"spring.ai.mcp.server.name=test-mcp-server",
121+
// "spring.ai.mcp.server.type=ASYNC",
122+
// "spring.ai.mcp.server.protocol=SSE",
121123
"spring.ai.mcp.server.version=1.0.0",
122124
"spring.ai.mcp.server.streamable-http.keep-alive-interval=1s",
123125
// "spring.ai.mcp.server.requestTimeout=1m",
@@ -143,6 +145,7 @@ void clientServerCapabilities() {
143145
clientApplicationContext.withUserConfiguration(TestMcpClientConfiguration.class)
144146
.withPropertyValues(// @formatter:off
145147
"spring.ai.mcp.client.streamable-http.connections.server1.url=http://localhost:" + serverPort,
148+
// "spring.ai.mcp.client.sse.connections.server1.url=http://localhost:" + serverPort,
146149
// "spring.ai.mcp.client.request-timeout=20m",
147150
"spring.ai.mcp.client.initialized=false") // @formatter:on
148151
.run(clientContext -> {
@@ -393,28 +396,6 @@ public McpServerHandlers serverSideSpecProviders() {
393396
return new McpServerHandlers();
394397
}
395398

396-
@Bean
397-
public List<McpServerFeatures.SyncToolSpecification> myTools(McpServerHandlers serverSideSpecProviders) {
398-
return SyncMcpAnnotationProviders.toolSpecifications(List.of(serverSideSpecProviders));
399-
}
400-
401-
@Bean
402-
public List<McpServerFeatures.SyncResourceSpecification> myResources(
403-
McpServerHandlers serverSideSpecProviders) {
404-
return SyncMcpAnnotationProviders.resourceSpecifications(List.of(serverSideSpecProviders));
405-
}
406-
407-
@Bean
408-
public List<McpServerFeatures.SyncPromptSpecification> myPrompts(McpServerHandlers serverSideSpecProviders) {
409-
return SyncMcpAnnotationProviders.promptSpecifications(List.of(serverSideSpecProviders));
410-
}
411-
412-
@Bean
413-
public List<McpServerFeatures.SyncCompletionSpecification> myCompletions(
414-
McpServerHandlers serverSideSpecProviders) {
415-
return SyncMcpAnnotationProviders.completeSpecifications(List.of(serverSideSpecProviders));
416-
}
417-
418399
}
419400

420401
public static class TestMcpClientConfiguration {
@@ -429,13 +410,13 @@ public static class TestContext {
429410

430411
}
431412

432-
public static class McpClientHandlers {
413+
public static class TestMcpClientHandlers {
433414

434-
private static final Logger logger = LoggerFactory.getLogger(McpClientHandlers.class);
415+
private static final Logger logger = LoggerFactory.getLogger(TestMcpClientHandlers.class);
435416

436417
private TestContext testContext;
437418

438-
public McpClientHandlers(TestContext testContext) {
419+
public TestMcpClientHandlers(TestContext testContext) {
439420
this.testContext = testContext;
440421
}
441422

@@ -480,28 +461,8 @@ public TestContext testContext() {
480461
}
481462

482463
@Bean
483-
public McpClientHandlers mcpClientHandlers(TestContext testContext) {
484-
return new McpClientHandlers(testContext);
485-
}
486-
487-
@Bean
488-
List<SyncLoggingSpecification> loggingSpecs(McpClientHandlers clientMcpHandlers) {
489-
return SyncMcpAnnotationProviders.loggingSpecifications(List.of(clientMcpHandlers));
490-
}
491-
492-
@Bean
493-
List<SyncSamplingSpecification> samplingSpecs(McpClientHandlers clientMcpHandlers) {
494-
return SyncMcpAnnotationProviders.samplingSpecifications(List.of(clientMcpHandlers));
495-
}
496-
497-
@Bean
498-
List<SyncElicitationSpecification> elicitationSpecs(McpClientHandlers clientMcpHandlers) {
499-
return SyncMcpAnnotationProviders.elicitationSpecifications(List.of(clientMcpHandlers));
500-
}
501-
502-
@Bean
503-
List<SyncProgressSpecification> progressSpecs(McpClientHandlers clientMcpHandlers) {
504-
return SyncMcpAnnotationProviders.progressSpecifications(List.of(clientMcpHandlers));
464+
public TestMcpClientHandlers mcpClientHandlers(TestContext testContext) {
465+
return new TestMcpClientHandlers(testContext);
505466
}
506467

507468
}

0 commit comments

Comments
 (0)