@@ -4515,4 +4515,113 @@ describe("elicitInput()", () => {
4515
4515
text : "Bulk 1"
4516
4516
} ) ;
4517
4517
} ) ;
4518
+
4519
+ /***
4520
+ * Test: registerResources() bulk method
4521
+ */
4522
+ test ( "should register multiple resources with single notification using registerResources()" , async ( ) => {
4523
+ const mcpServer = new McpServer ( {
4524
+ name : "test server" ,
4525
+ version : "1.0" ,
4526
+ } ) ;
4527
+
4528
+ // Register first resource to establish capabilities
4529
+ mcpServer . resource ( "initial" , "initial://resource" , async ( ) => ( {
4530
+ contents : [ {
4531
+ uri : "initial://resource" ,
4532
+ text : "Initial resource"
4533
+ } ]
4534
+ } ) ) ;
4535
+
4536
+ const notifications : Notification [ ] = [ ]
4537
+ const client = new Client ( {
4538
+ name : "test client" ,
4539
+ version : "1.0" ,
4540
+ } ) ;
4541
+ client . fallbackNotificationHandler = async ( notification ) => {
4542
+ notifications . push ( notification )
4543
+ }
4544
+
4545
+ const [ clientTransport , serverTransport ] =
4546
+ InMemoryTransport . createLinkedPair ( ) ;
4547
+
4548
+ await Promise . all ( [
4549
+ client . connect ( clientTransport ) ,
4550
+ mcpServer . connect ( serverTransport ) ,
4551
+ ] ) ;
4552
+
4553
+ // Clear initial notifications
4554
+ notifications . length = 0 ;
4555
+
4556
+ // Register multiple resources at once using the bulk method
4557
+ const resources = mcpServer . registerResources ( [
4558
+ {
4559
+ name : "bulk1" ,
4560
+ uriOrTemplate : "bulk://resource1" ,
4561
+ config : {
4562
+ title : "Bulk Resource 1" ,
4563
+ description : "First bulk resource"
4564
+ } ,
4565
+ callback : async ( ) => ( {
4566
+ contents : [ {
4567
+ uri : "bulk://resource1" ,
4568
+ text : "Bulk resource 1 content"
4569
+ } ]
4570
+ } )
4571
+ } ,
4572
+ {
4573
+ name : "bulk2" ,
4574
+ uriOrTemplate : "bulk://resource2" ,
4575
+ config : {
4576
+ title : "Bulk Resource 2" ,
4577
+ description : "Second bulk resource"
4578
+ } ,
4579
+ callback : async ( ) => ( {
4580
+ contents : [ {
4581
+ uri : "bulk://resource2" ,
4582
+ text : "Bulk resource 2 content"
4583
+ } ]
4584
+ } )
4585
+ }
4586
+ ] ) ;
4587
+
4588
+ // Yield event loop to let notifications process
4589
+ await new Promise ( process . nextTick ) ;
4590
+
4591
+ // Should have sent exactly ONE notification for all resources
4592
+ expect ( notifications ) . toHaveLength ( 1 ) ;
4593
+ expect ( notifications [ 0 ] ) . toMatchObject ( {
4594
+ method : "notifications/resources/list_changed" ,
4595
+ } ) ;
4596
+
4597
+ // Should return array of registered resources
4598
+ expect ( resources ) . toHaveLength ( 2 ) ;
4599
+ expect ( resources [ 0 ] . title ) . toBe ( "Bulk Resource 1" ) ;
4600
+ expect ( resources [ 1 ] . title ) . toBe ( "Bulk Resource 2" ) ;
4601
+
4602
+ // Verify all resources are registered and functional
4603
+ const resourcesResult = await client . request (
4604
+ { method : "resources/list" } ,
4605
+ ListResourcesResultSchema ,
4606
+ ) ;
4607
+ expect ( resourcesResult . resources ) . toHaveLength ( 3 ) ; // initial + 2 bulk resources
4608
+
4609
+ const resourceNames = resourcesResult . resources . map ( r => r . name ) . sort ( ) ;
4610
+ expect ( resourceNames ) . toEqual ( [ "bulk1" , "bulk2" , "initial" ] ) ;
4611
+
4612
+ // Test that a resource actually works
4613
+ const readResult = await client . request (
4614
+ {
4615
+ method : "resources/read" ,
4616
+ params : {
4617
+ uri : "bulk://resource1"
4618
+ }
4619
+ } ,
4620
+ ReadResourceResultSchema ,
4621
+ ) ;
4622
+ expect ( readResult . contents [ 0 ] ) . toMatchObject ( {
4623
+ uri : "bulk://resource1" ,
4624
+ text : "Bulk resource 1 content"
4625
+ } ) ;
4626
+ } ) ;
4518
4627
} ) ;
0 commit comments