Skip to content

Commit 0a6490c

Browse files
authored
Add Kotlin Weather STDIO server sample (#50)
* Add Kotlin Weather STDIO server sample * Update gradle build command in Readme to exclude tests
1 parent c57c56e commit 0a6490c

File tree

13 files changed

+863
-0
lines changed

13 files changed

+863
-0
lines changed

Diff for: samples/weather-stdio-server/.gitignore

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
.gradle
2+
build/
3+
!gradle/wrapper/gradle-wrapper.jar
4+
!**/src/main/**/build/
5+
!**/src/test/**/build/
6+
7+
### IntelliJ IDEA ###
8+
.idea/
9+
*.iws
10+
*.iml
11+
*.ipr
12+
out/
13+
!**/src/main/**/out/
14+
!**/src/test/**/out/
15+
16+
### Kotlin ###
17+
.kotlin
18+
19+
### Eclipse ###
20+
.apt_generated
21+
.classpath
22+
.factorypath
23+
.project
24+
.settings
25+
.springBeans
26+
.sts4-cache
27+
bin/
28+
!**/src/main/**/bin/
29+
!**/src/test/**/bin/
30+
31+
### NetBeans ###
32+
/nbproject/private/
33+
/nbbuild/
34+
/dist/
35+
/nbdist/
36+
/.nb-gradle/
37+
38+
### VS Code ###
39+
.vscode/
40+
41+
### Mac OS ###
42+
.DS_Store

Diff for: samples/weather-stdio-server/README.md

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# Kotlin MCP Weather STDIO Server
2+
3+
This project demonstrates how to build a Model Context Protocol (MCP) server in Kotlin that provides weather-related
4+
tools by consuming the National Weather Service (weather.gov) API. The server uses STDIO as the transport layer and
5+
leverages the Kotlin MCP SDK to expose weather forecast and alert tools.
6+
7+
For more information about the MCP SDK and protocol, please refer to
8+
the [MCP documentation](https://modelcontextprotocol.io/introduction).
9+
10+
## Prerequisites
11+
12+
- Java 17 or later
13+
- Gradle (or the Gradle wrapper provided with the project)
14+
- Basic understanding of MCP concepts
15+
- Basic understanding of Kotlin and Kotlin ecosystems (sush as kotlinx-serialization, coroutines, ktor)
16+
17+
## MCP Weather Server
18+
19+
The project provides:
20+
21+
- A lightweight MCP server built with Kotlin.
22+
- STDIO transport layer implementation for server-client communication.
23+
- Two weather tools:
24+
- **Weather Forecast Tool** — returns details such as temperature, wind information, and a detailed forecast for a
25+
given latitude/longitude.
26+
- **Weather Alerts Tool** — returns active weather alerts for a given US state.
27+
28+
## Building and running
29+
30+
Use the Gradle wrapper to build the application. In a terminal run:
31+
32+
```shell
33+
./gradlew clean build -x test
34+
```
35+
36+
To run the server:
37+
38+
```shell
39+
java -jar build/libs/<your-jar-name>.jar
40+
```
41+
42+
> [!NOTE]
43+
> The server uses STDIO transport, so it is typically launched in an environment where the client connects via standard
44+
> input/output.
45+
46+
## Tool Implementation
47+
48+
The project registers two MCP tools using the Kotlin MCP SDK. Below is an overview of the core tool implementations:
49+
50+
### 1. Weather Forecast Tool
51+
52+
This tool fetches the weather forecast for a specific latitude and longitude using the `weather.gov` API.
53+
54+
Example tool registration in Kotlin:
55+
56+
```kotlin
57+
server.addTool(
58+
name = "get_forecast",
59+
description = """
60+
Get weather forecast for a specific latitude/longitude
61+
""".trimIndent(),
62+
inputSchema = Tool.Input(
63+
properties = JsonObject(
64+
mapOf(
65+
"latitude" to JsonObject(mapOf("type" to JsonPrimitive("number"))),
66+
"longitude" to JsonObject(mapOf("type" to JsonPrimitive("number"))),
67+
)
68+
),
69+
required = listOf("latitude", "longitude")
70+
)
71+
) { request ->
72+
// Implementation tool
73+
}
74+
```
75+
76+
### 2. Weather Alerts Tool
77+
78+
This tool retrieves active weather alerts for a US state.
79+
80+
Example tool registration in Kotlin:
81+
82+
```kotlin
83+
server.addTool(
84+
name = "get_alerts",
85+
description = """
86+
Get weather alerts for a US state. Input is Two-letter US state code (e.g. CA, NY)
87+
""".trimIndent(),
88+
inputSchema = Tool.Input(
89+
properties = JsonObject(
90+
mapOf(
91+
"state" to JsonObject(
92+
mapOf(
93+
"type" to JsonPrimitive("string"),
94+
"description" to JsonPrimitive("Two-letter US state code (e.g. CA, NY)")
95+
)
96+
),
97+
)
98+
),
99+
required = listOf("state")
100+
)
101+
) { request ->
102+
// Implementation tool
103+
}
104+
```
105+
106+
## Client Integration
107+
108+
### Kotlin Client Example
109+
110+
Since the server uses STDIO for transport, the client typically connects via standard input/output streams. A sample
111+
client implementation can be found in the tests, demonstrating how to send tool requests and process responses.
112+
113+
### Claude for Desktop
114+
115+
To integrate with Claude Desktop, add the following configuration to your Claude Desktop settings:
116+
117+
```json
118+
{
119+
"mcpServers": {
120+
"weather": {
121+
"command": "java",
122+
"args": [
123+
"-jar",
124+
"/absolute/path/to/<your-jar-name>.jar"
125+
]
126+
}
127+
}
128+
}
129+
```
130+
131+
> [!NOTE]
132+
> Replace `/absolute/path/to/<your-jar-name>.jar` with the actual absolute path to your built jar file.
133+
134+
## Additional Resources
135+
136+
- [MCP Specification](https://spec.modelcontextprotocol.io/)
137+
- [Kotlin MCP SDK](https://github.com/modelcontextprotocol/kotlin-sdk)
138+
- [Ktor Client Documentation](https://ktor.io/docs/welcome.html)
139+
- [Kotlinx Serialization](https://kotlinlang.org/docs/serialization.html)
140+

Diff for: samples/weather-stdio-server/build.gradle.kts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
plugins {
2+
kotlin("jvm") version "2.1.10"
3+
kotlin("plugin.serialization") version "2.1.10"
4+
id("com.github.johnrengelman.shadow") version "8.1.1"
5+
application
6+
}
7+
8+
application {
9+
mainClass.set("io.modelcontextprotocol.sample.server.MainKt")
10+
}
11+
12+
13+
group = "org.example"
14+
version = "0.1.0"
15+
16+
val mcpVersion = "0.3.0"
17+
val slf4jVersion = "2.0.9"
18+
val ktorVersion = "3.1.1"
19+
20+
dependencies {
21+
implementation("io.modelcontextprotocol:kotlin-sdk:$mcpVersion")
22+
implementation("org.slf4j:slf4j-nop:$slf4jVersion")
23+
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
24+
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
25+
testImplementation(kotlin("test"))
26+
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.1")
27+
}
28+
29+
tasks.test {
30+
useJUnitPlatform()
31+
}
32+
33+
kotlin {
34+
jvmToolchain(17)
35+
}

Diff for: samples/weather-stdio-server/gradle.properties

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
kotlin.code.style=official
42.7 KB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
distributionBase=GRADLE_USER_HOME
2+
distributionPath=wrapper/dists
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
4+
networkTimeout=10000
5+
validateDistributionUrl=true
6+
zipStoreBase=GRADLE_USER_HOME
7+
zipStorePath=wrapper/dists

0 commit comments

Comments
 (0)