From 01c628de917012c84e24392780bd747c2e5839bd Mon Sep 17 00:00:00 2001 From: Christian Tzolov Date: Wed, 23 Jul 2025 15:17:13 +0200 Subject: [PATCH] refactor: migrate MCP annotations from logaritex to springaicommunity package - Update dependency groupId from com.logaritex.mcp to org.springaicommunity - Bump version to 0.2.0-SNAPSHOT - Update all imports to use new org.springaicommunity.mcp package structure - Rename SpringAiMcpAnnotationProvider to SyncMcpAnnotationProvider - Rename WeatherService to SpringAiToolProvider for clarity - Add new McpToolProvider with weather API integration - Add SyncToolSpecification support for MCP tools Signed-off-by: Christian Tzolov --- .../mcp-annotations-server/pom.xml | 4 +- .../sample/server/AutocompleteProvider.java | 2 +- .../sample/server/McpServerApplication.java | 17 +++-- .../ai/mcp/sample/server/McpToolProvider.java | 64 +++++++++++++++++++ .../ai/mcp/sample/server/PromptProvider.java | 4 +- ...Service.java => SpringAiToolProvider.java} | 6 +- .../server/UserProfileResourceProvider.java | 2 +- 7 files changed, 85 insertions(+), 14 deletions(-) create mode 100644 model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/McpToolProvider.java rename model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/{WeatherService.java => SpringAiToolProvider.java} (97%) diff --git a/model-context-protocol/mcp-annotations-server/pom.xml b/model-context-protocol/mcp-annotations-server/pom.xml index 484430b2..bae38e1a 100644 --- a/model-context-protocol/mcp-annotations-server/pom.xml +++ b/model-context-protocol/mcp-annotations-server/pom.xml @@ -32,9 +32,9 @@ - com.logaritex.mcp + org.springaicommunity spring-ai-mcp-annotations - 0.1.0 + 0.2.0-SNAPSHOT org.springframework.ai diff --git a/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/AutocompleteProvider.java b/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/AutocompleteProvider.java index 113a4e14..ab040138 100644 --- a/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/AutocompleteProvider.java +++ b/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/AutocompleteProvider.java @@ -19,10 +19,10 @@ import java.util.List; import java.util.Map; -import com.logaritex.mcp.annotation.McpComplete; import io.modelcontextprotocol.spec.McpSchema.CompleteRequest; import io.modelcontextprotocol.spec.McpSchema.CompleteResult; import io.modelcontextprotocol.spec.McpSchema.CompleteResult.CompleteCompletion; +import org.springaicommunity.mcp.annotation.McpComplete; import org.springframework.stereotype.Service; diff --git a/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/McpServerApplication.java b/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/McpServerApplication.java index 72165e64..3db91072 100644 --- a/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/McpServerApplication.java +++ b/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/McpServerApplication.java @@ -2,10 +2,11 @@ import java.util.List; -import com.logaritex.mcp.spring.SpringAiMcpAnnotationProvider; import io.modelcontextprotocol.server.McpServerFeatures.SyncCompletionSpecification; import io.modelcontextprotocol.server.McpServerFeatures.SyncPromptSpecification; import io.modelcontextprotocol.server.McpServerFeatures.SyncResourceSpecification; +import io.modelcontextprotocol.server.McpServerFeatures.SyncToolSpecification; +import org.springaicommunity.mcp.spring.SyncMcpAnnotationProvider; import org.springframework.ai.tool.ToolCallbackProvider; import org.springframework.ai.tool.method.MethodToolCallbackProvider; @@ -21,23 +22,29 @@ public static void main(String[] args) { } @Bean - public ToolCallbackProvider weatherTools(WeatherService weatherService) { + public ToolCallbackProvider weatherTools(SpringAiToolProvider weatherService) { return MethodToolCallbackProvider.builder().toolObjects(weatherService).build(); } @Bean public List resourceSpecs(UserProfileResourceProvider userProfileResourceProvider) { - return SpringAiMcpAnnotationProvider.createSyncResourceSpecifications(List.of(userProfileResourceProvider)); + return SyncMcpAnnotationProvider.createSyncResourceSpecifications(List.of(userProfileResourceProvider)); } @Bean public List promptSpecs(PromptProvider promptProvider) { - return SpringAiMcpAnnotationProvider.createSyncPromptSpecifications(List.of(promptProvider)); + return SyncMcpAnnotationProvider.createSyncPromptSpecifications(List.of(promptProvider)); } @Bean public List completionSpecs(AutocompleteProvider autocompleteProvider) { - return SpringAiMcpAnnotationProvider.createSyncCompleteSpecifications(List.of(autocompleteProvider)); + return SyncMcpAnnotationProvider.createSyncCompleteSpecifications(List.of(autocompleteProvider)); + } + + @Bean + public List toolSpecs(McpToolProvider toolProvider) { + var toolSpecs = SyncMcpAnnotationProvider.createSyncToolSpecifications(List.of(toolProvider)); + return toolSpecs; } } diff --git a/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/McpToolProvider.java b/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/McpToolProvider.java new file mode 100644 index 00000000..9226fc12 --- /dev/null +++ b/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/McpToolProvider.java @@ -0,0 +1,64 @@ +/* +* Copyright 2025 - 2025 the original author or authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* https://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package org.springframework.ai.mcp.sample.server; + +import java.time.LocalDateTime; + +import org.slf4j.Logger; +import org.springaicommunity.mcp.annotation.McpTool; +import org.springaicommunity.mcp.annotation.McpToolParam; + +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestClient; + +/** + * @author Christian Tzolov + */ +@Service +public class McpToolProvider { + + private static final Logger logger = org.slf4j.LoggerFactory.getLogger(McpToolProvider.class); + + private final RestClient restClient; + + public McpToolProvider() { + this.restClient = RestClient.create(); + } + + public record WeatherResponse(Current current) { + public record Current(LocalDateTime time, int interval, double temperature_2m) { + } + } + + @McpTool(description = "Get the temperature (in celsius) for a specific location") + public WeatherResponse getTemperature(@McpToolParam(description = "The location latitude") double latitude, + @McpToolParam(description = "The location longitude") double longitude, + @McpToolParam(description = "The city name") String city) { + + WeatherResponse response = restClient + .get() + .uri("https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}¤t=temperature_2m", + latitude, longitude) + .retrieve() + .body(WeatherResponse.class); + + logger.info("Check temparature for {}. Lat: {}, Lon: {}. Temp: {}", city, latitude, longitude, + response.current); + + return response; + } + +} diff --git a/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/PromptProvider.java b/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/PromptProvider.java index d252ec26..ffa4273d 100644 --- a/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/PromptProvider.java +++ b/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/PromptProvider.java @@ -18,8 +18,6 @@ import java.util.List; import java.util.Map; -import com.logaritex.mcp.annotation.McpArg; -import com.logaritex.mcp.annotation.McpPrompt; import io.modelcontextprotocol.server.McpSyncServerExchange; import io.modelcontextprotocol.spec.McpSchema.GetPromptRequest; import io.modelcontextprotocol.spec.McpSchema.GetPromptResult; @@ -28,6 +26,8 @@ import io.modelcontextprotocol.spec.McpSchema.PromptMessage; import io.modelcontextprotocol.spec.McpSchema.Role; import io.modelcontextprotocol.spec.McpSchema.TextContent; +import org.springaicommunity.mcp.annotation.McpArg; +import org.springaicommunity.mcp.annotation.McpPrompt; import org.springframework.stereotype.Service; diff --git a/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/WeatherService.java b/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/SpringAiToolProvider.java similarity index 97% rename from model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/WeatherService.java rename to model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/SpringAiToolProvider.java index 5966ea13..63a4c59a 100644 --- a/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/WeatherService.java +++ b/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/SpringAiToolProvider.java @@ -28,13 +28,13 @@ import org.springframework.web.client.RestClientException; @Service -public class WeatherService { +public class SpringAiToolProvider { private static final String BASE_URL = "https://api.weather.gov"; private final RestClient restClient; - public WeatherService() { + public SpringAiToolProvider() { this.restClient = RestClient.builder() .baseUrl(BASE_URL) @@ -137,7 +137,7 @@ public String getAlerts(String state) { } public static void main(String[] args) { - WeatherService client = new WeatherService(); + SpringAiToolProvider client = new SpringAiToolProvider(); System.out.println(client.getWeatherForecastByLocation(47.6062, -122.3321)); System.out.println(client.getAlerts("NY")); } diff --git a/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/UserProfileResourceProvider.java b/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/UserProfileResourceProvider.java index 16686856..df9e6bb2 100644 --- a/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/UserProfileResourceProvider.java +++ b/model-context-protocol/mcp-annotations-server/src/main/java/org/springframework/ai/mcp/sample/server/UserProfileResourceProvider.java @@ -19,12 +19,12 @@ import java.util.List; import java.util.Map; -import com.logaritex.mcp.annotation.McpResource; import io.modelcontextprotocol.server.McpSyncServerExchange; import io.modelcontextprotocol.spec.McpSchema.ReadResourceRequest; import io.modelcontextprotocol.spec.McpSchema.ReadResourceResult; import io.modelcontextprotocol.spec.McpSchema.ResourceContents; import io.modelcontextprotocol.spec.McpSchema.TextResourceContents; +import org.springaicommunity.mcp.annotation.McpResource; import org.springframework.stereotype.Service;