Fix kotlin-mcp-server example and update samples (#345)
- updated the sdk version in all examples - fixed `kotlin-mcp-server` example (#331) ## Motivation and Context Removed the WASM example, as it duplicates the JVM example and only adds unnecessary complexity ## How Has This Been Tested? Locally ## Breaking Changes No ## Types of changes - [x] 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) - [ ] Documentation update ## Checklist - [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 - [x] I have added or updated documentation as needed
This commit is contained in:
parent
cae9130e37
commit
458a49a5fb
10 changed files with 115 additions and 144 deletions
|
|
@ -1,8 +1,8 @@
|
||||||
[versions]
|
[versions]
|
||||||
anthropic = "2.9.0"
|
anthropic = "2.9.0"
|
||||||
kotlin = "2.2.20"
|
kotlin = "2.2.21"
|
||||||
ktor = "3.3.0"
|
ktor = "3.2.3"
|
||||||
mcp-kotlin = "0.7.3"
|
mcp-kotlin = "0.7.4"
|
||||||
shadow = "9.2.2"
|
shadow = "9.2.2"
|
||||||
slf4j = "2.0.17"
|
slf4j = "2.0.17"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
# MCP Kotlin Server Sample
|
# MCP Kotlin Server Sample
|
||||||
|
|
||||||
A sample implementation of an MCP (Model Communication Protocol) server in Kotlin that demonstrates different server
|
A sample implementation of an MCP (Model Context Protocol) server in Kotlin that demonstrates different server
|
||||||
configurations and transport methods for both JVM and WASM targets.
|
configurations and transport methods.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Multiple server operation modes:
|
- Multiple server operation modes:
|
||||||
- Standard I/O server (JVM only)
|
- Standard I/O server
|
||||||
- SSE (Server-Sent Events) server with plain configuration (JVM, WASM)
|
- SSE (Server-Sent Events) server with plain configuration
|
||||||
- SSE server using Ktor plugin (JVM, WASM)
|
- SSE server using Ktor plugin
|
||||||
- Multiplatform support
|
|
||||||
- Built-in capabilities for:
|
- Built-in capabilities for:
|
||||||
- Prompts management
|
- Prompts management
|
||||||
- Resources handling
|
- Resources handling
|
||||||
|
|
@ -19,31 +18,41 @@ configurations and transport methods for both JVM and WASM targets.
|
||||||
|
|
||||||
### Running the Server
|
### Running the Server
|
||||||
|
|
||||||
You can run the server on the JVM or using Kotlin/WASM on Node.js.
|
The server defaults to SSE mode with Ktor plugin on port 3001. You can customize the behavior using command-line arguments.
|
||||||
|
|
||||||
|
#### Default (SSE with Ktor plugin):
|
||||||
#### JVM:
|
|
||||||
|
|
||||||
To run the server on the JVM (defaults to SSE mode with Ktor plugin on port 3001):
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./gradlew runJvm
|
./gradlew run
|
||||||
```
|
```
|
||||||
|
|
||||||
#### WASM:
|
#### Standard I/O mode:
|
||||||
|
|
||||||
To run the server using Kotlin/WASM on Node.js (defaults to SSE mode with Ktor plugin on port 3001):
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./gradlew wasmJsNodeDevelopmentRun
|
./gradlew run --args="--stdio"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### SSE with plain configuration:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew run --args="--sse-server 3001"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### SSE with Ktor plugin (custom port):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew run --args="--sse-server-ktor 3002"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Connecting to the Server
|
### Connecting to the Server
|
||||||
|
|
||||||
For servers on JVM or WASM:
|
For SSE servers:
|
||||||
1. Start the server
|
1. Start the server
|
||||||
2. Use the [MCP inspector](https://modelcontextprotocol.io/docs/tools/inspector) to connect to `http://localhost:<port>/sse`
|
2. Use the [MCP inspector](https://modelcontextprotocol.io/docs/tools/inspector) to connect to `http://localhost:<port>/sse`
|
||||||
|
|
||||||
|
For STDIO servers:
|
||||||
|
- Connect using an MCP client that supports STDIO transport
|
||||||
|
|
||||||
## Server Capabilities
|
## Server Capabilities
|
||||||
|
|
||||||
- **Prompts**: Supports prompt management with list change notifications
|
- **Prompts**: Supports prompt management with list change notifications
|
||||||
|
|
@ -53,8 +62,14 @@ For servers on JVM or WASM:
|
||||||
## Implementation Details
|
## Implementation Details
|
||||||
|
|
||||||
The server is implemented using:
|
The server is implemented using:
|
||||||
- Ktor for HTTP server functionality
|
- Ktor for HTTP server functionality (SSE modes)
|
||||||
- Kotlin coroutines for asynchronous operations
|
- Kotlin coroutines for asynchronous operations
|
||||||
- SSE for real-time communication
|
- SSE for real-time communication in web contexts
|
||||||
- Standard I/O for command-line interface
|
- Standard I/O for command-line interface and process-based communication
|
||||||
- Common Kotlin code shared between JVM and WASM targets
|
|
||||||
|
## Example Capabilities
|
||||||
|
|
||||||
|
The sample server demonstrates:
|
||||||
|
- **Prompt**: "Kotlin Developer" - helps develop small Kotlin applications with a configurable project name
|
||||||
|
- **Tool**: "kotlin-sdk-tool" - a simple test tool that returns a greeting
|
||||||
|
- **Resource**: "Web Search" - a placeholder resource demonstrating resource handling
|
||||||
|
|
|
||||||
|
|
@ -1,50 +1,26 @@
|
||||||
@file:OptIn(ExperimentalWasmDsl::class, ExperimentalKotlinGradlePluginApi::class)
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
|
|
||||||
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.kotlin.multiplatform)
|
alias(libs.plugins.kotlin.jvm)
|
||||||
alias(libs.plugins.kotlin.serialization)
|
alias(libs.plugins.kotlin.serialization)
|
||||||
|
application
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "org.example"
|
group = "org.example"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
val jvmMainClass = "Main_jvmKt"
|
application {
|
||||||
|
mainClass.set("io.modelcontextprotocol.sample.server.MainKt")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(libs.mcp.kotlin.server)
|
||||||
|
implementation(libs.ktor.server.cio)
|
||||||
|
implementation(libs.slf4j.simple)
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
jvmToolchain(17)
|
jvmToolchain(17)
|
||||||
jvm {
|
|
||||||
binaries {
|
|
||||||
executable {
|
|
||||||
mainClass.set(jvmMainClass)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val jvmJar by tasks.getting(org.gradle.jvm.tasks.Jar::class) {
|
|
||||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
|
||||||
doFirst {
|
|
||||||
manifest {
|
|
||||||
attributes["Main-Class"] = jvmMainClass
|
|
||||||
}
|
|
||||||
|
|
||||||
from(configurations["jvmRuntimeClasspath"].map { if (it.isDirectory) it else zipTree(it) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wasmJs {
|
|
||||||
nodejs()
|
|
||||||
binaries.executable()
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
commonMain.dependencies {
|
|
||||||
implementation(libs.mcp.kotlin.server)
|
|
||||||
implementation(libs.ktor.server.cio)
|
|
||||||
}
|
|
||||||
jvmMain.dependencies {
|
|
||||||
implementation(libs.slf4j.simple)
|
|
||||||
}
|
|
||||||
wasmJsMain.dependencies {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
[versions]
|
[versions]
|
||||||
kotlin = "2.2.20"
|
kotlin = "2.2.21"
|
||||||
ktor = "3.3.1"
|
ktor = "3.2.3"
|
||||||
mcp-kotlin = "0.7.3"
|
mcp-kotlin = "0.7.4"
|
||||||
slf4j = "2.0.17"
|
slf4j = "2.0.17"
|
||||||
serialization = "1.9.0"
|
serialization = "1.9.0"
|
||||||
|
|
||||||
|
|
@ -11,5 +11,5 @@ mcp-kotlin-server = { group = "io.modelcontextprotocol", name = "kotlin-sdk-serv
|
||||||
slf4j-simple = { group = "org.slf4j", name = "slf4j-simple", version.ref = "slf4j" }
|
slf4j-simple = { group = "org.slf4j", name = "slf4j-simple", version.ref = "slf4j" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
|
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
||||||
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
|
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
|
||||||
|
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
import io.modelcontextprotocol.kotlin.sdk.server.StdioServerTransport
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import kotlinx.io.asSink
|
|
||||||
import kotlinx.io.asSource
|
|
||||||
import kotlinx.io.buffered
|
|
||||||
import shared.configureServer
|
|
||||||
import shared.runSseMcpServerUsingKtorPlugin
|
|
||||||
import shared.runSseMcpServerWithPlainConfiguration
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start sse-server mcp on port 3001.
|
|
||||||
*
|
|
||||||
* @param args
|
|
||||||
* - "--stdio": Runs an MCP server using standard input/output.
|
|
||||||
* - "--sse-server-ktor <port>": Runs an SSE MCP server using Ktor plugin (default if no argument is provided).
|
|
||||||
* - "--sse-server <port>": Runs an SSE MCP server with a plain configuration.
|
|
||||||
*/
|
|
||||||
fun main(args: Array<String>): Unit = runBlocking {
|
|
||||||
val command = args.firstOrNull() ?: "--sse-server-ktor"
|
|
||||||
val port = args.getOrNull(1)?.toIntOrNull() ?: 3001
|
|
||||||
when (command) {
|
|
||||||
"--stdio" -> runMcpServerUsingStdio()
|
|
||||||
"--sse-server-ktor" -> runSseMcpServerUsingKtorPlugin(port)
|
|
||||||
"--sse-server" -> runSseMcpServerWithPlainConfiguration(port)
|
|
||||||
else -> {
|
|
||||||
System.err.println("Unknown command: $command")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun runMcpServerUsingStdio() {
|
|
||||||
// Note: The server will handle listing prompts, tools, and resources automatically.
|
|
||||||
// The handleListResourceTemplates will return empty as defined in the Server code.
|
|
||||||
val server = configureServer()
|
|
||||||
val transport = StdioServerTransport(
|
|
||||||
inputStream = System.`in`.asSource().buffered(),
|
|
||||||
outputStream = System.out.asSink().buffered()
|
|
||||||
)
|
|
||||||
|
|
||||||
runBlocking {
|
|
||||||
server.connect(transport)
|
|
||||||
val done = Job()
|
|
||||||
server.onClose {
|
|
||||||
done.complete()
|
|
||||||
}
|
|
||||||
done.join()
|
|
||||||
println("Server closed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package io.modelcontextprotocol.sample.server
|
||||||
|
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start sse-server mcp on port 3001.
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
* - "--stdio": Runs an MCP server using standard input/output.
|
||||||
|
* - "--sse-server-ktor <port>": Runs an SSE MCP server using Ktor plugin (default if no argument is provided).
|
||||||
|
* - "--sse-server <port>": Runs an SSE MCP server with a plain configuration.
|
||||||
|
*/
|
||||||
|
fun main(args: Array<String>): Unit = runBlocking {
|
||||||
|
val command = args.firstOrNull() ?: "--sse-server-ktor"
|
||||||
|
val port = args.getOrNull(1)?.toIntOrNull() ?: 3001
|
||||||
|
when (command) {
|
||||||
|
"--stdio" -> runMcpServerUsingStdio()
|
||||||
|
"--sse-server-ktor" -> runSseMcpServerUsingKtorPlugin(port)
|
||||||
|
"--sse-server" -> runSseMcpServerWithPlainConfiguration(port)
|
||||||
|
else -> {
|
||||||
|
error("Unknown command: $command")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,182 @@
|
||||||
|
package io.modelcontextprotocol.sample.server
|
||||||
|
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.server.application.install
|
||||||
|
import io.ktor.server.cio.CIO
|
||||||
|
import io.ktor.server.engine.embeddedServer
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.post
|
||||||
|
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 kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import kotlinx.io.asSink
|
||||||
|
import kotlinx.io.asSource
|
||||||
|
import kotlinx.io.buffered
|
||||||
|
|
||||||
|
fun configureServer(): Server {
|
||||||
|
val server = Server(
|
||||||
|
Implementation(
|
||||||
|
name = "mcp-kotlin test server",
|
||||||
|
version = "0.1.0",
|
||||||
|
),
|
||||||
|
ServerOptions(
|
||||||
|
capabilities = ServerCapabilities(
|
||||||
|
prompts = ServerCapabilities.Prompts(listChanged = true),
|
||||||
|
resources = ServerCapabilities.Resources(subscribe = true, listChanged = true),
|
||||||
|
tools = ServerCapabilities.Tools(listChanged = true),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
server.addPrompt(
|
||||||
|
name = "Kotlin Developer",
|
||||||
|
description = "Develop small kotlin applications",
|
||||||
|
arguments = listOf(
|
||||||
|
PromptArgument(
|
||||||
|
name = "Project Name",
|
||||||
|
description = "Project name for the new project",
|
||||||
|
required = true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
) { request ->
|
||||||
|
GetPromptResult(
|
||||||
|
"Description for ${request.name}",
|
||||||
|
messages = listOf(
|
||||||
|
PromptMessage(
|
||||||
|
role = Role.user,
|
||||||
|
content = TextContent(
|
||||||
|
"Develop a kotlin project named <name>${request.arguments?.get("Project Name")}</name>",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a tool
|
||||||
|
server.addTool(
|
||||||
|
name = "kotlin-sdk-tool",
|
||||||
|
description = "A test tool",
|
||||||
|
inputSchema = Tool.Input(),
|
||||||
|
) { _ ->
|
||||||
|
CallToolResult(
|
||||||
|
content = listOf(TextContent("Hello, world!")),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a resource
|
||||||
|
server.addResource(
|
||||||
|
uri = "https://search.com/",
|
||||||
|
name = "Web Search",
|
||||||
|
description = "Web search engine",
|
||||||
|
mimeType = "text/html",
|
||||||
|
) { request ->
|
||||||
|
ReadResourceResult(
|
||||||
|
contents = listOf(
|
||||||
|
TextResourceContents("Placeholder content for ${request.uri}", request.uri, "text/html"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return server
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runSseMcpServerWithPlainConfiguration(port: Int) {
|
||||||
|
val serverSessions = ConcurrentMap<String, ServerSession>()
|
||||||
|
println("Starting SSE server on port $port")
|
||||||
|
println("Use inspector to connect to http://localhost:$port/sse")
|
||||||
|
|
||||||
|
val server = configureServer()
|
||||||
|
|
||||||
|
embeddedServer(CIO, host = "127.0.0.1", port = port) {
|
||||||
|
install(SSE)
|
||||||
|
routing {
|
||||||
|
sse("/sse") {
|
||||||
|
val transport = SseServerTransport("/message", this)
|
||||||
|
val serverSession = server.connect(transport)
|
||||||
|
serverSessions[transport.sessionId] = serverSession
|
||||||
|
|
||||||
|
serverSession.onClose {
|
||||||
|
println("Server session closed for: ${transport.sessionId}")
|
||||||
|
serverSessions.remove(transport.sessionId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
post("/message") {
|
||||||
|
val sessionId: String? = call.request.queryParameters["sessionId"]
|
||||||
|
if (sessionId == null) {
|
||||||
|
call.respond(HttpStatusCode.BadRequest, "Missing sessionId parameter")
|
||||||
|
return@post
|
||||||
|
}
|
||||||
|
|
||||||
|
val transport = serverSessions[sessionId]?.transport as? SseServerTransport
|
||||||
|
if (transport == null) {
|
||||||
|
call.respond(HttpStatusCode.NotFound, "Session not found")
|
||||||
|
return@post
|
||||||
|
}
|
||||||
|
|
||||||
|
transport.handlePostMessage(call)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.start(wait = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts an SSE (Server-Sent Events) MCP server using the Ktor plugin.
|
||||||
|
*
|
||||||
|
* This is the recommended approach for SSE servers as it simplifies configuration.
|
||||||
|
* The URL can be accessed in the MCP inspector at http://localhost:[port]/sse
|
||||||
|
*
|
||||||
|
* @param port The port number on which the SSE MCP server will listen for client connections.
|
||||||
|
*/
|
||||||
|
fun runSseMcpServerUsingKtorPlugin(port: Int) {
|
||||||
|
println("Starting SSE server on port $port")
|
||||||
|
println("Use inspector to connect to http://localhost:$port/sse")
|
||||||
|
|
||||||
|
embeddedServer(CIO, host = "127.0.0.1", port = port) {
|
||||||
|
mcp {
|
||||||
|
return@mcp configureServer()
|
||||||
|
}
|
||||||
|
}.start(wait = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts an MCP server using Standard I/O transport.
|
||||||
|
*
|
||||||
|
* This mode is useful for process-based communication where the server
|
||||||
|
* communicates via stdin/stdout with a parent process or client.
|
||||||
|
*/
|
||||||
|
fun runMcpServerUsingStdio() {
|
||||||
|
val server = configureServer()
|
||||||
|
val transport = StdioServerTransport(
|
||||||
|
inputStream = System.`in`.asSource().buffered(),
|
||||||
|
outputStream = System.out.asSink().buffered()
|
||||||
|
)
|
||||||
|
|
||||||
|
runBlocking {
|
||||||
|
server.connect(transport)
|
||||||
|
val done = Job()
|
||||||
|
server.onClose {
|
||||||
|
done.complete()
|
||||||
|
}
|
||||||
|
done.join()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Level of logging for the ROOT logger: ERROR, WARN, INFO, DEBUG, TRACE (default is INFO)
|
||||||
|
org.slf4j.simpleLogger.defaultLogLevel=INFO
|
||||||
|
org.slf4j.simpleLogger.showThreadName=true
|
||||||
|
org.slf4j.simpleLogger.showDateTime=false
|
||||||
|
|
||||||
|
# Log level for specific packages or classes
|
||||||
|
org.slf4j.simpleLogger.log.io.modelcontextprotocol=TRACE
|
||||||
|
org.slf4j.simpleLogger.log.io.ktor=TRACE
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
[versions]
|
[versions]
|
||||||
collections-immutable = "0.4.0"
|
collections-immutable = "0.4.0"
|
||||||
coroutines = "1.10.2"
|
coroutines = "1.10.2"
|
||||||
kotlin = "2.2.20"
|
kotlin = "2.2.21"
|
||||||
ktor = "3.3.0"
|
ktor = "3.2.3"
|
||||||
logging = "7.0.13"
|
logging = "7.0.13"
|
||||||
mcp-kotlin = "0.7.3"
|
mcp-kotlin = "0.7.4"
|
||||||
shadow = "9.2.2"
|
shadow = "9.2.2"
|
||||||
slf4j = "2.0.17"
|
slf4j = "2.0.17"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import io.ktor.http.ContentType
|
||||||
import io.ktor.http.contentType
|
import io.ktor.http.contentType
|
||||||
import io.ktor.http.headers
|
import io.ktor.http.headers
|
||||||
import io.ktor.serialization.kotlinx.json.json
|
import io.ktor.serialization.kotlinx.json.json
|
||||||
import io.ktor.utils.io.core.Input
|
|
||||||
import io.ktor.utils.io.streams.asInput
|
import io.ktor.utils.io.streams.asInput
|
||||||
import io.modelcontextprotocol.kotlin.sdk.CallToolResult
|
import io.modelcontextprotocol.kotlin.sdk.CallToolResult
|
||||||
import io.modelcontextprotocol.kotlin.sdk.Implementation
|
import io.modelcontextprotocol.kotlin.sdk.Implementation
|
||||||
|
|
@ -19,7 +18,6 @@ import io.modelcontextprotocol.kotlin.sdk.server.ServerOptions
|
||||||
import io.modelcontextprotocol.kotlin.sdk.server.StdioServerTransport
|
import io.modelcontextprotocol.kotlin.sdk.server.StdioServerTransport
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.io.Sink
|
|
||||||
import kotlinx.io.asSink
|
import kotlinx.io.asSink
|
||||||
import kotlinx.io.buffered
|
import kotlinx.io.buffered
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue