Skip to content

Commit c0249a5

Browse files
jclynekpavlov
authored andcommitted
Adds Instructions to the server and propagates to the InitializeResult
1 parent 0ed92f5 commit c0249a5

File tree

6 files changed

+133
-7
lines changed

6 files changed

+133
-7
lines changed

kotlin-sdk-core/api/kotlin-sdk-core.api

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -975,16 +975,18 @@ public final class io/modelcontextprotocol/kotlin/sdk/InitializeRequest$Companio
975975

976976
public final class io/modelcontextprotocol/kotlin/sdk/InitializeResult : io/modelcontextprotocol/kotlin/sdk/ServerResult {
977977
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/InitializeResult$Companion;
978-
public fun <init> (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/ServerCapabilities;Lio/modelcontextprotocol/kotlin/sdk/Implementation;Lkotlinx/serialization/json/JsonObject;)V
979-
public synthetic fun <init> (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/ServerCapabilities;Lio/modelcontextprotocol/kotlin/sdk/Implementation;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
978+
public fun <init> (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/ServerCapabilities;Lio/modelcontextprotocol/kotlin/sdk/Implementation;Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;)V
979+
public synthetic fun <init> (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/ServerCapabilities;Lio/modelcontextprotocol/kotlin/sdk/Implementation;Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
980980
public final fun component1 ()Ljava/lang/String;
981981
public final fun component2 ()Lio/modelcontextprotocol/kotlin/sdk/ServerCapabilities;
982982
public final fun component3 ()Lio/modelcontextprotocol/kotlin/sdk/Implementation;
983-
public final fun component4 ()Lkotlinx/serialization/json/JsonObject;
984-
public final fun copy (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/ServerCapabilities;Lio/modelcontextprotocol/kotlin/sdk/Implementation;Lkotlinx/serialization/json/JsonObject;)Lio/modelcontextprotocol/kotlin/sdk/InitializeResult;
985-
public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/InitializeResult;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/ServerCapabilities;Lio/modelcontextprotocol/kotlin/sdk/Implementation;Lkotlinx/serialization/json/JsonObject;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/InitializeResult;
983+
public final fun component4 ()Ljava/lang/String;
984+
public final fun component5 ()Lkotlinx/serialization/json/JsonObject;
985+
public final fun copy (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/ServerCapabilities;Lio/modelcontextprotocol/kotlin/sdk/Implementation;Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;)Lio/modelcontextprotocol/kotlin/sdk/InitializeResult;
986+
public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/InitializeResult;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/ServerCapabilities;Lio/modelcontextprotocol/kotlin/sdk/Implementation;Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/InitializeResult;
986987
public fun equals (Ljava/lang/Object;)Z
987988
public final fun getCapabilities ()Lio/modelcontextprotocol/kotlin/sdk/ServerCapabilities;
989+
public final fun getInstructions ()Ljava/lang/String;
988990
public final fun getProtocolVersion ()Ljava/lang/String;
989991
public final fun getServerInfo ()Lio/modelcontextprotocol/kotlin/sdk/Implementation;
990992
public fun get_meta ()Lkotlinx/serialization/json/JsonObject;

kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,10 @@ public data class InitializeResult(
512512
val protocolVersion: String = LATEST_PROTOCOL_VERSION,
513513
val capabilities: ServerCapabilities = ServerCapabilities(),
514514
val serverInfo: Implementation,
515+
/**
516+
* Optional instructions from the server to the client about how to use this server.
517+
*/
518+
val instructions: String? = null,
515519
override val _meta: JsonObject = EmptyJsonObject,
516520
) : ServerResult
517521

kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/TypesTest.kt

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,4 +394,63 @@ class TypesTest {
394394
assertEquals("id", request.argument.name)
395395
assertEquals("123", request.argument.value)
396396
}
397+
398+
// InitializeResult Tests
399+
@Test
400+
fun `should create InitializeResult with default instructions`() {
401+
val serverInfo = Implementation(name = "test-server", version = "1.0.0")
402+
val result = InitializeResult(
403+
serverInfo = serverInfo,
404+
)
405+
406+
assertEquals(LATEST_PROTOCOL_VERSION, result.protocolVersion)
407+
assertEquals(serverInfo, result.serverInfo)
408+
assertEquals(null, result.instructions)
409+
}
410+
411+
@Test
412+
fun `should create InitializeResult with custom instructions`() {
413+
val serverInfo = Implementation(name = "test-server", version = "1.0.0")
414+
val instructions = "Use this server to perform calculations. Call the 'add' tool to add numbers."
415+
val result = InitializeResult(
416+
serverInfo = serverInfo,
417+
instructions = instructions,
418+
)
419+
420+
assertEquals(LATEST_PROTOCOL_VERSION, result.protocolVersion)
421+
assertEquals(serverInfo, result.serverInfo)
422+
assertEquals(instructions, result.instructions)
423+
}
424+
425+
@Test
426+
fun `should serialize and deserialize InitializeResult with instructions`() {
427+
val serverInfo = Implementation(name = "test-server", version = "1.0.0")
428+
val instructions = "This server provides file system access. Use the 'read' tool to read files."
429+
val result = InitializeResult(
430+
serverInfo = serverInfo,
431+
instructions = instructions,
432+
)
433+
434+
val json = McpJson.encodeToString(result)
435+
val decoded = McpJson.decodeFromString<InitializeResult>(json)
436+
437+
assertEquals(LATEST_PROTOCOL_VERSION, decoded.protocolVersion)
438+
assertEquals(serverInfo, decoded.serverInfo)
439+
assertEquals(instructions, decoded.instructions)
440+
}
441+
442+
@Test
443+
fun `should serialize and deserialize InitializeResult without instructions`() {
444+
val serverInfo = Implementation(name = "test-server", version = "1.0.0")
445+
val result = InitializeResult(
446+
serverInfo = serverInfo,
447+
)
448+
449+
val json = McpJson.encodeToString(result)
450+
val decoded = McpJson.decodeFromString<InitializeResult>(json)
451+
452+
assertEquals(LATEST_PROTOCOL_VERSION, decoded.protocolVersion)
453+
assertEquals(serverInfo, decoded.serverInfo)
454+
assertEquals(null, decoded.instructions)
455+
}
397456
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ public final class io/modelcontextprotocol/kotlin/sdk/server/RegisteredTool {
4545
}
4646

4747
public class io/modelcontextprotocol/kotlin/sdk/server/Server : io/modelcontextprotocol/kotlin/sdk/shared/Protocol {
48-
public fun <init> (Lio/modelcontextprotocol/kotlin/sdk/Implementation;Lio/modelcontextprotocol/kotlin/sdk/server/ServerOptions;)V
48+
public fun <init> (Lio/modelcontextprotocol/kotlin/sdk/Implementation;Lio/modelcontextprotocol/kotlin/sdk/server/ServerOptions;Ljava/lang/String;)V
49+
public synthetic fun <init> (Lio/modelcontextprotocol/kotlin/sdk/Implementation;Lio/modelcontextprotocol/kotlin/sdk/server/ServerOptions;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
4950
public final fun addPrompt (Lio/modelcontextprotocol/kotlin/sdk/Prompt;Lkotlin/jvm/functions/Function2;)V
5051
public final fun addPrompt (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lkotlin/jvm/functions/Function2;)V
5152
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

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,13 @@ public class ServerOptions(public val capabilities: ServerCapabilities, enforceS
7676
*
7777
* @param serverInfo Information about this server implementation (name, version).
7878
* @param options Configuration options for the server.
79+
* @param instructions Optional instructions from the server to the client about how to use this server.
7980
*/
80-
public open class Server(private val serverInfo: Implementation, options: ServerOptions) : Protocol(options) {
81+
public open class Server(
82+
private val serverInfo: Implementation,
83+
options: ServerOptions,
84+
private val instructions: String? = null,
85+
) : Protocol(options) {
8186
@Suppress("ktlint:standard:backing-property-naming")
8287
private var _onInitialized: (() -> Unit) = {}
8388

@@ -613,6 +618,7 @@ public open class Server(private val serverInfo: Implementation, options: Server
613618
protocolVersion = protocolVersion,
614619
capabilities = capabilities,
615620
serverInfo = serverInfo,
621+
instructions = instructions,
616622
)
617623
}
618624

kotlin-sdk-test/src/jvmTest/kotlin/io/modelcontextprotocol/kotlin/sdk/server/ServerTest.kt

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,4 +471,58 @@ class ServerTest {
471471
}
472472
assertEquals("Server does not support resources capability.", exception.message)
473473
}
474+
475+
@Test
476+
fun `Server constructor should accept instructions parameter`() = runTest {
477+
val serverInfo = Implementation(name = "test server", version = "1.0")
478+
val serverOptions = ServerOptions(capabilities = ServerCapabilities())
479+
val instructions = "This is a test server. Use it for testing purposes only."
480+
481+
val server = Server(serverInfo, serverOptions, instructions)
482+
483+
// The instructions should be stored internally and used in handleInitialize
484+
// We can't directly access the private field, but we can test it through initialization
485+
val (clientTransport, serverTransport) = InMemoryTransport.createLinkedPair()
486+
val client = Client(clientInfo = Implementation(name = "test client", version = "1.0"))
487+
488+
launch { client.connect(clientTransport) }
489+
launch { server.connect(serverTransport) }
490+
491+
// The test passes if the server can be created with instructions without throwing
492+
assertTrue(true, "Server should accept instructions parameter")
493+
}
494+
495+
@Test
496+
fun `Server constructor should work with null instructions`() = runTest {
497+
val serverInfo = Implementation(name = "test server", version = "1.0")
498+
val serverOptions = ServerOptions(capabilities = ServerCapabilities())
499+
500+
val server = Server(serverInfo, serverOptions, null)
501+
502+
// Test that server works with null instructions
503+
val (clientTransport, serverTransport) = InMemoryTransport.createLinkedPair()
504+
val client = Client(clientInfo = Implementation(name = "test client", version = "1.0"))
505+
506+
launch { client.connect(clientTransport) }
507+
launch { server.connect(serverTransport) }
508+
509+
assertTrue(true, "Server should accept null instructions parameter")
510+
}
511+
512+
@Test
513+
fun `Server constructor should work with default instructions parameter`() = runTest {
514+
val serverInfo = Implementation(name = "test server", version = "1.0")
515+
val serverOptions = ServerOptions(capabilities = ServerCapabilities())
516+
517+
// Test that server works when instructions parameter is omitted (defaults to null)
518+
val server = Server(serverInfo, serverOptions)
519+
520+
val (clientTransport, serverTransport) = InMemoryTransport.createLinkedPair()
521+
val client = Client(clientInfo = Implementation(name = "test client", version = "1.0"))
522+
523+
launch { client.connect(clientTransport) }
524+
launch { server.connect(serverTransport) }
525+
526+
assertTrue(true, "Server should work with default instructions parameter")
527+
}
474528
}

0 commit comments

Comments
 (0)