kotlin-sdk/kotlin-sdk-testing/Module.md
Konstantin Pavlov 212cbfa325
feat: Add kotlin-sdk-testing module with channel-based transport implementation (#505)
# feat: Add kotlin-sdk-testing module with channel-based transport
implementation

- Introduced `kotlin-sdk-testing` module for testing utilities in the
MCP Kotlin SDK.
- Implemented `ChannelTransport`, providing JSON-RPC transport via
Kotlin coroutines channels.

<!-- Provide a brief summary of your changes -->

## Motivation and Context
This ChannelTransport can be used for testing Server implementation
without using real transports.

## How Has This Been Tested?
Unit test

## Breaking Changes
No

## Types of changes

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [x] Documentation update

## Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [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
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
2026-02-16 14:10:56 +02:00

67 lines
2.5 KiB
Markdown

# Module kotlin-sdk-testing
`kotlin-sdk-testing` provides testing utilities for MCP client-server interactions. It eliminates the need for external
processes or network connections by offering coroutine-safe in-memory transport implementations that connect clients and servers directly.
## Typical usage
1. Create linked transport pair with `ChannelTransport.createLinkedPair()`.
2. Connect client and server concurrently using the paired transports.
3. Configure server request handlers.
4. Execute client operations and verify results.
### Complete test example
```kotlin
@OptIn(ExperimentalMcpApi::class)
@Test
fun testClientServerCommunication(): Unit = runBlocking {
val server = Server(
Implementation(name = "test server", version = "1.0"),
ServerOptions(capabilities = ServerCapabilities(resources = ServerCapabilities.Resources())),
)
val (clientTransport, serverTransport) = ChannelTransport.createLinkedPair()
val client = Client(clientInfo = Implementation(name = "test client", version = "1.0"))
val serverSessionResult = CompletableDeferred<ServerSession>()
listOf(
launch { client.connect(clientTransport) },
launch { serverSessionResult.complete(server.createSession(serverTransport)) },
).joinAll()
val serverSession = serverSessionResult.await()
serverSession.setRequestHandler<InitializeRequest>(Method.Defined.Initialize) { _, _ ->
InitializeResult(
protocolVersion = LATEST_PROTOCOL_VERSION,
capabilities = ServerCapabilities(
resources = ServerCapabilities.Resources(null, null),
tools = ServerCapabilities.Tools(null),
),
serverInfo = Implementation(name = "test", version = "1.0"),
)
}
serverSession.setRequestHandler<ListResourcesRequest>(Method.Defined.ResourcesList) { _, _ ->
ListResourcesResult(
resources = listOf(Resource(uri = "/foo/bar", name = "foo-bar-resource")),
)
}
// Test client operations
client.listResources() shouldNotBeNull {
this.resources shouldHaveSize 1
}
// Clean up resources
client.close()
server.close()
}
```
**Note**: In production tests, wrap client/server operations in try-finally blocks to ensure proper resource cleanup even if assertions fail.
Use this module for unit and integration testing of MCP implementations without managing external server processes,
network ports, or I/O streams. The channel-based transport ensures tests run instantly with full isolation between test
cases.