Skip to content

Commit bc3c750

Browse files
committed
refactor: replace flat parameter definitions with StreamableHttpServerTransport.Configuration in Application Ktor extensions
Simplified `Application.mcp*StreamableHttp` functions by replacing individual parameters with the typed `StreamableHttpServerTransport.Configuration` for improved extensibility and performance.
1 parent 0df06f5 commit bc3c750

2 files changed

Lines changed: 35 additions & 45 deletions

File tree

kotlin-sdk-server/api/kotlin-sdk-server.api

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ public final class io/modelcontextprotocol/kotlin/sdk/server/KtorServerKt {
3838
public static final fun mcp (Lio/ktor/server/application/Application;Lkotlin/jvm/functions/Function1;)V
3939
public static final fun mcp (Lio/ktor/server/routing/Route;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
4040
public static final fun mcp (Lio/ktor/server/routing/Route;Lkotlin/jvm/functions/Function1;)V
41-
public static final fun mcpStatelessStreamableHttp (Lio/ktor/server/application/Application;Ljava/lang/String;ZLjava/util/List;Ljava/util/List;Lio/modelcontextprotocol/kotlin/sdk/server/EventStore;Lkotlin/jvm/functions/Function1;)V
42-
public static synthetic fun mcpStatelessStreamableHttp$default (Lio/ktor/server/application/Application;Ljava/lang/String;ZLjava/util/List;Ljava/util/List;Lio/modelcontextprotocol/kotlin/sdk/server/EventStore;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
43-
public static final fun mcpStreamableHttp (Lio/ktor/server/application/Application;Ljava/lang/String;ZLjava/util/List;Ljava/util/List;Lio/modelcontextprotocol/kotlin/sdk/server/EventStore;Lkotlin/jvm/functions/Function1;)V
44-
public static synthetic fun mcpStreamableHttp$default (Lio/ktor/server/application/Application;Ljava/lang/String;ZLjava/util/List;Ljava/util/List;Lio/modelcontextprotocol/kotlin/sdk/server/EventStore;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
41+
public static final fun mcpStatelessStreamableHttp (Lio/ktor/server/application/Application;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/server/StreamableHttpServerTransport$Configuration;Lkotlin/jvm/functions/Function1;)V
42+
public static synthetic fun mcpStatelessStreamableHttp$default (Lio/ktor/server/application/Application;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/server/StreamableHttpServerTransport$Configuration;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
43+
public static final fun mcpStreamableHttp (Lio/ktor/server/application/Application;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/server/StreamableHttpServerTransport$Configuration;Lkotlin/jvm/functions/Function1;)V
44+
public static synthetic fun mcpStreamableHttp$default (Lio/ktor/server/application/Application;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/server/StreamableHttpServerTransport$Configuration;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
4545
}
4646

4747
public final class io/modelcontextprotocol/kotlin/sdk/server/RegisteredPrompt : io/modelcontextprotocol/kotlin/sdk/server/Feature {

kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/KtorServer.kt

Lines changed: 31 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ public fun Route.mcp(block: ServerSSESession.() -> Server) {
9292
}
9393
}
9494

95+
/**
96+
* Configures the application to use Server-Sent Events (SSE) and sets up routing for the provided server logic.
97+
*
98+
* @param block A lambda function that defines the server logic within the context of a [ServerSSESession].
99+
*/
95100
@KtorDsl
96101
public fun Application.mcp(block: ServerSSESession.() -> Server) {
97102
install(SSE)
@@ -101,14 +106,20 @@ public fun Application.mcp(block: ServerSSESession.() -> Server) {
101106
}
102107
}
103108

109+
/**
110+
* Sets up HTTP endpoints for an application to support MCP streamable interactions
111+
* using the Server-Sent Events (SSE) protocol and other HTTP methods.
112+
*
113+
* @param path The base URL path for the MCP streamable HTTP routes. Defaults to "/mcp".
114+
* @param configuration An instance of `StreamableHttpServerTransport.Configuration` used to configure
115+
* the behavior of the transport layer.
116+
* @param block A lambda with a `RoutingContext` receiver, allowing the user to define server logic
117+
* for handling streamable transport.
118+
*/
104119
@KtorDsl
105-
@Suppress("LongParameterList")
106120
public fun Application.mcpStreamableHttp(
107121
path: String = "/mcp",
108-
enableDnsRebindingProtection: Boolean = false,
109-
allowedHosts: List<String>? = null,
110-
allowedOrigins: List<String>? = null,
111-
eventStore: EventStore? = null,
122+
configuration: StreamableHttpServerTransport.Configuration = StreamableHttpServerTransport.Configuration(),
112123
block: RoutingContext.() -> Server,
113124
) {
114125
install(SSE)
@@ -125,10 +136,7 @@ public fun Application.mcpStreamableHttp(
125136
post {
126137
val transport = streamableTransport(
127138
transportManager = transportManager,
128-
enableDnsRebindingProtection = enableDnsRebindingProtection,
129-
allowedHosts = allowedHosts,
130-
allowedOrigins = allowedOrigins,
131-
eventStore = eventStore,
139+
configuration = configuration,
132140
block = block,
133141
)
134142
?: return@post
@@ -144,14 +152,19 @@ public fun Application.mcpStreamableHttp(
144152
}
145153
}
146154

155+
/**
156+
* Sets up a stateless and streamable HTTP endpoint within the application using the specified path and configuration.
157+
* This method installs the SSE feature and defines specific routing behavior for HTTP methods.
158+
*
159+
* @param path The URL path where the endpoint will be accessible. Defaults to "/mcp".
160+
* @param configuration The configuration object used to customize the behavior of the streamable HTTP server transport.
161+
* @param block A lambda function that provides the routing context to define the server behavior.
162+
*/
147163
@KtorDsl
148164
@Suppress("LongParameterList")
149165
public fun Application.mcpStatelessStreamableHttp(
150166
path: String = "/mcp",
151-
enableDnsRebindingProtection: Boolean = false,
152-
allowedHosts: List<String>? = null,
153-
allowedOrigins: List<String>? = null,
154-
eventStore: EventStore? = null,
167+
configuration: StreamableHttpServerTransport.Configuration = StreamableHttpServerTransport.Configuration(),
155168
block: RoutingContext.() -> Server,
156169
) {
157170
install(SSE)
@@ -160,10 +173,7 @@ public fun Application.mcpStatelessStreamableHttp(
160173
route(path) {
161174
post {
162175
mcpStatelessStreamableHttpEndpoint(
163-
enableDnsRebindingProtection = enableDnsRebindingProtection,
164-
allowedHosts = allowedHosts,
165-
allowedOrigins = allowedOrigins,
166-
eventStore = eventStore,
176+
configuration = configuration,
167177
block = block,
168178
)
169179
}
@@ -218,20 +228,11 @@ private fun ServerSSESession.mcpSseTransport(
218228
}
219229

220230
private suspend fun RoutingContext.mcpStatelessStreamableHttpEndpoint(
221-
enableDnsRebindingProtection: Boolean = false,
222-
allowedHosts: List<String>? = null,
223-
allowedOrigins: List<String>? = null,
224-
eventStore: EventStore? = null,
231+
configuration: StreamableHttpServerTransport.Configuration,
225232
block: RoutingContext.() -> Server,
226233
) {
227234
val transport = StreamableHttpServerTransport(
228-
StreamableHttpServerTransport.Configuration(
229-
enableDnsRebindingProtection = enableDnsRebindingProtection,
230-
allowedHosts = allowedHosts,
231-
allowedOrigins = allowedOrigins,
232-
eventStore = eventStore,
233-
enableJsonResponse = true,
234-
),
235+
configuration,
235236
).also { it.setSessionIdGenerator(null) }
236237

237238
logger.info { "New stateless StreamableHttp connection established without sessionId" }
@@ -294,10 +295,7 @@ private suspend fun existingStreamableTransport(
294295

295296
private suspend fun RoutingContext.streamableTransport(
296297
transportManager: TransportManager,
297-
enableDnsRebindingProtection: Boolean,
298-
allowedHosts: List<String>?,
299-
allowedOrigins: List<String>?,
300-
eventStore: EventStore?,
298+
configuration: StreamableHttpServerTransport.Configuration,
301299
block: RoutingContext.() -> Server,
302300
): StreamableHttpServerTransport? {
303301
val sessionId = call.request.sessionId()
@@ -306,15 +304,7 @@ private suspend fun RoutingContext.streamableTransport(
306304
return transport ?: existingStreamableTransport(call, transportManager)
307305
}
308306

309-
val transport = StreamableHttpServerTransport(
310-
StreamableHttpServerTransport.Configuration(
311-
enableDnsRebindingProtection = enableDnsRebindingProtection,
312-
allowedHosts = allowedHosts,
313-
allowedOrigins = allowedOrigins,
314-
eventStore = eventStore,
315-
enableJsonResponse = true,
316-
),
317-
)
307+
val transport = StreamableHttpServerTransport(configuration)
318308

319309
transport.setOnSessionInitialized { initializedSessionId ->
320310
transportManager.addTransport(initializedSessionId, transport)

0 commit comments

Comments
 (0)