@@ -36,7 +36,7 @@ To use the MCP Annotations core module in your project, add the following depend
3636<dependency >
3737 <groupId >org.springaicommunity</groupId >
3838 <artifactId >mcp-annotations</artifactId >
39- <version >0.1.0 </version >
39+ <version >0.2.0-SNAPSHOT </version >
4040</dependency >
4141```
4242
@@ -48,7 +48,7 @@ To use the Spring integration module, add the following dependency:
4848<dependency >
4949 <groupId >corg.springaicommunity</groupId >
5050 <artifactId >spring-ai-mcp-annotations</artifactId >
51- <version >0.1.0 </version >
51+ <version >0.2.0-SNAPSHOT </version >
5252</dependency >
5353```
5454
@@ -89,8 +89,9 @@ The core module provides a set of annotations and callback implementations for p
89891 . ** Complete** - For auto-completion functionality in prompts and URI templates
90902 . ** Prompt** - For generating prompt messages
91913 . ** Resource** - For accessing resources via URI templates
92- 4 . ** Logging Consumer** - For handling logging message notifications
93- 5 . ** Sampling** - For handling sampling requests
92+ 4 . ** Tool** - For implementing MCP tools with automatic JSON schema generation
93+ 5 . ** Logging Consumer** - For handling logging message notifications
94+ 6 . ** Sampling** - For handling sampling requests
9495
9596Each operation type has both synchronous and asynchronous implementations, allowing for flexible integration with different application architectures.
9697
@@ -105,6 +106,8 @@ The Spring integration module provides seamless integration with Spring AI and S
105106- ** ` @McpComplete ` ** - Annotates methods that provide completion functionality for prompts or URI templates
106107- ** ` @McpPrompt ` ** - Annotates methods that generate prompt messages
107108- ** ` @McpResource ` ** - Annotates methods that provide access to resources
109+ - ** ` @McpTool ` ** - Annotates methods that implement MCP tools with automatic JSON schema generation
110+ - ** ` @McpToolParam ` ** - Annotates tool method parameters with descriptions and requirement specifications
108111- ** ` @McpLoggingConsumer ` ** - Annotates methods that handle logging message notifications from MCP servers
109112- ** ` @McpSampling ` ** - Annotates methods that handle sampling requests from MCP servers
110113- ** ` @McpArg ` ** - Annotates method parameters as MCP arguments
@@ -133,6 +136,10 @@ The modules provide callback implementations for each operation type:
133136- ` SyncMcpLoggingConsumerMethodCallback ` - Synchronous implementation
134137- ` AsyncMcpLoggingConsumerMethodCallback ` - Asynchronous implementation using Reactor's Mono
135138
139+ #### Tool
140+ - ` SyncMcpToolMethodCallback ` - Synchronous implementation for tool method callbacks
141+ - ` AsyncMcpToolMethodCallback ` - Asynchronous implementation using Reactor's Mono
142+
136143#### Sampling
137144- ` AbstractMcpSamplingMethodCallback ` - Base class for sampling method callbacks
138145- ` SyncMcpSamplingMethodCallback ` - Synchronous implementation
@@ -145,6 +152,8 @@ The project includes provider classes that scan for annotated methods and create
145152- ` SyncMcpCompletionProvider ` - Processes ` @McpComplete ` annotations for synchronous operations
146153- ` SyncMcpPromptProvider ` - Processes ` @McpPrompt ` annotations for synchronous operations
147154- ` SyncMcpResourceProvider ` - Processes ` @McpResource ` annotations for synchronous operations
155+ - ` SyncMcpToolProvider ` - Processes ` @McpTool ` annotations for synchronous operations
156+ - ` AsyncMcpToolProvider ` - Processes ` @McpTool ` annotations for asynchronous operations
148157- ` SyncMcpLoggingConsumerProvider ` - Processes ` @McpLoggingConsumer ` annotations for synchronous operations
149158- ` AsyncMcpLoggingConsumerProvider ` - Processes ` @McpLoggingConsumer ` annotations for asynchronous operations
150159- ` SyncMcpSamplingProvider ` - Processes ` @McpSampling ` annotations for synchronous operations
@@ -325,6 +334,166 @@ public class MyResourceProvider {
325334}
326335```
327336
337+ ### Tool Example
338+
339+ ``` java
340+ public class CalculatorToolProvider {
341+
342+ @McpTool (name = " add" , description = " Add two numbers together" )
343+ public int add (
344+ @McpToolParam (description = " First number to add" , required = true ) int a ,
345+ @McpToolParam (description = " Second number to add" , required = true ) int b ) {
346+ return a + b;
347+ }
348+
349+ @McpTool (name = " multiply" , description = " Multiply two numbers" )
350+ public double multiply (
351+ @McpToolParam (description = " First number" , required = true ) double x ,
352+ @McpToolParam (description = " Second number" , required = true ) double y ) {
353+ return x * y;
354+ }
355+
356+ @McpTool (name = " calculate-area" ,
357+ description = " Calculate the area of a rectangle" ,
358+ annotations = @McpTool.McpAnnotations (
359+ title = " Rectangle Area Calculator" ,
360+ readOnlyHint = true ,
361+ destructiveHint = false ,
362+ idempotentHint = true
363+ ))
364+ public AreaResult calculateRectangleArea (
365+ @McpToolParam (description = " Width of the rectangle" , required = true ) double width ,
366+ @McpToolParam (description = " Height of the rectangle" , required = true ) double height ) {
367+
368+ double area = width * height;
369+ return new AreaResult (area, " square units" );
370+ }
371+
372+ @McpTool (name = " process-data" , description = " Process data with exchange context" )
373+ public String processData (
374+ McpSyncServerExchange exchange ,
375+ @McpToolParam (description = " Data to process" , required = true ) String data ) {
376+
377+ exchange. loggingNotification(LoggingMessageNotification . builder()
378+ .level(LoggingLevel . INFO )
379+ .data(" Processing data: " + data)
380+ .build());
381+
382+ return " Processed: " + data. toUpperCase();
383+ }
384+
385+ // Async tool example
386+ @McpTool (name = " async-calculation" , description = " Perform async calculation" )
387+ public Mono<String > asyncCalculation (
388+ @McpToolParam (description = " Input value" , required = true ) int value ) {
389+ return Mono . fromCallable(() - > {
390+ // Simulate some async work
391+ Thread . sleep(100 );
392+ return " Async result: " + (value * 2 );
393+ }). subscribeOn(Schedulers . boundedElastic());
394+ }
395+
396+ public static class AreaResult {
397+ public double area;
398+ public String unit;
399+
400+ public AreaResult (double area , String unit ) {
401+ this . area = area;
402+ this . unit = unit;
403+ }
404+ }
405+ }
406+ ```
407+
408+ ### Async Tool Example
409+
410+ ``` java
411+ public class AsyncToolProvider {
412+
413+ @McpTool (name = " fetch-data" , description = " Fetch data asynchronously" )
414+ public Mono<DataResponse > fetchData (
415+ @McpToolParam (description = " Data ID to fetch" , required = true ) String dataId ,
416+ @McpToolParam (description = " Include metadata" , required = false ) Boolean includeMetadata ) {
417+
418+ return Mono . fromCallable(() - > {
419+ // Simulate async data fetching
420+ DataResponse response = new DataResponse ();
421+ response. id = dataId;
422+ response. data = " Sample data for " + dataId;
423+ response. metadata = Boolean . TRUE. equals(includeMetadata) ?
424+ Map . of(" timestamp" , System . currentTimeMillis()) : null ;
425+ return response;
426+ }). subscribeOn(Schedulers . boundedElastic());
427+ }
428+
429+ @McpTool (name = " stream-process" , description = " Process data stream" )
430+ public Flux<String > streamProcess (
431+ @McpToolParam (description = " Number of items to process" , required = true ) int count ) {
432+
433+ return Flux . range(1 , count)
434+ .map(i - > " Processed item " + i)
435+ .delayElements(Duration . ofMillis(100 ));
436+ }
437+
438+ public static class DataResponse {
439+ public String id;
440+ public String data;
441+ public Map<String , Object > metadata;
442+ }
443+ }
444+ ```
445+
446+ ### Mcp Server with Tool capabilities
447+
448+ ``` java
449+ public class McpServerFactory {
450+
451+ public McpSyncServer createMcpServerWithTools (
452+ CalculatorToolProvider calculatorProvider ,
453+ MyResourceProvider resourceProvider ) {
454+
455+ List<SyncToolSpecification > toolSpecifications =
456+ new SyncMcpToolProvider (List . of(calculatorProvider)). getToolSpecifications();
457+
458+ List<SyncResourceSpecification > resourceSpecifications =
459+ new SyncMcpResourceProvider (List . of(resourceProvider)). getResourceSpecifications();
460+
461+ // Create a server with tool support
462+ McpSyncServer syncServer = McpServer . sync(transportProvider)
463+ .serverInfo(" calculator-server" , " 1.0.0" )
464+ .capabilities(ServerCapabilities . builder()
465+ .tools(true ) // Enable tool support
466+ .resources(true ) // Enable resource support
467+ .logging() // Enable logging support
468+ .build())
469+ .tools(toolSpecifications)
470+ .resources(resourceSpecifications)
471+ .build();
472+
473+ return syncServer;
474+ }
475+
476+ public McpAsyncServer createAsyncMcpServerWithTools (
477+ AsyncToolProvider asyncToolProvider ) {
478+
479+ List<AsyncToolSpecification > asyncToolSpecifications =
480+ new AsyncMcpToolProvider (List . of(asyncToolProvider)). getToolSpecifications();
481+
482+ // Create an async server with tool support
483+ McpAsyncServer asyncServer = McpServer . async(transportProvider)
484+ .serverInfo(" async-tool-server" , " 1.0.0" )
485+ .capabilities(ServerCapabilities . builder()
486+ .tools(true ) // Enable tool support
487+ .logging() // Enable logging support
488+ .build())
489+ .tools(asyncToolSpecifications)
490+ .build();
491+
492+ return asyncServer;
493+ }
494+ }
495+ ```
496+
328497### Mcp Server with Resource, Prompt and Completion capabilities
329498
330499``` java
@@ -506,6 +675,18 @@ public class McpConfig {
506675 return SpringAiMcpAnnotationProvider . createSyncResourceSpecifications(resourceProviders);
507676 }
508677
678+ @Bean
679+ public List<SyncToolSpecification > syncToolSpecifications (
680+ List<CalculatorToolProvider > toolProviders ) {
681+ return SpringAiMcpAnnotationProvider . createSyncToolSpecifications(toolProviders);
682+ }
683+
684+ @Bean
685+ public List<AsyncToolSpecification > asyncToolSpecifications (
686+ List<AsyncToolProvider > asyncToolProviders ) {
687+ return SpringAiMcpAnnotationProvider . createAsyncToolSpecifications(asyncToolProviders);
688+ }
689+
509690 @Bean
510691 public List<Consumer<LoggingMessageNotification > > syncLoggingConsumers (
511692 List<LoggingHandler > loggingHandlers ) {
@@ -533,6 +714,7 @@ public class McpConfig {
533714- ** Builder pattern for callback creation** - Clean and fluent API for creating method callbacks
534715- ** Comprehensive validation** - Ensures method signatures are compatible with MCP operations
535716- ** URI template support** - Powerful URI template handling for resource and completion operations
717+ - ** Tool support with automatic JSON schema generation** - Create MCP tools with automatic input/output schema generation from method signatures
536718- ** Logging consumer support** - Handle logging message notifications from MCP servers
537719- ** Sampling support** - Handle sampling requests from MCP servers
538720- ** Spring integration** - Seamless integration with Spring Framework and Spring AI
0 commit comments