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
3 changed files with 298 additions and 258 deletions

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