Skip to content

Commit eacc8be

Browse files
authored
Merge branch 'main' into fix/test-calculator-format-and-tags
2 parents 422ba06 + 3d82883 commit eacc8be

File tree

35 files changed

+1553
-624
lines changed

35 files changed

+1553
-624
lines changed

.github/workflows/apidocs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
cache: gradle
3434

3535
- name: Setup Gradle
36-
uses: gradle/actions/setup-gradle@v4
36+
uses: gradle/actions/setup-gradle@v5
3737

3838
- name: Generate Dokka Site
3939
run: |-

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
distribution: 'temurin'
2929

3030
- name: Setup Gradle
31-
uses: gradle/actions/setup-gradle@v4
31+
uses: gradle/actions/setup-gradle@v5
3232
with:
3333
add-job-summary: 'always'
3434
cache-read-only: true

.github/workflows/gradle-publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
distribution: 'temurin'
3232

3333
- name: Setup Gradle
34-
uses: gradle/actions/setup-gradle@v4
34+
uses: gradle/actions/setup-gradle@v5
3535

3636
- name: Clean Build with Gradle
3737
run: ./gradlew clean build

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ val server = Server(
112112
)
113113
)
114114
)
115-
)
115+
){
116+
"This server provides example resources and demonstrates MCP capabilities."
117+
}
116118

