Skip to content

Commit 97ac810

Browse files
tzolovilayaperumalg
authored andcommitted
feat: Add MCP resource template support to server auto-configurations
- Add ResourceTemplateSpecification support for both sync and async servers - Include resource template handling in stateful and stateless configurations - Add resource template bean definitions and provider methods - Update tests to verify resource template registration and functionality - Upgrade MCP SDK to 0.14.0-SNAPSHOT and mcp-annotations to 0.5.0-SNAPSHOT This extends the existing MCP resource capabilities by adding support for parameterized resource templates, enabling more flexible resource provisioning in MCP server implementations. Signed-off-by: Christian Tzolov <[email protected]>
1 parent b915413 commit 97ac810

File tree

9 files changed

+167
-9
lines changed

9 files changed

+167
-9
lines changed

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@
3131
import io.modelcontextprotocol.server.McpServerFeatures.AsyncCompletionSpecification;
3232
import io.modelcontextprotocol.server.McpServerFeatures.AsyncPromptSpecification;
3333
import io.modelcontextprotocol.server.McpServerFeatures.AsyncResourceSpecification;
34+
import io.modelcontextprotocol.server.McpServerFeatures.AsyncResourceTemplateSpecification;
3435
import io.modelcontextprotocol.server.McpServerFeatures.AsyncToolSpecification;
3536
import io.modelcontextprotocol.server.McpServerFeatures.SyncCompletionSpecification;
3637
import io.modelcontextprotocol.server.McpServerFeatures.SyncPromptSpecification;
3738
import io.modelcontextprotocol.server.McpServerFeatures.SyncResourceSpecification;
39+
import io.modelcontextprotocol.server.McpServerFeatures.SyncResourceTemplateSpecification;
3840
import io.modelcontextprotocol.server.McpServerFeatures.SyncToolSpecification;
3941
import io.modelcontextprotocol.server.McpSyncServer;
4042
import io.modelcontextprotocol.server.McpSyncServerExchange;
@@ -111,6 +113,7 @@ public McpSyncServer mcpSyncServer(McpServerTransportProviderBase transportProvi
111113
McpServerChangeNotificationProperties changeNotificationProperties,
112114
ObjectProvider<List<SyncToolSpecification>> tools,
113115
ObjectProvider<List<SyncResourceSpecification>> resources,
116+
ObjectProvider<List<SyncResourceTemplateSpecification>> resourceTemplates,
114117
ObjectProvider<List<SyncPromptSpecification>> prompts,
115118
ObjectProvider<List<SyncCompletionSpecification>> completions,
116119
ObjectProvider<BiConsumer<McpSyncServerExchange, List<McpSchema.Root>>> rootsChangeConsumers,
@@ -157,6 +160,21 @@ public McpSyncServer mcpSyncServer(McpServerTransportProviderBase transportProvi
157160
}
158161
}
159162

