Skip to content

Commit 8b7b3bb

Browse files
committed
Update weather example remote
1 parent 9b771d0 commit 8b7b3bb

File tree

4 files changed

+114
-1
lines changed

4 files changed

+114
-1
lines changed

integrations/mcp/tests/imperative/pom.xml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<artifactId>helidon-integrations-mcp-imperative-tests</artifactId>
3131

3232
<properties>
33-
<mainClass>io.helidon.integrations.mcp.tests.imperative.McpWeatherServer</mainClass>
33+
<mainClass>io.helidon.integrations.mcp.tests.imperative.McpDemoServer</mainClass>
3434
</properties>
3535

3636
<dependencies>
@@ -39,6 +39,14 @@
3939
<artifactId>helidon-integrations-mcp-server</artifactId>
4040
<version>${project.version}</version>
4141
</dependency>
42+
<dependency>
43+
<groupId>io.helidon.webclient</groupId>
44+
<artifactId>helidon-webclient</artifactId>
45+
</dependency>
46+
<dependency>
47+
<groupId>io.helidon.http.media</groupId>
48+
<artifactId>helidon-http-media-jackson</artifactId>
49+
</dependency>
4250
<dependency>
4351
<groupId>io.helidon.logging</groupId>
4452
<artifactId>helidon-logging-slf4j</artifactId>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.helidon.integrations.mcp.tests.imperative;
2+
3+
import io.helidon.integrations.mcp.server.McpHttpFeatureConfig;
4+
import io.helidon.webserver.WebServer;
5+
6+
public class McpDemoServer {
7+
8+
public static void main(String[] args) {
9+
WebServer.builder()
10+
.port(8081)
11+
.routing(routing -> routing.addFeature(
12+
McpHttpFeatureConfig.builder()
13+
.addTool(new McpWeatherTool())))
14+
.build()
15+
.start();
16+
}
17+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package io.helidon.integrations.mcp.tests.imperative;
2+
3+
import java.util.List;
4+
import java.util.stream.Collectors;
5+
6+
import io.helidon.integrations.mcp.server.JsonSchema;
7+
import io.helidon.integrations.mcp.server.McpParameters;
8+
import io.helidon.integrations.mcp.server.Tool;
9+
import io.helidon.integrations.mcp.server.ToolContent;
10+
import io.helidon.integrations.mcp.server.ToolContents;
11+
import io.helidon.webclient.api.HttpClientResponse;
12+
import io.helidon.webclient.api.WebClient;
13+
14+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
15+
import com.fasterxml.jackson.annotation.JsonProperty;
16+
import com.fasterxml.jackson.core.JsonProcessingException;
17+
import com.fasterxml.jackson.core.type.TypeReference;
18+
import com.fasterxml.jackson.databind.ObjectMapper;
19+
20+
public class McpWeatherTool implements Tool {
21+
private final WebClient webClient;
22+
23+
McpWeatherTool() {
24+
webClient = WebClient.builder()
25+
.baseUri("https://api.weather.gov")
26+
.addHeader("Accept", "application/geo+json")
27+
.addHeader("User-Agent", "WeatherApiClient/1.0 ([email protected])")
28+
.build();
29+
}
30+
31+
@Override
32+
public String name() {
33+
return "weather-state-report";
34+
}
35+
36+
@Override
37+
public String description() {
38+
return "Get a weather report per US state";
39+
}
40+
41+
@Override
42+
public JsonSchema schema() {
43+
return JsonSchema.builder()
44+
.addString("state")
45+
.build();
46+
}
47+
48+
@Override
49+
public ToolContent process(McpParameters parameters) {
50+
String state = parameters.get("state").asString().orElse("");
51+
52+
try (HttpClientResponse response = webClient.get()
53+
.path("/alerts/active/area/" + state)
54+
.request()) {
55+
Alert alert = new ObjectMapper().readValue(response.as(String.class), new TypeReference<>() {});
56+
String content = alert.features()
57+
.stream()
58+
.map(f -> String.format("""
59+
Event: %s
60+
Area: %s
61+
Severity: %s
62+
Description: %s
63+
Instructions: %s
64+
""", f.properties().event(), f.properties.areaDesc(), f.properties.severity(),
65+
f.properties.description(), f.properties.instruction()))
66+
.collect(Collectors.joining("\n"));
67+
return ToolContents.textContent(content);
68+
} catch (JsonProcessingException e) {
69+
throw new RuntimeException(e);
70+
}
71+
}
72+
73+
@JsonIgnoreProperties(ignoreUnknown = true)
74+
public record Alert(@JsonProperty("features") List<Feature> features) {
75+
76+
@JsonIgnoreProperties(ignoreUnknown = true)
77+
public record Feature(@JsonProperty("properties") Properties properties) {}
78+
79+
@JsonIgnoreProperties(ignoreUnknown = true)
80+
public record Properties(@JsonProperty("event") String event,
81+
@JsonProperty("areaDesc") String areaDesc,
82+
@JsonProperty("severity") String severity,
83+
@JsonProperty("description") String description,
84+
@JsonProperty("instruction") String instruction) {}
85+
}
86+
}

integrations/mcp/tests/imperative/src/main/java/module-info.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
requires io.helidon.webserver;
1919
requires io.helidon.service.registry;
2020
requires jakarta.json;
21+
requires com.fasterxml.jackson.databind;
22+
requires io.helidon.webclient.api;
2123

2224
exports io.helidon.integrations.mcp.tests.imperative;
2325
}

0 commit comments

Comments
 (0)