117119
// Add a resource
118120
server.addResource(
@@ -156,8 +158,10 @@ fun Application.module() {
156158
prompts = ServerCapabilities.Prompts(listChanged = null),
157159
resources = ServerCapabilities.Resources(subscribe = null, listChanged = null)
158160
)
159-
)
160-
)
161+
),
162+
) {
163+
"This SSE server provides prompts and resources via Server-Sent Events."
164+
}
161165
}
162166
}
163167
```
@@ -184,8 +188,10 @@ fun Application.module() {
184188
prompts = ServerCapabilities.Prompts(listChanged = null),
185189
resources = ServerCapabilities.Resources(subscribe = null, listChanged = null)
186190
)
187-
)
188-
)
191+
),
192+
) {
193+
"Connect via SSE to interact with this MCP server."
194+
}
189195
}
190196
}
191197
}

build.gradle.kts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,18 @@ dokka {
3333
}
3434
}
3535

36+
ktlint {
37+
filter {
38+
exclude("**/generated*/**")
39+
}
40+
}
41+
3642
kover {
3743
reports {
3844
filters {
3945
includes.classes("io.modelcontextprotocol.kotlin.sdk.*")
46+
excludes.classes("io.modelcontextprotocol.kotlin.sdk.models.*") // temporary
47+
excludes.classes("io.modelcontextprotocol.kotlin.sdk.models.infrastructure.*") // generated
4048
}
4149
total {
4250
log {

gradle/libs.versions.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ kotlin = "2.2.10"
44
dokka = "2.0.0"
55
atomicfu = "0.29.0"
66
ktlint = "13.1.0"
7-
kover = "0.9.1"
7+
kover = "0.9.2"
88
mavenPublish = "0.34.0"
99
binaryCompatibilityValidatorPlugin = "0.18.1"
1010

@@ -48,6 +48,7 @@ ktor-server-core = { group = "io.ktor", name = "ktor-server-core", version.ref =
4848

4949
# Testing
5050
awaitility = { group = "org.awaitility", name = "awaitility-kotlin", version.ref = "awaitility" }
51+
kotest-assertions-core = { group = "io.kotest", name = "kotest-assertions-core", version.ref = "kotest" }
5152
kotest-assertions-json = { group = "io.kotest", name = "kotest-assertions-json", version.ref = "kotest" }
5253
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "coroutines" }
5354
ktor-client-mock = { group = "io.ktor", name = "ktor-client-mock", version.ref = "ktor" }

kotlin-sdk-client/api/kotlin-sdk-client.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class io/modelcontextprotocol/kotlin/sdk/client/Client : io/modelcontextp
1717
public final fun getPrompt (Lio/modelcontextprotocol/kotlin/sdk/GetPromptRequest;Lio/modelcontextprotocol/kotlin/sdk/shared/RequestOptions;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
1818
public static synthetic fun getPrompt$default (Lio/modelcontextprotocol/kotlin/sdk/client/Client;Lio/modelcontextprotocol/kotlin/sdk/GetPromptRequest;Lio/modelcontextprotocol/kotlin/sdk/shared/RequestOptions;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
1919
public final fun getServerCapabilities ()Lio/modelcontextprotocol/kotlin/sdk/ServerCapabilities;
20+
public final fun getServerInstructions ()Ljava/lang/String;
2021
public final fun getServerVersion ()Lio/modelcontextprotocol/kotlin/sdk/Implementation;
2122
public final fun listPrompts (Lio/modelcontextprotocol/kotlin/sdk/ListPromptsRequest;Lio/modelcontextprotocol/kotlin/sdk/shared/RequestOptions;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
2223
public static synthetic fun listPrompts$default (Lio/modelcontextprotocol/kotlin/sdk/client/Client;Lio/modelcontextprotocol/kotlin/sdk/ListPromptsRequest;Lio/modelcontextprotocol/kotlin/sdk/shared/RequestOptions;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;

kotlin-sdk-client/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/client/Client.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ public open class Client(private val clientInfo: Implementation, options: Client
9191
public var serverCapabilities: ServerCapabilities? = null
9292
private set
9393

94+
/**
95+
* Optional human-readable instructions or description from the server.
96+
*
97+
* @return Instructions provided by the server, or `null` if none were given or initialization is not yet complete.
98+
*/
99+
public var serverInstructions: String? = null
100+
private set
101+
94102
/**
95103
* Retrieves the server's reported version information after initialization.
96104
*
@@ -154,12 +162,15 @@ public open class Client(private val clientInfo: Implementation, options: Client
154162

155163
serverCapabilities = result.capabilities
156164
serverVersion = result.serverInfo
165+
serverInstructions = result.instructions
157166

158167
notification(InitializedNotification())
159168
} catch (error: Throwable) {
169+
logger.error(error) { "Failed to initialize client: ${error.message}" }
160170
close()
171+
161172
if (error !is CancellationException) {
162-
throw IllegalStateException("Error connecting to transport: ${error.message}")
173+
throw IllegalStateException("Error connecting to transport: ${error.message}", error)
163174
}
164175

165176
throw error

kotlin-sdk-client/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/client/SSEClientTransport.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.modelcontextprotocol.kotlin.sdk.client
22

3+
import io.github.oshai.kotlinlogging.KotlinLogging
34
import io.ktor.client.HttpClient
45
import io.ktor.client.plugins.sse.ClientSSESession
56
import io.ktor.client.plugins.sse.sseSession
@@ -46,6 +47,8 @@ public class SseClientTransport(
4647
private val reconnectionTime: Duration? = null,
4748
private val requestBuilder: HttpRequestBuilder.() -> Unit = {},
4849
) : AbstractTransport() {
50+
private val logger = KotlinLogging.logger {}
51+
4952
private val initialized: AtomicBoolean = AtomicBoolean(false)
5053
private val endpoint = CompletableDeferred<String>()
5154

@@ -111,6 +114,8 @@ public class SseClientTransport(
111114
val text = response.bodyAsText()
112115
error("Error POSTing to endpoint (HTTP ${response.status}): $text")
113116
}
117+
118+
logger.debug { "Client successfully sent message via SSE $endpoint" }
114119
} catch (e: Throwable) {
115120
_onError(e)
116121
throw e
@@ -158,6 +163,7 @@ public class SseClientTransport(
158163
val path = if (eventData.startsWith("/")) eventData.substring(1) else eventData
159164
val endpointUrl = Url("$baseUrl/$path")
160165
endpoint.complete(endpointUrl.toString())
166+
logger.debug { "Client connected to endpoint: $endpointUrl" }
161167
} catch (e: Throwable) {
162168
_onError(e)
163169
endpoint.completeExceptionally(e)

kotlin-sdk-client/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/client/WebSocketClientTransport.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.modelcontextprotocol.kotlin.sdk.client
22

3+
import io.github.oshai.kotlinlogging.KotlinLogging
34
import io.ktor.client.HttpClient
45
import io.ktor.client.plugins.websocket.webSocketSession
56
import io.ktor.client.request.HttpRequestBuilder
@@ -10,6 +11,8 @@ import io.modelcontextprotocol.kotlin.sdk.shared.MCP_SUBPROTOCOL
1011
import io.modelcontextprotocol.kotlin.sdk.shared.WebSocketMcpTransport
1112
import kotlin.properties.Delegates
1213

14+
private val logger = KotlinLogging.logger {}
15+
1316
/**
1417
* Client transport for WebSocket: this will connect to a server over the WebSocket protocol.
1518
*/
@@ -21,6 +24,8 @@ public class WebSocketClientTransport(
2124
override var session: WebSocketSession by Delegates.notNull()
2225

2326
override suspend fun initializeSession() {
27+
logger.debug { "Websocket session initialization started..." }
28+
2429
session = urlString?.let {
2530
client.webSocketSession(it) {
2631
requestBuilder()
@@ -32,5 +37,7 @@ public class WebSocketClientTransport(
3237

3338
header(HttpHeaders.SecWebSocketProtocol, MCP_SUBPROTOCOL)
3439
}
40+
41+
logger.debug { "Websocket session initialization finished" }
3542
}
3643
}

0 commit comments

Comments
 (0)