163+
// Resources Templates
164+
if (serverProperties.getCapabilities().isResource()) {
165+
logger.info("Enable resources templates capabilities, notification: "
166+
+ changeNotificationProperties.isResourceChangeNotification());
167+
capabilitiesBuilder.resources(false, changeNotificationProperties.isResourceChangeNotification());
168+
169+
List<SyncResourceTemplateSpecification> resourceTemplateSpecifications = resourceTemplates.stream()
170+
.flatMap(List::stream)
171+
.toList();
172+
if (!CollectionUtils.isEmpty(resourceTemplateSpecifications)) {
173+
serverBuilder.resourceTemplates(resourceTemplateSpecifications);
174+
logger.info("Registered resource templates: " + resourceTemplateSpecifications.size());
175+
}
176+
}
177+
160178
// Prompts
161179
if (serverProperties.getCapabilities().isPrompt()) {
162180
logger.info("Enable prompts capabilities, notification: "
@@ -210,6 +228,7 @@ public McpAsyncServer mcpAsyncServer(McpServerTransportProviderBase transportPro
210228
McpServerChangeNotificationProperties changeNotificationProperties,
211229
ObjectProvider<List<AsyncToolSpecification>> tools,
212230
ObjectProvider<List<AsyncResourceSpecification>> resources,
231+
ObjectProvider<List<AsyncResourceTemplateSpecification>> resourceTemplates,
213232
ObjectProvider<List<AsyncPromptSpecification>> prompts,
214233
ObjectProvider<List<AsyncCompletionSpecification>> completions,
215234
ObjectProvider<BiConsumer<McpAsyncServerExchange, List<McpSchema.Root>>> rootsChangeConsumer) {
@@ -255,6 +274,21 @@ public McpAsyncServer mcpAsyncServer(McpServerTransportProviderBase transportPro
255274
}
256275
}
257276

277+
// Resources Templates
278+
if (serverProperties.getCapabilities().isResource()) {
279+
logger.info("Enable resources templates capabilities, notification: "
280+
+ changeNotificationProperties.isResourceChangeNotification());
281+
capabilitiesBuilder.resources(false, changeNotificationProperties.isResourceChangeNotification());
282+
283+
List<AsyncResourceTemplateSpecification> resourceTemplateSpecifications = resourceTemplates.stream()
284+
.flatMap(List::stream)
285+
.toList();
286+
if (!CollectionUtils.isEmpty(resourceTemplateSpecifications)) {
287+
serverBuilder.resourceTemplates(resourceTemplateSpecifications);
288+
logger.info("Registered resources templates: " + resourceTemplateSpecifications.size());
289+
}
290+
}
291+
258292
// Prompts
259293
if (serverProperties.getCapabilities().isPrompt()) {
260294
logger.info("Enable prompts capabilities, notification: "

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@
2626
import io.modelcontextprotocol.server.McpStatelessServerFeatures.AsyncCompletionSpecification;
2727
import io.modelcontextprotocol.server.McpStatelessServerFeatures.AsyncPromptSpecification;
2828
import io.modelcontextprotocol.server.McpStatelessServerFeatures.AsyncResourceSpecification;
29+
import io.modelcontextprotocol.server.McpStatelessServerFeatures.AsyncResourceTemplateSpecification;
2930
import io.modelcontextprotocol.server.McpStatelessServerFeatures.AsyncToolSpecification;
3031
import io.modelcontextprotocol.server.McpStatelessServerFeatures.SyncCompletionSpecification;
3132
import io.modelcontextprotocol.server.McpStatelessServerFeatures.SyncPromptSpecification;
3233
import io.modelcontextprotocol.server.McpStatelessServerFeatures.SyncResourceSpecification;
34+
import io.modelcontextprotocol.server.McpStatelessServerFeatures.SyncResourceTemplateSpecification;
3335
import io.modelcontextprotocol.server.McpStatelessServerFeatures.SyncToolSpecification;
3436
import io.modelcontextprotocol.server.McpStatelessSyncServer;
3537
import io.modelcontextprotocol.spec.McpSchema;
@@ -80,6 +82,7 @@ public McpStatelessSyncServer mcpStatelessSyncServer(McpStatelessServerTransport
8082
McpSchema.ServerCapabilities.Builder capabilitiesBuilder, McpServerProperties serverProperties,
8183
ObjectProvider<List<SyncToolSpecification>> tools,
8284
ObjectProvider<List<SyncResourceSpecification>> resources,
85+
ObjectProvider<List<SyncResourceTemplateSpecification>> resourceTemplates,
8386
ObjectProvider<List<SyncPromptSpecification>> prompts,
8487
ObjectProvider<List<SyncCompletionSpecification>> completions, Environment environment) {
8588

@@ -113,6 +116,19 @@ public McpStatelessSyncServer mcpStatelessSyncServer(McpStatelessServerTransport
113116
}
114117
}
115118

119+
// Resources Templates
120+
if (serverProperties.getCapabilities().isResource()) {
121+
capabilitiesBuilder.resources(false, false);
122+
123+
List<SyncResourceTemplateSpecification> resourceSpecifications = resourceTemplates.stream()
124+
.flatMap(List::stream)
125+
.toList();
126+
if (!CollectionUtils.isEmpty(resourceSpecifications)) {
127+
serverBuilder.resourceTemplates(resourceSpecifications);
128+
logger.info("Registered resource templates: " + resourceSpecifications.size());
129+
}
130+
}
131+
116132
// Prompts
117133
if (serverProperties.getCapabilities().isPrompt()) {
118134
capabilitiesBuilder.prompts(false);
@@ -156,6 +172,7 @@ public McpStatelessAsyncServer mcpStatelessAsyncServer(McpStatelessServerTranspo
156172
McpSchema.ServerCapabilities.Builder capabilitiesBuilder, McpServerProperties serverProperties,
157173
ObjectProvider<List<AsyncToolSpecification>> tools,
158174
ObjectProvider<List<AsyncResourceSpecification>> resources,
175+
ObjectProvider<List<AsyncResourceTemplateSpecification>> resourceTemplates,
159176
ObjectProvider<List<AsyncPromptSpecification>> prompts,
160177
ObjectProvider<List<AsyncCompletionSpecification>> completions) {
161178

@@ -189,6 +206,19 @@ public McpStatelessAsyncServer mcpStatelessAsyncServer(McpStatelessServerTranspo
189206
}
190207
}
191208

209+
// Resources Templates
210+
if (serverProperties.getCapabilities().isResource()) {
211+
capabilitiesBuilder.resources(false, false);
212+
213+
List<AsyncResourceTemplateSpecification> resourceSpecifications = resourceTemplates.stream()
214+
.flatMap(List::stream)
215+
.toList();
216+
if (!CollectionUtils.isEmpty(resourceSpecifications)) {
217+
serverBuilder.resourceTemplates(resourceSpecifications);
218+
logger.info("Registered resource templates: " + resourceSpecifications.size());
219+
}
220+
}
221+
192222
// Prompts
193223
if (serverProperties.getCapabilities().isPrompt()) {
194224
capabilitiesBuilder.prompts(false);

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

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,15 @@ public List<McpServerFeatures.SyncResourceSpecification> resourceSpecs(
6060
return syncResourceSpecifications;
6161
}
6262

63+
@Bean
64+
public List<McpServerFeatures.SyncResourceTemplateSpecification> resourceTemplateSpecs(
65+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
66+
67+
List<McpServerFeatures.SyncResourceTemplateSpecification> syncResourceTemplateSpecifications = SyncMcpAnnotationProviders
68+
.resourceTemplateSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpResource.class));
69+
return syncResourceTemplateSpecifications;
70+
}
71+
6372
@Bean
6473
public List<McpServerFeatures.SyncPromptSpecification> promptSpecs(
6574
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
@@ -78,9 +87,7 @@ public List<McpServerFeatures.SyncCompletionSpecification> completionSpecs(
7887
public List<McpServerFeatures.SyncToolSpecification> toolSpecs(
7988
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
8089
List<Object> beansByAnnotation = beansWithMcpMethodAnnotations.getBeansByAnnotation(McpTool.class);
81-
List<McpServerFeatures.SyncToolSpecification> syncToolSpecifications = SyncMcpAnnotationProviders
82-
.toolSpecifications(beansByAnnotation);
83-
return syncToolSpecifications;
90+
return SyncMcpAnnotationProviders.toolSpecifications(beansByAnnotation);
8491
}
8592

8693
}
@@ -96,6 +103,14 @@ public List<McpServerFeatures.AsyncResourceSpecification> resourceSpecs(
96103
.resourceSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpResource.class));
97104
}
98105

106+
@Bean
107+
public List<McpServerFeatures.AsyncResourceTemplateSpecification> resourceTemplateSpecs(
108+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
109+
110+
return AsyncMcpAnnotationProviders
111+
.resourceTemplateSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpResource.class));
112+
}
113+
99114
@Bean
100115
public List<McpServerFeatures.AsyncPromptSpecification> promptSpecs(
101116
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ public List<McpStatelessServerFeatures.SyncResourceSpecification> resourceSpecs(
6060
.statelessResourceSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpResource.class));
6161
}
6262

