Refactor mcp server, rename connect to (#364)

- Rename `connect` to `createSession` in `Server.kt `to make naming more
clear
- Add block to configure build to `Server.kt`
- Move sse test to jvm to be able to run, small test refactoring
- Introduce base integration test for sse server / client
This commit is contained in:
Maria Tigina 2025-11-03 15:32:25 +01:00 • committed by GitHub
commit f27fe9a41d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 298 additions and 258 deletions

View file

@ -45,9 +45,10 @@ public final class io/modelcontextprotocol/kotlin/sdk/server/RegisteredTool {
}
public class io/modelcontextprotocol/kotlin/sdk/server/Server {
public fun <init> (Lio/modelcontextprotocol/kotlin/sdk/Implementation;Lio/modelcontextprotocol/kotlin/sdk/server/ServerOptions;Ljava/lang/String;)V
public fun <init> (Lio/modelcontextprotocol/kotlin/sdk/Implementation;Lio/modelcontextprotocol/kotlin/sdk/server/ServerOptions;Lkotlin/jvm/functions/Function0;)V
public synthetic fun <init> (Lio/modelcontextprotocol/kotlin/sdk/Implementation;Lio/modelcontextprotocol/kotlin/sdk/server/ServerOptions;Lkotlin/jvm/functions/Function0;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Lio/modelcontextprotocol/kotlin/sdk/Implementation;Lio/modelcontextprotocol/kotlin/sdk/server/ServerOptions;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public synthetic fun <init> (Lio/modelcontextprotocol/kotlin/sdk/Implementation;Lio/modelcontextprotocol/kotlin/sdk/server/ServerOptions;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Lio/modelcontextprotocol/kotlin/sdk/Implementation;Lio/modelcontextprotocol/kotlin/sdk/server/ServerOptions;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;)V
public synthetic fun <init> (Lio/modelcontextprotocol/kotlin/sdk/Implementation;Lio/modelcontextprotocol/kotlin/sdk/server/ServerOptions;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun addPrompt (Lio/modelcontextprotocol/kotlin/sdk/Prompt;Lkotlin/jvm/functions/Function2;)V
public final fun addPrompt (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lkotlin/jvm/functions/Function2;)V
public static synthetic fun addPrompt$default (Lio/modelcontextprotocol/kotlin/sdk/server/Server;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V
@ -61,6 +62,7 @@ public class io/modelcontextprotocol/kotlin/sdk/server/Server {
public final fun addTools (Ljava/util/List;)V
public final fun close (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun connect (Lio/modelcontextprotocol/kotlin/sdk/shared/Transport;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun createSession (Lio/modelcontextprotocol/kotlin/sdk/shared/Transport;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
protected final fun getInstructionsProvider ()Lkotlin/jvm/functions/Function0;
protected final fun getOptions ()Lio/modelcontextprotocol/kotlin/sdk/server/ServerOptions;
public final fun getPrompts ()Ljava/util/Map;

View file

@ -88,7 +88,7 @@ internal suspend fun ServerSSESession.mcpSseEndpoint(
sseTransportManager.removeTransport(transport.sessionId)
}
server.connect(transport)
server.createSession(transport)
logger.debug { "Server connected to transport for sessionId: ${transport.sessionId}" }
}

View file

@ -57,12 +57,14 @@ public class ServerOptions(public val capabilities: ServerCapabilities, enforceS
* @param options Configuration options for the server.
* @param instructionsProvider Optional provider for instructions from the server to the client about how to use
* this server. The provider is called each time a new session is started to support dynamic instructions.
* @param block A block to configure the mcp server.
*/
public open class Server(
protected val serverInfo: Implementation,
protected val options: ServerOptions,
protected val instructionsProvider: (() -> String)? = null,
block: Server.() -> Unit = {},
) {
/**
* Alternative constructor that provides the instructions directly as a string.
@ -70,12 +72,14 @@ public open class Server(
* @param serverInfo Information about this server implementation (name, version).
* @param options Configuration options for the server.
* @param instructions Instructions from the server to the client about how to use this server.
* @param block A block to configure the mcp server.
*/
public constructor(
serverInfo: Implementation,
options: ServerOptions,
instructions: String,
) : this(serverInfo, options, { instructions })
block: Server.() -> Unit = {},
) : this(serverInfo, options, { instructions }, block)
private val sessions = atomic(persistentListOf<ServerSession>())
@ -98,6 +102,10 @@ public open class Server(
public val resources: Map<String, RegisteredResource>
get() = _resources.value
init {
block(this)
}
public suspend fun close() {
logger.debug { "Closing MCP server" }
sessions.value.forEach { it.close() }
@ -111,7 +119,21 @@ public open class Server(
* @param transport The transport layer to connect the session with.
* @return The initialized and connected server session.
*/
public suspend fun connect(transport: Transport): ServerSession {
@Deprecated(
"Use createSession(transport) instead.",
ReplaceWith("createSession(transport)"),
DeprecationLevel.WARNING,
)
public suspend fun connect(transport: Transport): ServerSession = createSession(transport)
/**
* Starts a new server session with the given transport and initializes
* internal request handlers based on the server's capabilities.
*
* @param transport The transport layer to connect the session with.
* @return The initialized and connected server session.
*/
public suspend fun createSession(transport: Transport): ServerSession {
val session = ServerSession(serverInfo, options, instructionsProvider?.invoke())
// Internal handlers for tools

View file

@ -69,7 +69,7 @@ internal suspend fun WebSocketServerSession.mcpWebSocketEndpoint(block: () -> Se
val server = block()
var session: ServerSession? = null
try {
session = server.connect(transport)
session = server.createSession(transport)
awaitCancellation()
} catch (e: CancellationException) {
session?.close()
@ -103,7 +103,7 @@ public fun Route.mcpWebSocket(options: ServerOptions? = null, handler: suspend S
)
public fun Route.mcpWebSocket(block: () -> Server) {
webSocket {
block().connect(createMcpTransport(this))
block().createSession(createMcpTransport(this))
}
}
@ -190,7 +190,7 @@ private suspend fun Route.createMcpServer(
),
)
server.connect(transport)
server.createSession(transport)
handler(server)
server.close()
}