2121import org .junit .jupiter .api .AfterEach ;
2222import org .junit .jupiter .api .BeforeEach ;
2323import org .junit .jupiter .api .Test ;
24+ import org .junit .jupiter .params .ParameterizedTest ;
25+ import org .junit .jupiter .params .provider .ValueSource ;
2426import reactor .core .publisher .Mono ;
2527import reactor .test .StepVerifier ;
2628
@@ -43,7 +45,7 @@ public abstract class AbstractMcpAsyncServerTests {
4345
4446 private static final String TEST_PROMPT_NAME = "test-prompt" ;
4547
46- abstract protected McpServerTransportProvider createMcpTransportProvider ();
48+ abstract protected McpServer . AsyncSpecification <?> prepareAsyncServerBuilder ();
4749
4850 protected void onStart () {
4951 }
@@ -64,28 +66,29 @@ void tearDown() {
6466 // Server Lifecycle Tests
6567 // ---------------------------------------
6668
67- @ Test
68- void testConstructorWithInvalidArguments () {
69+ @ ParameterizedTest (name = "{0} : {displayName} " )
70+ @ ValueSource (strings = { "sse" , "streamable" })
71+ void testConstructorWithInvalidArguments (String serverType ) {
6972 assertThatThrownBy (() -> McpServer .async ((McpServerTransportProvider ) null ))
7073 .isInstanceOf (IllegalArgumentException .class )
7174 .hasMessage ("Transport provider must not be null" );
7275
73- assertThatThrownBy (
74- () -> McpServer .async (createMcpTransportProvider ()).serverInfo ((McpSchema .Implementation ) null ))
76+ assertThatThrownBy (() -> prepareAsyncServerBuilder ().serverInfo ((McpSchema .Implementation ) null ))
7577 .isInstanceOf (IllegalArgumentException .class )
7678 .hasMessage ("Server info must not be null" );
7779 }
7880
7981 @ Test
8082 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 ();
8285
8386 StepVerifier .create (mcpAsyncServer .closeGracefully ()).verifyComplete ();
8487 }
8588
8689 @ Test
8790 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 ();
8992
9093 assertThatCode (() -> mcpAsyncServer .close ()).doesNotThrowAnyException ();
9194 }
@@ -105,8 +108,7 @@ void testImmediateClose() {
105108 @ Deprecated
106109 void testAddTool () {
107110 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" )
110112 .capabilities (ServerCapabilities .builder ().tools (true ).build ())
111113 .build ();
112114
@@ -120,8 +122,7 @@ void testAddTool() {
120122 @ Test
121123 void testAddToolCall () {
122124 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" )
125126 .capabilities (ServerCapabilities .builder ().tools (true ).build ())
126127 .build ();
127128
@@ -138,8 +139,7 @@ void testAddToolCall() {
138139 void testAddDuplicateTool () {
139140 Tool duplicateTool = new McpSchema .Tool (TEST_TOOL_NAME , "Duplicate tool" , emptyJsonSchema );
140141
141- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
142- .serverInfo ("test-server" , "1.0.0" )
142+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
143143 .capabilities (ServerCapabilities .builder ().tools (true ).build ())
144144 .tool (duplicateTool , (exchange , args ) -> Mono .just (new CallToolResult (List .of (), false )))
145145 .build ();
@@ -159,8 +159,7 @@ void testAddDuplicateTool() {
159159 void testAddDuplicateToolCall () {
160160 Tool duplicateTool = new McpSchema .Tool (TEST_TOOL_NAME , "Duplicate tool" , emptyJsonSchema );
161161
162- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
163- .serverInfo ("test-server" , "1.0.0" )
162+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
164163 .capabilities (ServerCapabilities .builder ().tools (true ).build ())
165164 .toolCall (duplicateTool , (exchange , request ) -> Mono .just (new CallToolResult (List .of (), false )))
166165 .build ();
@@ -181,8 +180,7 @@ void testDuplicateToolCallDuringBuilding() {
181180 Tool duplicateTool = new Tool ("duplicate-build-toolcall" , "Duplicate toolcall during building" ,
182181 emptyJsonSchema );
183182
184- assertThatThrownBy (() -> McpServer .async (createMcpTransportProvider ())
185- .serverInfo ("test-server" , "1.0.0" )
183+ assertThatThrownBy (() -> prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
186184 .capabilities (ServerCapabilities .builder ().tools (true ).build ())
187185 .toolCall (duplicateTool , (exchange , request ) -> Mono .just (new CallToolResult (List .of (), false )))
188186 .toolCall (duplicateTool , (exchange , request ) -> Mono .just (new CallToolResult (List .of (), false ))) // Duplicate!
@@ -204,8 +202,7 @@ void testDuplicateToolsInBatchListRegistration() {
204202 .build () // Duplicate!
205203 );
206204
207- assertThatThrownBy (() -> McpServer .async (createMcpTransportProvider ())
208- .serverInfo ("test-server" , "1.0.0" )
205+ assertThatThrownBy (() -> prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
209206 .capabilities (ServerCapabilities .builder ().tools (true ).build ())
210207 .tools (specs )
211208 .build ()).isInstanceOf (IllegalArgumentException .class )
@@ -216,8 +213,7 @@ void testDuplicateToolsInBatchListRegistration() {
216213 void testDuplicateToolsInBatchVarargsRegistration () {
217214 Tool duplicateTool = new Tool ("batch-varargs-tool" , "Duplicate tool in batch varargs" , emptyJsonSchema );
218215
219- assertThatThrownBy (() -> McpServer .async (createMcpTransportProvider ())
220- .serverInfo ("test-server" , "1.0.0" )
216+ assertThatThrownBy (() -> prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
221217 .capabilities (ServerCapabilities .builder ().tools (true ).build ())
222218 .tools (McpServerFeatures .AsyncToolSpecification .builder ()
223219 .tool (duplicateTool )
@@ -236,8 +232,7 @@ void testDuplicateToolsInBatchVarargsRegistration() {
236232 void testRemoveTool () {
237233 Tool too = new McpSchema .Tool (TEST_TOOL_NAME , "Duplicate tool" , emptyJsonSchema );
238234
239- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
240- .serverInfo ("test-server" , "1.0.0" )
235+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
241236 .capabilities (ServerCapabilities .builder ().tools (true ).build ())
242237 .toolCall (too , (exchange , request ) -> Mono .just (new CallToolResult (List .of (), false )))
243238 .build ();
@@ -249,8 +244,7 @@ void testRemoveTool() {
249244
250245 @ Test
251246 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" )
254248 .capabilities (ServerCapabilities .builder ().tools (true ).build ())
255249 .build ();
256250
@@ -265,8 +259,7 @@ void testRemoveNonexistentTool() {
265259 void testNotifyToolsListChanged () {
266260 Tool too = new McpSchema .Tool (TEST_TOOL_NAME , "Duplicate tool" , emptyJsonSchema );
267261
268- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
269- .serverInfo ("test-server" , "1.0.0" )
262+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
270263 .capabilities (ServerCapabilities .builder ().tools (true ).build ())
271264 .toolCall (too , (exchange , args ) -> Mono .just (new CallToolResult (List .of (), false )))
272265 .build ();
@@ -282,7 +275,7 @@ void testNotifyToolsListChanged() {
282275
283276 @ Test
284277 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 ();
286279
287280 StepVerifier .create (mcpAsyncServer .notifyResourcesListChanged ()).verifyComplete ();
288281
@@ -291,7 +284,7 @@ void testNotifyResourcesListChanged() {
291284
292285 @ Test
293286 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 ();
295288
296289 StepVerifier
297290 .create (mcpAsyncServer
@@ -303,8 +296,7 @@ void testNotifyResourcesUpdated() {
303296
304297 @ Test
305298 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" )
308300 .capabilities (ServerCapabilities .builder ().resources (true , false ).build ())
309301 .build ();
310302
@@ -320,8 +312,7 @@ void testAddResource() {
320312
321313 @ Test
322314 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" )
325316 .capabilities (ServerCapabilities .builder ().resources (true , false ).build ())
326317 .build ();
327318
@@ -336,9 +327,7 @@ void testAddResourceWithNullSpecification() {
336327 @ Test
337328 void testAddResourceWithoutCapability () {
338329 // 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 ();
342331
343332 Resource resource = new Resource (TEST_RESOURCE_URI , "Test Resource" , "text/plain" , "Test resource description" ,
344333 null );
@@ -354,9 +343,7 @@ void testAddResourceWithoutCapability() {
354343 @ Test
355344 void testRemoveResourceWithoutCapability () {
356345 // 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 ();
360347
361348 StepVerifier .create (serverWithoutResources .removeResource (TEST_RESOURCE_URI )).verifyErrorSatisfies (error -> {
362349 assertThat (error ).isInstanceOf (McpError .class )
@@ -370,7 +357,7 @@ void testRemoveResourceWithoutCapability() {
370357
371358 @ Test
372359 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 ();
374361
375362 StepVerifier .create (mcpAsyncServer .notifyPromptsListChanged ()).verifyComplete ();
376363
@@ -379,8 +366,7 @@ void testNotifyPromptsListChanged() {
379366
380367 @ Test
381368 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" )
384370 .capabilities (ServerCapabilities .builder ().prompts (false ).build ())
385371 .build ();
386372
@@ -393,9 +379,7 @@ void testAddPromptWithNullSpecification() {
393379 @ Test
394380 void testAddPromptWithoutCapability () {
395381 // 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 ();
399383
400384 Prompt prompt = new Prompt (TEST_PROMPT_NAME , "Test Prompt" , "Test Prompt" , List .of ());
401385 McpServerFeatures .AsyncPromptSpecification specification = new McpServerFeatures .AsyncPromptSpecification (
@@ -411,9 +395,7 @@ void testAddPromptWithoutCapability() {
411395 @ Test
412396 void testRemovePromptWithoutCapability () {
413397 // 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 ();
417399
418400 StepVerifier .create (serverWithoutPrompts .removePrompt (TEST_PROMPT_NAME )).verifyErrorSatisfies (error -> {
419401 assertThat (error ).isInstanceOf (McpError .class )
@@ -430,8 +412,7 @@ void testRemovePrompt() {
430412 prompt , (exchange , req ) -> Mono .just (new GetPromptResult ("Test prompt description" , List
431413 .of (new PromptMessage (McpSchema .Role .ASSISTANT , new McpSchema .TextContent ("Test content" ))))));
432414
433- var mcpAsyncServer = McpServer .async (createMcpTransportProvider ())
434- .serverInfo ("test-server" , "1.0.0" )
415+ var mcpAsyncServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
435416 .capabilities (ServerCapabilities .builder ().prompts (true ).build ())
436417 .prompts (specification )
437418 .build ();
@@ -443,8 +424,7 @@ void testRemovePrompt() {
443424
444425 @ Test
445426 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" )
448428 .capabilities (ServerCapabilities .builder ().prompts (true ).build ())
449429 .build ();
450430
@@ -467,8 +447,7 @@ void testRootsChangeHandlers() {
467447 var rootsReceived = new McpSchema .Root [1 ];
468448 var consumerCalled = new boolean [1 ];
469449
470- var singleConsumerServer = McpServer .async (createMcpTransportProvider ())
471- .serverInfo ("test-server" , "1.0.0" )
450+ var singleConsumerServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
472451 .rootsChangeHandlers (List .of ((exchange , roots ) -> Mono .fromRunnable (() -> {
473452 consumerCalled [0 ] = true ;
474453 if (!roots .isEmpty ()) {
@@ -487,8 +466,7 @@ void testRootsChangeHandlers() {
487466 var consumer2Called = new boolean [1 ];
488467 var rootsContent = new List [1 ];
489468
490- var multipleConsumersServer = McpServer .async (createMcpTransportProvider ())
491- .serverInfo ("test-server" , "1.0.0" )
469+ var multipleConsumersServer = prepareAsyncServerBuilder ().serverInfo ("test-server" , "1.0.0" )
492470 .rootsChangeHandlers (List .of ((exchange , roots ) -> Mono .fromRunnable (() -> {
493471 consumer1Called [0 ] = true ;
494472 rootsContent [0 ] = roots ;
@@ -501,8 +479,7 @@ void testRootsChangeHandlers() {
501479 onClose ();
502480
503481 // 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" )
506483 .rootsChangeHandlers (List .of ((exchange , roots ) -> {
507484 throw new RuntimeException ("Test error" );
508485 }))
@@ -514,9 +491,7 @@ void testRootsChangeHandlers() {
514491 onClose ();
515492
516493 // 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 ();
520495
521496 assertThat (noConsumersServer ).isNotNull ();
522497 assertThatCode (() -> noConsumersServer .closeGracefully ().block (Duration .ofSeconds (10 )))
0 commit comments