Skip to content

Commit ad07232

Browse files
authored
samples: update mcp-kotlin to 0.10.0 across sample projects (#645)
## Update mcp-kotlin to 0.10.0 across sample projects ## How Has This Been Tested? Locally, added ServerIntegrationTest to simple-streamable-server ## Breaking Changes No ## Types of changes - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [x] Documentation update - [x] Test update ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [x] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [x] My code follows the repository's style guidelines - [x] New and existing tests pass locally - [ ] I have added appropriate error handling - [ ] I have added or updated documentation as needed
1 parent 6e247f9 commit ad07232

File tree

6 files changed

+453
-233
lines changed

6 files changed

+453
-233
lines changed

samples/kotlin-mcp-client/gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
anthropic = "2.18.0"
33
kotlin = "2.2.21"
44
ktor = "3.2.3"
5-
mcp-kotlin = "0.9.0"
5+
mcp-kotlin = "0.10.0"
66
shadow = "9.4.1"
77
slf4j = "2.0.17"
88

samples/notebooks/McpClient.ipynb

Lines changed: 286 additions & 231 deletions
Large diffs are not rendered by default.

samples/simple-streamable-server/build.gradle.kts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ dependencies {
2222
implementation(libs.ktor.server.sse)
2323
implementation(libs.ktor.serialization.kotlinx.json)
2424
implementation(libs.slf4j.simple)
25+
26+
testImplementation(libs.mcp.kotlin.client)
27+
testImplementation(libs.ktor.client.cio)
28+
testImplementation(libs.junit.jupiter)
29+
testImplementation(kotlin("test"))
30+
}
31+
32+
tasks.test {
33+
useJUnitPlatform()
2534
}
2635

2736
kotlin {

samples/simple-streamable-server/gradle/libs.versions.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
[versions]
22
kotlin = "2.2.21"
33
ktor = "3.2.3"
4-
mcp-kotlin = "0.9.0"
4+
junit = "6.0.3"
5+
mcp-kotlin = "0.10.0"
56
slf4j = "2.0.17"
67
shadow = "9.4.1"
78

@@ -13,7 +14,10 @@ ktor-server-content-negotiation = { group = "io.ktor", name = "ktor-server-conte
1314
ktor-serialization-kotlinx-json = { group = "io.ktor", name = "ktor-serialization-kotlinx-json" }
1415
ktor-server-auth = { group = "io.ktor", name = "ktor-server-auth" }
1516
ktor-server-sse = { group = "io.ktor", name = "ktor-server-sse" }
17+
mcp-kotlin-client = { group = "io.modelcontextprotocol", name = "kotlin-sdk-client", version.ref = "mcp-kotlin" }
1618
mcp-kotlin-server = { group = "io.modelcontextprotocol", name = "kotlin-sdk-server", version.ref = "mcp-kotlin" }
19+
ktor-client-cio = { group = "io.ktor", name = "ktor-client-cio" }
20+
junit-jupiter = { group = "org.junit.jupiter", name = "junit-jupiter", version.ref = "junit" }
1721
slf4j-simple = { group = "org.slf4j", name = "slf4j-simple", version.ref = "slf4j" }
1822

1923
[plugins]
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package io.modelcontextprotocol.sample.server
2+
3+
import io.ktor.client.HttpClient
4+
import io.ktor.client.engine.cio.CIO
5+
import io.ktor.client.plugins.sse.SSE
6+
import io.ktor.server.engine.embeddedServer
7+
import io.ktor.server.netty.Netty
8+
import io.modelcontextprotocol.kotlin.sdk.client.Client
9+
import io.modelcontextprotocol.kotlin.sdk.client.mcpStreamableHttp
10+
import io.modelcontextprotocol.kotlin.sdk.types.GetPromptRequest
11+
import io.modelcontextprotocol.kotlin.sdk.types.GetPromptRequestParams
12+
import io.modelcontextprotocol.kotlin.sdk.types.ReadResourceRequest
13+
import io.modelcontextprotocol.kotlin.sdk.types.ReadResourceRequestParams
14+
import io.modelcontextprotocol.kotlin.sdk.types.Role
15+
import io.modelcontextprotocol.kotlin.sdk.types.TextContent
16+
import io.modelcontextprotocol.kotlin.sdk.types.TextResourceContents
17+
import org.junit.jupiter.api.AfterAll
18+
import org.junit.jupiter.api.BeforeAll
19+
import org.junit.jupiter.api.Test
20+
import org.junit.jupiter.api.TestInstance
21+
import kotlin.test.assertEquals
22+
import kotlin.test.assertIs
23+
import kotlin.test.assertNotNull
24+
25+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
26+
class ServerIntegrationTest {
27+
28+
private val server = embeddedServer(Netty, host = "127.0.0.1", port = 0) {
29+
configureServer()
30+
}
31+
32+
private val httpClient = HttpClient(CIO) {
33+
install(SSE)
34+
}
35+
36+
private lateinit var mcpClient: Client
37+
38+
@BeforeAll
39+
suspend fun beforeAll() {
40+
server.start(wait = false)
41+
val port = server.engine.resolvedConnectors().single().port
42+
43+
mcpClient = httpClient.mcpStreamableHttp(
44+
url = "http://127.0.0.1:$port/mcp",
45+
)
46+
}
47+
48+
@AfterAll
49+
suspend fun afterAll() {
50+
mcpClient.close()
51+
httpClient.close()
52+
server.stop(500, 1000)
53+
}
54+
55+
@Test
56+
fun `should negotiate server capabilities`() {
57+
val capabilities = mcpClient.serverCapabilities
58+
assertNotNull(capabilities)
59+
assertNotNull(capabilities.tools)
60+
assertNotNull(capabilities.prompts)
61+
assertNotNull(capabilities.resources)
62+
assertNotNull(capabilities.logging)
63+
}
64+
65+
@Test
66+
fun `should report server version`() {
67+
val version = mcpClient.serverVersion
68+
assertNotNull(version)
69+
assertEquals("simple-streamable-http-server", version.name)
70+
assertEquals("1.0.0", version.version)
71+
}
72+
73+
@Test
74+
suspend fun `should list tools`() {
75+
val result = mcpClient.listTools()
76+
val toolNames = result.tools.map { it.name }.sorted()
77+
assertEquals(listOf("greet", "multi-greet"), toolNames)
78+
}
79+
80+
@Test
81+
suspend fun `should call greet tool`() {
82+
val result = mcpClient.callTool(name = "greet", arguments = mapOf("name" to "Alice"))
83+
val content = result.content.single()
84+
assertIs<TextContent>(content)
85+
assertEquals("Hello, Alice!", content.text)
86+
}
87+
88+
@Test
89+
suspend fun `should call greet tool with default name`() {
90+
val result = mcpClient.callTool(name = "greet", arguments = emptyMap())
91+
val content = result.content.single()
92+
assertIs<TextContent>(content)
93+
assertEquals("Hello, World!", content.text)
94+
}
95+
96+
@Test
97+
suspend fun `should call multi-greet tool with logging notifications`() {
98+
val result = mcpClient.callTool(name = "multi-greet", arguments = mapOf("name" to "Bob"))
99+
val content = result.content.single()
100+
assertIs<TextContent>(content)
101+
assertEquals("Good morning, Bob!", content.text)
102+
}
103+
104+
@Test
105+
suspend fun `should list prompts`() {
106+
val result = mcpClient.listPrompts()
107+
assertEquals(listOf("greeting-template"), result.prompts.map { it.name })
108+
}
109+
110+
@Test
111+
suspend fun `should get greeting template prompt`() {
112+
val result = mcpClient.getPrompt(
113+
GetPromptRequest(
114+
GetPromptRequestParams(
115+
name = "greeting-template",
116+
arguments = mapOf("name" to "Charlie"),
117+
),
118+
),
119+
)
120+
val message = result.messages.single()
121+
assertEquals(Role.User, message.role)
122+
val content = message.content
123+
assertIs<TextContent>(content)
124+
assertEquals("Please greet Charlie in a friendly manner.", content.text)
125+
}
126+
127+
@Test
128+
suspend fun `should list resources`() {
129+
val result = mcpClient.listResources()
130+
assertEquals(listOf("Default Greeting"), result.resources.map { it.name })
131+
}
132+
133+
@Test
134+
suspend fun `should read default greeting resource`() {
135+
val result = mcpClient.readResource(
136+
ReadResourceRequest(
137+
ReadResourceRequestParams(uri = "https://example.com/greetings/default"),
138+
),
139+
)
140+
val content = result.contents.single()
141+
assertIs<TextResourceContents>(content)
142+
assertEquals("Hello, world!", content.text)
143+
assertEquals("text/plain", content.mimeType)
144+
}
145+
}
146+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
org.slf4j.simpleLogger.defaultLogLevel=INFO
2+
org.slf4j.simpleLogger.showThreadName=true
3+
org.slf4j.simpleLogger.showDateTime=false
4+
5+
# Log level for specific packages or classes
6+
org.slf4j.simpleLogger.log.io.modelcontextprotocol.sample.server=DEBUG

0 commit comments

Comments
 (0)