Skip to content

Commit 03e2d2c

Browse files
committed
Update weather-stdio-server
1 parent 08a803e commit 03e2d2c

File tree

8 files changed

+60
-27
lines changed

8 files changed

+60
-27
lines changed

samples/weather-stdio-server/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ The project provides:
3030
Use the Gradle wrapper to build the application. In a terminal run:
3131

3232
```shell
33-
./gradlew clean build -x test
33+
./gradlew clean build
3434
```
3535

3636
To run the server:
3737

3838
```shell
39-
java -jar build/libs/<your-jar-name>.jar
39+
java -jar build/libs/weather-stdio-server-0.1.0-all.jar
4040
```
4141

4242
> [!NOTE]

samples/weather-stdio-server/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ dependencies {
1919
implementation(libs.ktor.server.cio)
2020
implementation(libs.ktor.client.cio)
2121
implementation(libs.slf4j.simple)
22+
runtimeOnly(libs.kotlin.logging)
23+
runtimeOnly(libs.kotlinx.collections.immutable)
2224

2325
testImplementation(kotlin("test"))
2426

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
org.gradle.configuration-cache=true
22
org.gradle.parallel=true
33
org.gradle.caching=true
4-

samples/weather-stdio-server/gradle/libs.versions.toml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
[versions]
2+
collections-immutable = "0.4.0"
3+
coroutines = "1.10.2"
24
kotlin = "2.2.20"
35
ktor = "3.3.0"
6+
logging = "7.0.13"
47
mcp-kotlin = "0.7.3"
5-
slf4j = "2.0.17"
68
shadow = "9.2.2"
7-
coroutines = "1.10.2"
9+
slf4j = "2.0.17"
810

911
[libraries]
12+
kotlin-logging = { group = "io.github.oshai", name = "kotlin-logging-jvm", version.ref = "logging" }
13+
kotlinx-collections-immutable = { group = "org.jetbrains.kotlinx", name = "kotlinx-collections-immutable-jvm", version.ref = "collections-immutable" }
14+
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "coroutines" }
1015
ktor-client-cio = { group = "io.ktor", name = "ktor-client-cio", version.ref = "ktor" }
1116
ktor-client-content-negotiation = { group = "io.ktor", name = "ktor-client-content-negotiation", version.ref = "ktor" }
1217
ktor-serialization-kotlinx-json = { group = "io.ktor", name = "ktor-serialization-kotlinx-json-jvm", version.ref = "ktor" }
1318
ktor-server-cio = { group = "io.ktor", name = "ktor-server-cio", version.ref = "ktor" }
1419
mcp-kotlin-client = { group = "io.modelcontextprotocol", name = "kotlin-sdk-client", version.ref = "mcp-kotlin" }
1520
mcp-kotlin-server = { group = "io.modelcontextprotocol", name = "kotlin-sdk-server", version.ref = "mcp-kotlin" }
1621
slf4j-simple = { group = "org.slf4j", name = "slf4j-simple", version.ref = "slf4j" }
17-
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "coroutines" }
1822

1923
[plugins]
2024
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }

samples/weather-stdio-server/src/main/kotlin/io/modelcontextprotocol/sample/server/McpWeatherServer.kt

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,38 @@
11
package io.modelcontextprotocol.sample.server
22

3-
import io.ktor.client.*
4-
import io.ktor.client.plugins.*
5-
import io.ktor.client.plugins.contentnegotiation.*
6-
import io.ktor.http.*
7-
import io.ktor.serialization.kotlinx.json.*
8-
import io.ktor.utils.io.streams.*
9-
import io.modelcontextprotocol.kotlin.sdk.*
3+
import io.ktor.client.HttpClient
4+
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
5+
import io.ktor.client.plugins.defaultRequest
6+
import io.ktor.http.ContentType
7+
import io.ktor.http.contentType
8+
import io.ktor.http.headers
9+
import io.ktor.serialization.kotlinx.json.json
10+
import io.ktor.utils.io.core.Input
11+
import io.ktor.utils.io.streams.asInput
12+
import io.modelcontextprotocol.kotlin.sdk.CallToolResult
13+
import io.modelcontextprotocol.kotlin.sdk.Implementation
14+
import io.modelcontextprotocol.kotlin.sdk.ServerCapabilities
15+
import io.modelcontextprotocol.kotlin.sdk.TextContent
16+
import io.modelcontextprotocol.kotlin.sdk.Tool
1017
import io.modelcontextprotocol.kotlin.sdk.server.Server
1118
import io.modelcontextprotocol.kotlin.sdk.server.ServerOptions
1219
import io.modelcontextprotocol.kotlin.sdk.server.StdioServerTransport
1320
import kotlinx.coroutines.Job
1421
import kotlinx.coroutines.runBlocking
22+
import kotlinx.io.Sink
1523
import kotlinx.io.asSink
1624
import kotlinx.io.buffered
17-
import kotlinx.serialization.json.*
25+
import kotlinx.serialization.json.Json
26+
import kotlinx.serialization.json.buildJsonObject
27+
import kotlinx.serialization.json.doubleOrNull
28+
import kotlinx.serialization.json.jsonPrimitive
29+
import kotlinx.serialization.json.put
30+
import kotlinx.serialization.json.putJsonObject
1831

