From 1159332022c7bb87ecf9df268b62ad6d226642da Mon Sep 17 00:00:00 2001
From: Konstantin Pavlov <1517853+kpavlov@users.noreply.github.com>
Date: Wed, 3 Dec 2025 20:07:54 +0200
Subject: [PATCH] Update samples to use new schema
Refactor samples to use `kotlin-sdk.types`, update integration tests to assert `meta` is null, and adjust coroutine logic.
---
.../sample/client/MCPClient.kt | 12 +++++----
.../sample/server/server.kt | 24 ++++++++---------
.../test/kotlin/SseServerIntegrationTest.kt | 26 +++++++++++--------
3 files changed, 33 insertions(+), 29 deletions(-)
diff --git a/samples/kotlin-mcp-client/src/main/kotlin/io/modelcontextprotocol/sample/client/MCPClient.kt b/samples/kotlin-mcp-client/src/main/kotlin/io/modelcontextprotocol/sample/client/MCPClient.kt
index 0a0817e7..8360316e 100644
--- a/samples/kotlin-mcp-client/src/main/kotlin/io/modelcontextprotocol/sample/client/MCPClient.kt
+++ b/samples/kotlin-mcp-client/src/main/kotlin/io/modelcontextprotocol/sample/client/MCPClient.kt
@@ -9,12 +9,13 @@ import com.anthropic.models.messages.Tool
import com.anthropic.models.messages.ToolUnion
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.ObjectMapper
-import io.modelcontextprotocol.kotlin.sdk.EmptyJsonObject
-import io.modelcontextprotocol.kotlin.sdk.Implementation
-import io.modelcontextprotocol.kotlin.sdk.TextContent
import io.modelcontextprotocol.kotlin.sdk.client.Client
import io.modelcontextprotocol.kotlin.sdk.client.StdioClientTransport
+import io.modelcontextprotocol.kotlin.sdk.types.EmptyJsonObject
+import io.modelcontextprotocol.kotlin.sdk.types.Implementation
+import io.modelcontextprotocol.kotlin.sdk.types.TextContent
import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.yield
import kotlinx.io.asSink
import kotlinx.io.asSource
import kotlinx.io.buffered
@@ -137,8 +138,8 @@ class MCPClient : AutoCloseable {
"type": "tool_result",
"tool_name": $toolName,
"result": ${
- result?.content?.joinToString("\n") {
- (it as TextContent).text ?: ""
+ result.content.joinToString("\n") {
+ (it as TextContent).text
}
}
""".trimIndent(),
@@ -173,6 +174,7 @@ class MCPClient : AutoCloseable {
if (message.lowercase() == "quit") break
val response = processQuery(message)
println("\n$response")
+ yield()
}
}
diff --git a/samples/kotlin-mcp-server/src/main/kotlin/io/modelcontextprotocol/sample/server/server.kt b/samples/kotlin-mcp-server/src/main/kotlin/io/modelcontextprotocol/sample/server/server.kt
index a593377f..e707743d 100644
--- a/samples/kotlin-mcp-server/src/main/kotlin/io/modelcontextprotocol/sample/server/server.kt
+++ b/samples/kotlin-mcp-server/src/main/kotlin/io/modelcontextprotocol/sample/server/server.kt
@@ -14,23 +14,22 @@ import io.ktor.server.routing.routing
import io.ktor.server.sse.SSE
import io.ktor.server.sse.sse
import io.ktor.util.collections.ConcurrentMap
-import io.modelcontextprotocol.kotlin.sdk.CallToolResult
-import io.modelcontextprotocol.kotlin.sdk.GetPromptResult
-import io.modelcontextprotocol.kotlin.sdk.Implementation
-import io.modelcontextprotocol.kotlin.sdk.PromptArgument
-import io.modelcontextprotocol.kotlin.sdk.PromptMessage
-import io.modelcontextprotocol.kotlin.sdk.ReadResourceResult
-import io.modelcontextprotocol.kotlin.sdk.Role
-import io.modelcontextprotocol.kotlin.sdk.ServerCapabilities
-import io.modelcontextprotocol.kotlin.sdk.TextContent
-import io.modelcontextprotocol.kotlin.sdk.TextResourceContents
-import io.modelcontextprotocol.kotlin.sdk.Tool
import io.modelcontextprotocol.kotlin.sdk.server.Server
import io.modelcontextprotocol.kotlin.sdk.server.ServerOptions
import io.modelcontextprotocol.kotlin.sdk.server.ServerSession
import io.modelcontextprotocol.kotlin.sdk.server.SseServerTransport
import io.modelcontextprotocol.kotlin.sdk.server.StdioServerTransport
import io.modelcontextprotocol.kotlin.sdk.server.mcp
+import io.modelcontextprotocol.kotlin.sdk.types.CallToolResult
+import io.modelcontextprotocol.kotlin.sdk.types.GetPromptResult
+import io.modelcontextprotocol.kotlin.sdk.types.Implementation
+import io.modelcontextprotocol.kotlin.sdk.types.PromptArgument
+import io.modelcontextprotocol.kotlin.sdk.types.PromptMessage
+import io.modelcontextprotocol.kotlin.sdk.types.ReadResourceResult
+import io.modelcontextprotocol.kotlin.sdk.types.Role
+import io.modelcontextprotocol.kotlin.sdk.types.ServerCapabilities
+import io.modelcontextprotocol.kotlin.sdk.types.TextContent
+import io.modelcontextprotocol.kotlin.sdk.types.TextResourceContents
import kotlinx.coroutines.Job
import kotlinx.coroutines.runBlocking
import kotlinx.io.asSink
@@ -66,7 +65,7 @@ fun configureServer(): Server {
GetPromptResult(
messages = listOf(
PromptMessage(
- role = Role.user,
+ role = Role.User,
content = TextContent(
"Develop a kotlin project named ${request.arguments?.get("Project Name")}",
),
@@ -80,7 +79,6 @@ fun configureServer(): Server {
server.addTool(
name = "kotlin-sdk-tool",
description = "A test tool",
- inputSchema = Tool.Input(),
) { _ ->
CallToolResult(
content = listOf(TextContent("Hello, world!")),
diff --git a/samples/kotlin-mcp-server/src/test/kotlin/SseServerIntegrationTest.kt b/samples/kotlin-mcp-server/src/test/kotlin/SseServerIntegrationTest.kt
index 7f8b6a9a..9cbeddac 100644
--- a/samples/kotlin-mcp-server/src/test/kotlin/SseServerIntegrationTest.kt
+++ b/samples/kotlin-mcp-server/src/test/kotlin/SseServerIntegrationTest.kt
@@ -1,13 +1,14 @@
-import io.modelcontextprotocol.kotlin.sdk.EmptyJsonObject
-import io.modelcontextprotocol.kotlin.sdk.ReadResourceRequest
-import io.modelcontextprotocol.kotlin.sdk.TextContent
-import io.modelcontextprotocol.kotlin.sdk.TextResourceContents
import io.modelcontextprotocol.kotlin.sdk.client.Client
+import io.modelcontextprotocol.kotlin.sdk.types.ReadResourceRequest
+import io.modelcontextprotocol.kotlin.sdk.types.ReadResourceRequestParams
+import io.modelcontextprotocol.kotlin.sdk.types.TextContent
+import io.modelcontextprotocol.kotlin.sdk.types.TextResourceContents
import kotlinx.coroutines.runBlocking
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertIs
import kotlin.test.assertNotNull
+import kotlin.test.assertNull
import kotlin.test.assertTrue
class SseServerIntegrationTest {
@@ -20,7 +21,7 @@ class SseServerIntegrationTest {
val listToolsResult = client.listTools()
// then
- assertEquals(expected = EmptyJsonObject, actual = listToolsResult._meta)
+ assertNull(listToolsResult.meta)
val tools = listToolsResult.tools
assertEquals(actual = tools.size, expected = 1)
@@ -33,7 +34,7 @@ class SseServerIntegrationTest {
val listPromptsResult = client.listPrompts()
// then
- assertEquals(expected = EmptyJsonObject, actual = listPromptsResult._meta)
+ assertNull(listPromptsResult.meta)
val prompts = listPromptsResult.prompts
@@ -45,7 +46,7 @@ class SseServerIntegrationTest {
val listResourcesResult = client.listResources()
// then
- assertEquals(expected = EmptyJsonObject, actual = listResourcesResult._meta)
+ assertNull(listResourcesResult.meta)
val resources = listResourcesResult.resources
assertEquals(expected = listOf("Web Search"), actual = resources.map { it.name })
@@ -55,11 +56,11 @@ class SseServerIntegrationTest {
fun `should get resource`(): Unit = runBlocking {
val testResourceUri = "https://search.com/"
val getResourcesResult = client.readResource(
- ReadResourceRequest(uri = testResourceUri),
+ ReadResourceRequest(ReadResourceRequestParams(uri = testResourceUri)),
)
// then
- assertEquals(expected = EmptyJsonObject, actual = getResourcesResult._meta)
+ assertEquals(expected = null, actual = getResourcesResult.meta)
val contents = getResourcesResult.contents
assertEquals(expected = 1, actual = contents.size)
assertTrue {
@@ -72,11 +73,14 @@ class SseServerIntegrationTest {
@Test
fun `should call tool`(): Unit = runBlocking {
// when
- val toolResult = client.callTool("kotlin-sdk-tool", EmptyJsonObject)
+ val toolResult = client.callTool(
+ name = "kotlin-sdk-tool",
+ arguments = emptyMap(),
+ )
// then
assertNotNull(toolResult)
- assertEquals(expected = EmptyJsonObject, actual = toolResult._meta)
+ assertNull(toolResult.meta)
val content = toolResult.content.single()
assertIs(content, "Tool result should be a text content")