63+
@Bean
64+
public List<McpStatelessServerFeatures.SyncResourceTemplateSpecification> resourceTemplateSpecs(
65+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
66+
return SyncMcpAnnotationProviders.statelessResourceTemplateSpecifications(
67+
beansWithMcpMethodAnnotations.getBeansByAnnotation(McpResource.class));
68+
}
69+
6370
@Bean
6471
public List<McpStatelessServerFeatures.SyncPromptSpecification> promptSpecs(
6572
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
@@ -96,6 +103,13 @@ public List<McpStatelessServerFeatures.AsyncResourceSpecification> resourceSpecs
96103
.statelessResourceSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpResource.class));
97104
}
98105

106+
@Bean
107+
public List<McpStatelessServerFeatures.AsyncResourceTemplateSpecification> resourceTemplateSpecs(
108+
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
109+
return AsyncMcpAnnotationProviders.statelessResourceTemplateSpecifications(
110+
beansWithMcpMethodAnnotations.getBeansByAnnotation(McpResource.class));
111+
}
112+
99113
@Bean
100114
public List<McpStatelessServerFeatures.AsyncPromptSpecification> promptSpecs(
101115
ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {

auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common/src/test/java/org/springframework/ai/mcp/server/common/autoconfigure/McpServerAutoConfigurationIT.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import io.modelcontextprotocol.server.McpServerFeatures.AsyncCompletionSpecification;
3232
import io.modelcontextprotocol.server.McpServerFeatures.AsyncPromptSpecification;
3333
import io.modelcontextprotocol.server.McpServerFeatures.AsyncResourceSpecification;
34+
import io.modelcontextprotocol.server.McpServerFeatures.AsyncResourceTemplateSpecification;
3435
import io.modelcontextprotocol.server.McpServerFeatures.AsyncToolSpecification;
3536
import io.modelcontextprotocol.server.McpServerFeatures.SyncCompletionSpecification;
3637
import io.modelcontextprotocol.server.McpServerFeatures.SyncPromptSpecification;
@@ -379,7 +380,12 @@ void syncServerSpecificationConfiguration() {
379380
ConcurrentHashMap<String, AsyncResourceSpecification> resources = (ConcurrentHashMap<String, AsyncResourceSpecification>) ReflectionTestUtils
380381
.getField(asyncServer, "resources");
381382
assertThat(resources).hasSize(1);
382-
assertThat(resources.get("config://{key}")).isNotNull();
383+
assertThat(resources.get("simple://static")).isNotNull();
384+
385+
ConcurrentHashMap<String, AsyncResourceTemplateSpecification> resourceTemplatess = (ConcurrentHashMap<String, AsyncResourceTemplateSpecification>) ReflectionTestUtils
386+
.getField(asyncServer, "resourceTemplates");
387+
assertThat(resourceTemplatess).hasSize(1);
388+
assertThat(resourceTemplatess.get("config://{key}")).isNotNull();
383389

384390
ConcurrentHashMap<String, AsyncPromptSpecification> prompts = (ConcurrentHashMap<String, AsyncPromptSpecification>) ReflectionTestUtils
385391
.getField(asyncServer, "prompts");
@@ -412,7 +418,12 @@ void asyncServerSpecificationConfiguration() {
412418
ConcurrentHashMap<String, AsyncResourceSpecification> resources = (ConcurrentHashMap<String, AsyncResourceSpecification>) ReflectionTestUtils
413419
.getField(asyncServer, "resources");
414420
assertThat(resources).hasSize(1);
415-
assertThat(resources.get("config://{key}")).isNotNull();
421+
assertThat(resources.get("simple://static")).isNotNull();
422+
423+
ConcurrentHashMap<String, AsyncResourceTemplateSpecification> resourceTemplatess = (ConcurrentHashMap<String, AsyncResourceTemplateSpecification>) ReflectionTestUtils
424+
.getField(asyncServer, "resourceTemplates");
425+
assertThat(resourceTemplatess).hasSize(1);
426+
assertThat(resourceTemplatess.get("config://{key}")).isNotNull();
416427

417428
ConcurrentHashMap<String, AsyncPromptSpecification> prompts = (ConcurrentHashMap<String, AsyncPromptSpecification>) ReflectionTestUtils
418429
.getField(asyncServer, "prompts");
@@ -608,6 +619,11 @@ public int add(@McpToolParam(description = "First number", required = true) int
608619
return a + b;
609620
}
610621

622+
@McpResource(uri = "simple://static", name = "Configuration", description = "Provides configuration data")
623+
public String getSimple() {
624+
return "Hi there!";
625+
}
626+
611627
@McpResource(uri = "config://{key}", name = "Configuration", description = "Provides configuration data")
612628
public String getConfig(String key) {
613629
return "config value";
@@ -644,6 +660,11 @@ public Mono<Integer> add(@McpToolParam(description = "First number", required =
644660
return Mono.just(a + b);
645661
}
646662

663+
@McpResource(uri = "simple://static", name = "Configuration", description = "Provides configuration data")
664+
public Mono<String> getSimple() {
665+
return Mono.just("Hi there!");
666+
}
667+
647668
@McpResource(uri = "config://{key}", name = "Configuration", description = "Provides configuration data")
648669
public Mono<String> getConfig(String key) {
649670
return Mono.just("config value");

auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common/src/test/java/org/springframework/ai/mcp/server/common/autoconfigure/McpStatelessServerAutoConfigurationIT.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import io.modelcontextprotocol.server.McpStatelessServerFeatures.AsyncCompletionSpecification;
3131
import io.modelcontextprotocol.server.McpStatelessServerFeatures.AsyncPromptSpecification;
3232
import io.modelcontextprotocol.server.McpStatelessServerFeatures.AsyncResourceSpecification;
33+
import io.modelcontextprotocol.server.McpStatelessServerFeatures.AsyncResourceTemplateSpecification;
3334
import io.modelcontextprotocol.server.McpStatelessServerFeatures.AsyncToolSpecification;
3435
import io.modelcontextprotocol.server.McpStatelessServerFeatures.SyncCompletionSpecification;
3536
import io.modelcontextprotocol.server.McpStatelessServerFeatures.SyncPromptSpecification;
@@ -330,7 +331,12 @@ void syncStatelessServerSpecificationConfiguration() {
330331
ConcurrentHashMap<String, AsyncResourceSpecification> resources = (ConcurrentHashMap<String, AsyncResourceSpecification>) ReflectionTestUtils
331332
.getField(asyncServer, "resources");
332333
assertThat(resources).hasSize(1);
333-
assertThat(resources.get("config://{key}")).isNotNull();
334+
assertThat(resources.get("simple://static")).isNotNull();
335+
336+
ConcurrentHashMap<String, AsyncResourceTemplateSpecification> resourceTemplates = (ConcurrentHashMap<String, AsyncResourceTemplateSpecification>) ReflectionTestUtils
337+
.getField(asyncServer, "resourceTemplates");
338+
assertThat(resourceTemplates).hasSize(1);
339+
assertThat(resourceTemplates.get("config://{key}")).isNotNull();
334340

335341
ConcurrentHashMap<String, AsyncPromptSpecification> prompts = (ConcurrentHashMap<String, AsyncPromptSpecification>) ReflectionTestUtils
336342
.getField(asyncServer, "prompts");
@@ -363,7 +369,12 @@ void asyncStatelessServerSpecificationConfiguration() {
363369
ConcurrentHashMap<String, AsyncResourceSpecification> resources = (ConcurrentHashMap<String, AsyncResourceSpecification>) ReflectionTestUtils
364370
.getField(asyncServer, "resources");
365371
assertThat(resources).hasSize(1);
366-
assertThat(resources.get("config://{key}")).isNotNull();
372+
assertThat(resources.get("simple://static")).isNotNull();
373+
374+
ConcurrentHashMap<String, AsyncResourceTemplateSpecification> resourceTemplates = (ConcurrentHashMap<String, AsyncResourceTemplateSpecification>) ReflectionTestUtils
375+
.getField(asyncServer, "resourceTemplates");
376+
assertThat(resourceTemplates).hasSize(1);
377+
assertThat(resourceTemplates.get("config://{key}")).isNotNull();
367378

368379
ConcurrentHashMap<String, AsyncPromptSpecification> prompts = (ConcurrentHashMap<String, AsyncPromptSpecification>) ReflectionTestUtils
369380
.getField(asyncServer, "prompts");
@@ -530,6 +541,11 @@ public int add(@McpToolParam(description = "First number", required = true) int
530541
return a + b;
531542
}
532543

544+
@McpResource(uri = "simple://static", name = "Configuration", description = "Provides configuration data")
545+
public String getSimple() {
546+
return "Hi there!";
547+
}
548+
533549
@McpResource(uri = "config://{key}", name = "Configuration", description = "Provides configuration data")
534550
public String getConfig(String key) {
535551
return "config value";
@@ -566,6 +582,11 @@ public Mono<Integer> add(@McpToolParam(description = "First number", required =
566582
return Mono.just(a + b);
567583
}
568584

585+
@McpResource(uri = "simple://static", name = "Configuration", description = "Provides configuration data")
586+
public Mono<String> getSimple() {
587+
return Mono.just("Hi there!");
588+
}
589+
569590
@McpResource(uri = "config://{key}", name = "Configuration", description = "Provides configuration data")
570591
public Mono<String> getConfig(String key) {
571592
return Mono.just("config value");

mcp/mcp-annotations-spring/src/main/java/org/springframework/ai/mcp/annotation/spring/AsyncMcpAnnotationProviders.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import io.modelcontextprotocol.server.McpServerFeatures.AsyncCompletionSpecification;
2323
import io.modelcontextprotocol.server.McpServerFeatures.AsyncPromptSpecification;
2424
import io.modelcontextprotocol.server.McpServerFeatures.AsyncResourceSpecification;
25+
import io.modelcontextprotocol.server.McpServerFeatures.AsyncResourceTemplateSpecification;
2526
import io.modelcontextprotocol.server.McpServerFeatures.AsyncToolSpecification;
2627
import io.modelcontextprotocol.server.McpStatelessServerFeatures;
2728
import org.springaicommunity.mcp.method.changed.prompt.AsyncPromptListChangedSpecification;
@@ -119,6 +120,17 @@ public static List<McpStatelessServerFeatures.AsyncResourceSpecification> statel
119120
return new SpringAiAsyncStatelessResourceProvider(resourceObjects).getResourceSpecifications();
120121
}
121122

123+
// RESOURCE TEMPLATE
124+
public static List<AsyncResourceTemplateSpecification> resourceTemplateSpecifications(
125+
List<Object> resourceObjects) {
126+
return new SpringAiAsyncResourceProvider(resourceObjects).getResourceTemplateSpecifications();
127+
}
128+
129+
public static List<McpStatelessServerFeatures.AsyncResourceTemplateSpecification> statelessResourceTemplateSpecifications(
130+
List<Object> resourceObjects) {
131+
return new SpringAiAsyncStatelessResourceProvider(resourceObjects).getResourceTemplateSpecifications();
132+
}
133+
122134
// RESOURCE LIST CHANGED
123135
public static List<AsyncResourceListChangedSpecification> resourceListChangedSpecifications(
124136
List<Object> resourceListChangedObjects) {

0 commit comments

Comments
 (0)