19-
// Main function to run the MCP server
20-
fun `run mcp server`() {
32+
/**
33+
* Starts an MCP server that provides weather-related tools for fetching active weather alerts by state and weather forecasts by latitude/longitude.
34+
*/
35+
fun runMcpServer() {
2136
// Base URL for the Weather API
2237
val baseUrl = "https://api.weather.gov"
2338

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package io.modelcontextprotocol.sample.server
22

3-
fun main() = `run mcp server`()
3+
fun main() = runMcpServer()

samples/weather-stdio-server/src/test/kotlin/io/modelcontextprotocol/sample/client/ClientStdio.kt

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ import kotlinx.io.asSource
1111
import kotlinx.io.buffered
1212
import kotlinx.serialization.json.JsonObject
1313
import kotlinx.serialization.json.JsonPrimitive
14-
14+
import kotlinx.serialization.json.buildJsonObject
1515

1616
fun main(): Unit = runBlocking {
17-
val process = ProcessBuilder("java", "-jar", "build/libs/weather-stdio-server-0.1.0-all.jar")
17+
val process = ProcessBuilder("java", "-jar", "./build/libs/weather-stdio-server-0.1.0-all.jar")
1818
.start()
1919

2020
val transport = StdioClientTransport(
2121
input = process.inputStream.asSource().buffered(),
22-
output = process.outputStream.asSink().buffered()
22+
output = process.outputStream.asSink().buffered(),
2323
)
2424

2525
// Initialize the MCP client with client information
@@ -29,15 +29,17 @@ fun main(): Unit = runBlocking {
2929

3030
client.connect(transport)
3131

32-
33-
val toolsList = client.listTools()?.tools?.map { it.name }
32+
val toolsList = client.listTools().tools.map { it.name }
3433
println("Available Tools = $toolsList")
3534

3635
val weatherForecastResult = client.callTool(
3736
CallToolRequest(
3837
name = "get_forecast",
39-
arguments = JsonObject(mapOf("latitude" to JsonPrimitive(38.5816), "longitude" to JsonPrimitive(-121.4944)))
40-
)
38+
arguments = buildJsonObject {
39+
put("latitude", JsonPrimitive(38.5816))
40+
put("longitude", JsonPrimitive(-121.4944))
41+
},
42+
),
4143
)?.content?.map { if (it is TextContent) it.text else it.toString() }
4244

4345
println("Weather Forcast: ${weatherForecastResult?.joinToString(separator = "\n", prefix = "\n", postfix = "\n")}")
@@ -46,11 +48,11 @@ fun main(): Unit = runBlocking {
4648
client.callTool(
4749
CallToolRequest(
4850
name = "get_alerts",
49-
arguments = JsonObject(mapOf("state" to JsonPrimitive("TX")))
50-
)
51+
arguments = JsonObject(mapOf("state" to JsonPrimitive("TX"))),
52+
),
5153
)?.content?.map { if (it is TextContent) it.text else it.toString() }
5254

5355
println("Alert Response = $alertResult")
5456

5557
client.close()
56-
}
58+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package io.modelcontextprotocol.sample.client
2+
3+
import kotlin.test.Test
4+
5+
class FakeTest {
6+
7+
@Test
8+
fun testSomething() {
9+
assert(true) { "Bingo!" }
10+
}
11+
}

0 commit comments

Comments
 (0)