Update samples to use new schema (#443)

This commit is contained in:
Konstantin Pavlov 2025-12-04 10:37:02 +02:00 • committed by GitHub
commit bb8de718d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 33 additions and 29 deletions

View file

@ -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()
}
}

View file

@ -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 <name>${request.arguments?.get("Project Name")}</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!")),

View file

@ -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<TextContent>(content, "Tool result should be a text content")