21
21
import org .junit .jupiter .api .AfterEach ;
22
22
import org .junit .jupiter .api .BeforeEach ;
23
23
import org .junit .jupiter .api .Test ;
24
+ import org .junit .jupiter .params .ParameterizedTest ;
25
+ import org .junit .jupiter .params .provider .ValueSource ;
24
26
import reactor .core .publisher .Mono ;
25
27
import reactor .test .StepVerifier ;
26
28
@@ -43,7 +45,7 @@ public abstract class AbstractMcpAsyncServerTests {
43
45
44
46
private static final String TEST_PROMPT_NAME = "test-prompt" ;
45
47
46
- abstract protected McpServerTransportProvider createMcpTransportProvider ();
48
+ abstract protected McpServer . AsyncSpecification <?> prepareAsyncServerBuilder ();
47
49
48
50
protected void onStart () {
49
51
}
@@ -64,28 +66,29 @@ void tearDown() {
64
66
// Server Lifecycle Tests
65
67
// ---------------------------------------
66
68
67
- @ Test
68
- void testConstructorWithInvalidArguments () {
69
+ @ ParameterizedTest (name = "{0} : {displayName} " )
70
+ @ ValueSource (strings = { "sse" , "streamable" })
71
+ void testConstructorWithInvalidArguments (String serverType ) {
69
72
assertThatThrownBy (() -> McpServer .async ((McpServerTransportProvider ) null ))
70
73
.isInstanceOf (IllegalArgumentException .class )
71
74
.hasMessage ("Transport provider must not be null" );
72
75
73
- assertThatThrownBy (
74
- () -> McpServer .async (createMcpTransportProvider ()).serverInfo ((McpSchema .Implementation ) null ))
76
+ assertThatThrownBy (() -> prepareAsyncServerBuilder ().serverInfo ((McpSchema .Implementation ) null ))
75
77
.isInstanceOf (IllegalArgumentException .class )
76
78
.hasMessage ("Server info must not be null" );
77
79
}
78
80
79
81
@ Test
80
82
void testGracefulShutdown () {
81
- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ()).serverInfo ("test-server" , "1.0.0" ).build ();
83
+ McpServer .AsyncSpecification <?> builder = prepareAsyncServerBuilder ();
84
+ var mcpAsyncServer = builder .serverInfo ("test-server" , "1.0.0" ).build ();
82
85
83
86
StepVerifier .create (mcpAsyncServer .closeGracefully ()).verifyComplete ();
84
87
}
85
88
86
89
@ Test
87
90
void testImmediateClose () {
88
- var mcpAsyncServer = McpServer . async ( createMcpTransportProvider () ).serverInfo ("test-server" , "1.0.0" ).build ();
91
+ var mcpAsyncServer = prepareAsyncServerBuilder ( ).serverInfo ("test-server" , "1.0.0" ).build ();
89
92
90
93
assertThatCode (() -> mcpAsyncServer .close ()).doesNotThrowAnyException ();
91
94
}
@@ -105,8 +108,7 @@ void testImmediateClose() {
105
108
@ Deprecated
106
109
void testAddTool () {
107
110
Tool newTool = new McpSchema .Tool ("new-tool" , "New test tool" , emptyJsonSchema );
108
- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
109
- .serverInfo ("test-server" , "1.0.0" )
111
+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
110
112
.capabilities (ServerCapabilities .builder ().tools (true ).build ())
111
113
.build ();
112
114
@@ -120,8 +122,7 @@ void testAddTool() {
120
122
@ Test
121
123
void testAddToolCall () {
122
124
Tool newTool = new McpSchema .Tool ("new-tool" , "New test tool" , emptyJsonSchema );
123
- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
124
- .serverInfo ("test-server" , "1.0.0" )
125
+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
125
126
.capabilities (ServerCapabilities .builder ().tools (true ).build ())
126
127
.build ();
127
128
@@ -138,8 +139,7 @@ void testAddToolCall() {
138
139
void testAddDuplicateTool () {
139
140
Tool duplicateTool = new McpSchema .Tool (TEST_TOOL_NAME , "Duplicate tool" , emptyJsonSchema );
140
141
141
- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
142
- .serverInfo ("test-server" , "1.0.0" )
142
+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
143
143
.capabilities (ServerCapabilities .builder ().tools (true ).build ())
144
144
.tool (duplicateTool , (exchange , args ) -> Mono .just (new CallToolResult (List .of (), false )))
145
145
.build ();
@@ -159,8 +159,7 @@ void testAddDuplicateTool() {
159
159
void testAddDuplicateToolCall () {
160
160
Tool duplicateTool = new McpSchema .Tool (TEST_TOOL_NAME , "Duplicate tool" , emptyJsonSchema );
161
161
162
- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
163
- .serverInfo ("test-server" , "1.0.0" )
162
+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
164
163
.capabilities (ServerCapabilities .builder ().tools (true ).build ())
165
164
.toolCall (duplicateTool , (exchange , request ) -> Mono .just (new CallToolResult (List .of (), false )))
166
165
.build ();
@@ -181,8 +180,7 @@ void testDuplicateToolCallDuringBuilding() {
181
180
Tool duplicateTool = new Tool ("duplicate-build-toolcall" , "Duplicate toolcall during building" ,
182
181
emptyJsonSchema );
183
182
184
- assertThatThrownBy (() -> McpServer .async (createMcpTransportProvider ())
185
- .serverInfo ("test-server" , "1.0.0" )
183
+ assertThatThrownBy (() -> prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
186
184
.capabilities (ServerCapabilities .builder ().tools (true ).build ())
187
185
.toolCall (duplicateTool , (exchange , request ) -> Mono .just (new CallToolResult (List .of (), false )))
188
186
.toolCall (duplicateTool , (exchange , request ) -> Mono .just (new CallToolResult (List .of (), false ))) // Duplicate!
@@ -204,8 +202,7 @@ void testDuplicateToolsInBatchListRegistration() {
204
202
.build () // Duplicate!
205
203
);
206
204
207
- assertThatThrownBy (() -> McpServer .async (createMcpTransportProvider ())
208
- .serverInfo ("test-server" , "1.0.0" )
205
+ assertThatThrownBy (() -> prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
209
206
.capabilities (ServerCapabilities .builder ().tools (true ).build ())
210
207
.tools (specs )
211
208
.build ()).isInstanceOf (IllegalArgumentException .class )
@@ -216,8 +213,7 @@ void testDuplicateToolsInBatchListRegistration() {
216
213
void testDuplicateToolsInBatchVarargsRegistration () {
217
214
Tool duplicateTool = new Tool ("batch-varargs-tool" , "Duplicate tool in batch varargs" , emptyJsonSchema );
218
215
219
- assertThatThrownBy (() -> McpServer .async (createMcpTransportProvider ())
220
- .serverInfo ("test-server" , "1.0.0" )
216
+ assertThatThrownBy (() -> prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
221
217
.capabilities (ServerCapabilities .builder ().tools (true ).build ())
222
218
.tools (McpServerFeatures .AsyncToolSpecification .builder ()
223
219
.tool (duplicateTool )
@@ -236,8 +232,7 @@ void testDuplicateToolsInBatchVarargsRegistration() {
236
232
void testRemoveTool () {
237
233
Tool too = new McpSchema .Tool (TEST_TOOL_NAME , "Duplicate tool" , emptyJsonSchema );
238
234
239
- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
240
- .serverInfo ("test-server" , "1.0.0" )
235
+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
241
236
.capabilities (ServerCapabilities .builder ().tools (true ).build ())
242
237
.toolCall (too , (exchange , request ) -> Mono .just (new CallToolResult (List .of (), false )))
243
238
.build ();
@@ -249,8 +244,7 @@ void testRemoveTool() {
249
244
250
245
@ Test
251
246
void testRemoveNonexistentTool () {
252
- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
253
- .serverInfo ("test-server" , "1.0.0" )
247
+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
254
248
.capabilities (ServerCapabilities .builder ().tools (true ).build ())
255
249
.build ();
256
250
@@ -265,8 +259,7 @@ void testRemoveNonexistentTool() {
265
259
void testNotifyToolsListChanged () {
266
260
Tool too = new McpSchema .Tool (TEST_TOOL_NAME , "Duplicate tool" , emptyJsonSchema );
267
261
268
- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
269
- .serverInfo ("test-server" , "1.0.0" )
262
+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
270
263
.capabilities (ServerCapabilities .builder ().tools (true ).build ())
271
264
.toolCall (too , (exchange , args ) -> Mono .just (new CallToolResult (List .of (), false )))
272
265
.build ();
@@ -282,7 +275,7 @@ void testNotifyToolsListChanged() {
282
275
283
276
@ Test
284
277
void testNotifyResourcesListChanged () {
285
- var mcpAsyncServer = McpServer . async ( createMcpTransportProvider () ).serverInfo ("test-server" , "1.0.0" ).build ();
278
+ var mcpAsyncServer = prepareAsyncServerBuilder ( ).serverInfo ("test-server" , "1.0.0" ).build ();
286
279
287
280
StepVerifier .create (mcpAsyncServer .notifyResourcesListChanged ()).verifyComplete ();
288
281
@@ -291,7 +284,7 @@ void testNotifyResourcesListChanged() {
291
284
292
285
@ Test
293
286
void testNotifyResourcesUpdated () {
294
- var mcpAsyncServer = McpServer . async ( createMcpTransportProvider () ).serverInfo ("test-server" , "1.0.0" ).build ();
287
+ var mcpAsyncServer = prepareAsyncServerBuilder ( ).serverInfo ("test-server" , "1.0.0" ).build ();
295
288
296
289
StepVerifier
297
290
.create (mcpAsyncServer
@@ -303,8 +296,7 @@ void testNotifyResourcesUpdated() {
303
296
304
297
@ Test
305
298
void testAddResource () {
306
- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
307
- .serverInfo ("test-server" , "1.0.0" )
299
+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
308
300
.capabilities (ServerCapabilities .builder ().resources (true , false ).build ())
309
301
.build ();
310
302
@@ -320,8 +312,7 @@ void testAddResource() {
320
312
321
313
@ Test
322
314
void testAddResourceWithNullSpecification () {
323
- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
324
- .serverInfo ("test-server" , "1.0.0" )
315
+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
325
316
.capabilities (ServerCapabilities .builder ().resources (true , false ).build ())
326
317
.build ();
327
318
@@ -336,9 +327,7 @@ void testAddResourceWithNullSpecification() {
336
327
@ Test
337
328
void testAddResourceWithoutCapability () {
338
329
// Create a server without resource capabilities
339
- McpAsyncServer serverWithoutResources = McpServer .async (createMcpTransportProvider ())
340
- .serverInfo ("test-server" , "1.0.0" )
341
- .build ();
330
+ McpAsyncServer serverWithoutResources = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" ).build ();
342
331
343
332
Resource resource = new Resource (TEST_RESOURCE_URI , "Test Resource" , "text/plain" , "Test resource description" ,
344
333
null );
@@ -354,9 +343,7 @@ void testAddResourceWithoutCapability() {
354
343
@ Test
355
344
void testRemoveResourceWithoutCapability () {
356
345
// Create a server without resource capabilities
357
- McpAsyncServer serverWithoutResources = McpServer .async (createMcpTransportProvider ())
358
- .serverInfo ("test-server" , "1.0.0" )
359
- .build ();
346
+ McpAsyncServer serverWithoutResources = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" ).build ();
360
347
361
348
StepVerifier .create (serverWithoutResources .removeResource (TEST_RESOURCE_URI )).verifyErrorSatisfies (error -> {
362
349
assertThat (error ).isInstanceOf (McpError .class )
@@ -370,7 +357,7 @@ void testRemoveResourceWithoutCapability() {
370
357
371
358
@ Test
372
359
void testNotifyPromptsListChanged () {
373
- var mcpAsyncServer = McpServer . async ( createMcpTransportProvider () ).serverInfo ("test-server" , "1.0.0" ).build ();
360
+ var mcpAsyncServer = prepareAsyncServerBuilder ( ).serverInfo ("test-server" , "1.0.0" ).build ();
374
361
375
362
StepVerifier .create (mcpAsyncServer .notifyPromptsListChanged ()).verifyComplete ();
376
363
@@ -379,8 +366,7 @@ void testNotifyPromptsListChanged() {
379
366
380
367
@ Test
381
368
void testAddPromptWithNullSpecification () {
382
- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
383
- .serverInfo ("test-server" , "1.0.0" )
369
+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
384
370
.capabilities (ServerCapabilities .builder ().prompts (false ).build ())
385
371
.build ();
386
372
@@ -393,9 +379,7 @@ void testAddPromptWithNullSpecification() {
393
379
@ Test
394
380
void testAddPromptWithoutCapability () {
395
381
// Create a server without prompt capabilities
396
- McpAsyncServer serverWithoutPrompts = McpServer .async (createMcpTransportProvider ())
397
- .serverInfo ("test-server" , "1.0.0" )
398
- .build ();
382
+ McpAsyncServer serverWithoutPrompts = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" ).build ();
399
383
400
384
Prompt prompt = new Prompt (TEST_PROMPT_NAME , "Test Prompt" , "Test Prompt" , List .of ());
401
385
McpServerFeatures .AsyncPromptSpecification specification = new McpServerFeatures .AsyncPromptSpecification (
@@ -411,9 +395,7 @@ void testAddPromptWithoutCapability() {
411
395
@ Test
412
396
void testRemovePromptWithoutCapability () {
413
397
// Create a server without prompt capabilities
414
- McpAsyncServer serverWithoutPrompts = McpServer .async (createMcpTransportProvider ())
415
- .serverInfo ("test-server" , "1.0.0" )
416
- .build ();
398
+ McpAsyncServer serverWithoutPrompts = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" ).build ();
417
399
418
400
StepVerifier .create (serverWithoutPrompts .removePrompt (TEST_PROMPT_NAME )).verifyErrorSatisfies (error -> {
419
401
assertThat (error ).isInstanceOf (McpError .class )
@@ -430,8 +412,7 @@ void testRemovePrompt() {
430
412
prompt , (exchange , req ) -> Mono .just (new GetPromptResult ("Test prompt description" , List
431
413
.of (new PromptMessage (McpSchema .Role .ASSISTANT , new McpSchema .TextContent ("Test content" ))))));
432
414
433
- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
434
- .serverInfo ("test-server" , "1.0.0" )
415
+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
435
416
.capabilities (ServerCapabilities .builder ().prompts (true ).build ())
436
417
.prompts (specification )
437
418
.build ();
@@ -443,8 +424,7 @@ void testRemovePrompt() {
443
424
444
425
@ Test
445
426
void testRemoveNonexistentPrompt () {
446
- var mcpAsyncServer2 = McpServer .async (createMcpTransportProvider ())
447
- .serverInfo ("test-server" , "1.0.0" )
427
+ var mcpAsyncServer2 = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
448
428
.capabilities (ServerCapabilities .builder ().prompts (true ).build ())
449
429
.build ();
450
430
@@ -467,8 +447,7 @@ void testRootsChangeHandlers() {
467
447
var rootsReceived = new McpSchema .Root [1 ];
468
448
var consumerCalled = new boolean [1 ];
469
449
470
- var singleConsumerServer = McpServer .async (createMcpTransportProvider ())
471
- .serverInfo ("test-server" , "1.0.0" )
450
+ var singleConsumerServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
472
451
.rootsChangeHandlers (List .of ((exchange , roots ) -> Mono .fromRunnable (() -> {
473
452
consumerCalled [0 ] = true ;
474
453
if (!roots .isEmpty ()) {
@@ -487,8 +466,7 @@ void testRootsChangeHandlers() {
487
466
var consumer2Called = new boolean [1 ];
488
467
var rootsContent = new List [1 ];
489
468
490
- var multipleConsumersServer = McpServer .async (createMcpTransportProvider ())
491
- .serverInfo ("test-server" , "1.0.0" )
469
+ var multipleConsumersServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
492
470
.rootsChangeHandlers (List .of ((exchange , roots ) -> Mono .fromRunnable (() -> {
493
471
consumer1Called [0 ] = true ;
494
472
rootsContent [0 ] = roots ;
@@ -501,8 +479,7 @@ void testRootsChangeHandlers() {
501
479
onClose ();
502
480
503
481
// Test error handling
504
- var errorHandlingServer = McpServer .async (createMcpTransportProvider ())
505
- .serverInfo ("test-server" , "1.0.0" )
482
+ var errorHandlingServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
506
483
.rootsChangeHandlers (List .of ((exchange , roots ) -> {
507
484
throw new RuntimeException ("Test error" );
508
485
}))
@@ -514,9 +491,7 @@ void testRootsChangeHandlers() {
514
491
onClose ();
515
492
516
493
// Test without consumers
517
- var noConsumersServer = McpServer .async (createMcpTransportProvider ())
518
- .serverInfo ("test-server" , "1.0.0" )
519
- .build ();
494
+ var noConsumersServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" ).build ();
520
495
521
496
assertThat (noConsumersServer ).isNotNull ();
522
497
assertThatCode (() -> noConsumersServer .closeGracefully ().block (Duration .ofSeconds (10 )))
0 commit comments