17
17
import io .modelcontextprotocol .spec .McpError ;
18
18
import io .modelcontextprotocol .spec .McpSchema ;
19
19
import io .modelcontextprotocol .spec .McpSchema .ClientCapabilities ;
20
+ import io .modelcontextprotocol .spec .McpSchema .InitializeResult ;
20
21
import io .modelcontextprotocol .spec .McpSchema .Root ;
22
+ import org .junit .jupiter .api .Disabled ;
21
23
import org .junit .jupiter .api .Test ;
22
24
import reactor .core .publisher .Mono ;
23
25
27
29
28
30
class McpAsyncClientResponseHandlerTests {
29
31
32
+ private InitializeResult initialization (McpAsyncClient asyncMcpClient , MockMcpTransport transport ) {
33
+
34
+ // Create mock server response
35
+ McpSchema .ServerCapabilities mockServerCapabilities = McpSchema .ServerCapabilities .builder ()
36
+ .tools (true )
37
+ .resources (true , true ) // Enable both resources and resource templates
38
+ .build ();
39
+ McpSchema .Implementation mockServerInfo = new McpSchema .Implementation ("test-server" , "1.0.0" );
40
+ McpSchema .InitializeResult mockInitResult = new McpSchema .InitializeResult (McpSchema .LATEST_PROTOCOL_VERSION ,
41
+ mockServerCapabilities , mockServerInfo , "Test instructions" );
42
+
43
+ Mono <McpSchema .InitializeResult > initMono = asyncMcpClient .initialize ();
44
+
45
+ new Thread (new Runnable () {
46
+ @ Override
47
+ public void run () {
48
+ McpSchema .JSONRPCRequest initRequest = transport .getLastSentMessageAsRequest ();
49
+ assertThat (initRequest .method ()).isEqualTo (McpSchema .METHOD_INITIALIZE );
50
+
51
+ // Send mock server response
52
+ McpSchema .JSONRPCResponse initResponse = new McpSchema .JSONRPCResponse (McpSchema .JSONRPC_VERSION ,
53
+ initRequest .id (), mockInitResult , null );
54
+ transport .simulateIncomingMessage (initResponse );
55
+ }
56
+ }).start ();
57
+
58
+ return initMono .block ();
59
+ }
60
+
61
+ @ Test
62
+ void testSuccessfulInitialization () {
63
+ MockMcpTransport transport = new MockMcpTransport ();
64
+ McpAsyncClient asyncMcpClient = McpClient .async (transport ).build ();
65
+
66
+ // Verify client is not initialized initially
67
+ assertThat (asyncMcpClient .isInitialized ()).isFalse ();
68
+
69
+ // Create mock server response
70
+ McpSchema .ServerCapabilities mockServerCapabilities = McpSchema .ServerCapabilities .builder ()
71
+ .tools (true )
72
+ .resources (true , true ) // Enable both resources and resource templates
73
+ .build ();
74
+ McpSchema .Implementation mockServerInfo = new McpSchema .Implementation ("test-server" , "1.0.0" );
75
+ McpSchema .InitializeResult mockInitResult = new McpSchema .InitializeResult (McpSchema .LATEST_PROTOCOL_VERSION ,
76
+ mockServerCapabilities , mockServerInfo , "Test instructions" );
77
+
78
+ // Start initialization
79
+ Mono <McpSchema .InitializeResult > initMono = asyncMcpClient .initialize ();
80
+
81
+ new Thread (new Runnable () {
82
+ @ Override
83
+ public void run () {
84
+ McpSchema .JSONRPCRequest initRequest = transport .getLastSentMessageAsRequest ();
85
+ assertThat (initRequest .method ()).isEqualTo (McpSchema .METHOD_INITIALIZE );
86
+
87
+ // Send mock server response
88
+ McpSchema .JSONRPCResponse initResponse = new McpSchema .JSONRPCResponse (McpSchema .JSONRPC_VERSION ,
89
+ initRequest .id (), mockInitResult , null );
90
+ transport .simulateIncomingMessage (initResponse );
91
+ }
92
+ }).start ();
93
+
94
+ InitializeResult result = initMono .block ();
95
+
96
+ // Verify initialized notification was sent
97
+ McpSchema .JSONRPCMessage notificationMessage = transport .getLastSentMessage ();
98
+ assertThat (notificationMessage ).isInstanceOf (McpSchema .JSONRPCNotification .class );
99
+ McpSchema .JSONRPCNotification notification = (McpSchema .JSONRPCNotification ) notificationMessage ;
100
+ assertThat (notification .method ()).isEqualTo (McpSchema .METHOD_NOTIFICATION_INITIALIZED );
101
+
102
+ // Verify initialization result
103
+ assertThat (result ).isNotNull ();
104
+ assertThat (result .protocolVersion ()).isEqualTo (McpSchema .LATEST_PROTOCOL_VERSION );
105
+ assertThat (result .capabilities ()).isEqualTo (mockServerCapabilities );
106
+ assertThat (result .serverInfo ()).isEqualTo (mockServerInfo );
107
+ assertThat (result .instructions ()).isEqualTo ("Test instructions" );
108
+
109
+ // Verify client state after initialization
110
+ assertThat (asyncMcpClient .isInitialized ()).isTrue ();
111
+ assertThat (asyncMcpClient .getServerCapabilities ()).isEqualTo (mockServerCapabilities );
112
+ assertThat (asyncMcpClient .getServerInfo ()).isEqualTo (mockServerInfo );
113
+
114
+ asyncMcpClient .closeGracefully ();
115
+ }
116
+
30
117
@ Test
31
118
void testToolsChangeNotificationHandling () throws JsonProcessingException {
32
119
MockMcpTransport transport = new MockMcpTransport ();
@@ -41,6 +128,8 @@ void testToolsChangeNotificationHandling() throws JsonProcessingException {
41
128
// Create client with tools change consumer
42
129
McpAsyncClient asyncMcpClient = McpClient .async (transport ).toolsChangeConsumer (toolsChangeConsumer ).build ();
43
130
131
+ assertThat (initialization (asyncMcpClient , transport )).isNotNull ();
132
+
44
133
// Create a mock tools list that the server will return
45
134
Map <String , Object > inputSchema = Map .of ("type" , "object" , "properties" , Map .of (), "required" , List .of ());
46
135
McpSchema .Tool mockTool = new McpSchema .Tool ("test-tool" , "Test Tool Description" ,
@@ -78,6 +167,8 @@ void testRootsListRequestHandling() {
78
167
.roots (new Root ("file:///test/path" , "test-root" ))
79
168
.build ();
80
169
170
+ assertThat (initialization (asyncMcpClient , transport )).isNotNull ();
171
+
81
172
// Simulate incoming request
82
173
McpSchema .JSONRPCRequest request = new McpSchema .JSONRPCRequest (McpSchema .JSONRPC_VERSION ,
83
174
McpSchema .METHOD_ROOTS_LIST , "test-id" , null );
@@ -112,6 +203,8 @@ void testResourcesChangeNotificationHandling() {
112
203
.resourcesChangeConsumer (resourcesChangeConsumer )
113
204
.build ();
114
205
206
+ assertThat (initialization (asyncMcpClient , transport )).isNotNull ();
207
+
115
208
// Create a mock resources list that the server will return
116
209
McpSchema .Resource mockResource = new McpSchema .Resource ("test://resource" , "Test Resource" , "A test resource" ,
117
210
"text/plain" , null );
@@ -156,6 +249,8 @@ void testPromptsChangeNotificationHandling() {
156
249
// Create client with prompts change consumer
157
250
McpAsyncClient asyncMcpClient = McpClient .async (transport ).promptsChangeConsumer (promptsChangeConsumer ).build ();
158
251
252
+ assertThat (initialization (asyncMcpClient , transport )).isNotNull ();
253
+
159
254
// Create a mock prompts list that the server will return
160
255
McpSchema .Prompt mockPrompt = new McpSchema .Prompt ("test-prompt" , "Test Prompt Description" ,
161
256
List .of (new McpSchema .PromptArgument ("arg1" , "Test argument" , true )));
@@ -203,6 +298,8 @@ void testSamplingCreateMessageRequestHandling() {
203
298
.sampling (samplingHandler )
204
299
.build ();
205
300
301
+ assertThat (initialization (asyncMcpClient , transport )).isNotNull ();
302
+
206
303
// Create a mock create message request
207
304
var messageRequest = new McpSchema .CreateMessageRequest (
208
305
List .of (new McpSchema .SamplingMessage (McpSchema .Role .USER , new McpSchema .TextContent ("Test message" ))),
@@ -247,6 +344,8 @@ void testSamplingCreateMessageRequestHandlingWithoutCapability() {
247
344
.capabilities (ClientCapabilities .builder ().build ()) // No sampling capability
248
345
.build ();
249
346
347
+ assertThat (initialization (asyncMcpClient , transport )).isNotNull ();
348
+
250
349
// Create a mock create message request
251
350
var messageRequest = new McpSchema .CreateMessageRequest (
252
351
List .of (new McpSchema .SamplingMessage (McpSchema .Role .USER , new McpSchema .TextContent ("Test message" ))),
0 commit comments