@@ -3466,4 +3466,144 @@ describe("prompt()", () => {
3466
3466
expect ( typeof receivedRequestId === 'string' || typeof receivedRequestId === 'number' ) . toBe ( true ) ;
3467
3467
expect ( result . messages [ 0 ] . content . text ) . toContain ( "Received request ID:" ) ;
3468
3468
} ) ;
3469
+
3470
+ /***
3471
+ * Test: Resource Template Metadata Priority
3472
+ */
3473
+ test ( "should prioritize individual resource metadata over template metadata" , async ( ) => {
3474
+ const mcpServer = new McpServer ( {
3475
+ name : "test server" ,
3476
+ version : "1.0" ,
3477
+ } ) ;
3478
+ const client = new Client ( {
3479
+ name : "test client" ,
3480
+ version : "1.0" ,
3481
+ } ) ;
3482
+
3483
+ mcpServer . resource (
3484
+ "test" ,
3485
+ new ResourceTemplate ( "test://resource/{id}" , {
3486
+ list : async ( ) => ( {
3487
+ resources : [
3488
+ {
3489
+ name : "Resource 1" ,
3490
+ uri : "test://resource/1" ,
3491
+ description : "Individual resource description" ,
3492
+ mimeType : "text/plain" ,
3493
+ } ,
3494
+ {
3495
+ name : "Resource 2" ,
3496
+ uri : "test://resource/2" ,
3497
+ // This resource has no description or mimeType
3498
+ } ,
3499
+ ] ,
3500
+ } ) ,
3501
+ } ) ,
3502
+ {
3503
+ description : "Template description" ,
3504
+ mimeType : "application/json" ,
3505
+ } ,
3506
+ async ( uri ) => ( {
3507
+ contents : [
3508
+ {
3509
+ uri : uri . href ,
3510
+ text : "Test content" ,
3511
+ } ,
3512
+ ] ,
3513
+ } ) ,
3514
+ ) ;
3515
+
3516
+ const [ clientTransport , serverTransport ] =
3517
+ InMemoryTransport . createLinkedPair ( ) ;
3518
+
3519
+ await Promise . all ( [
3520
+ client . connect ( clientTransport ) ,
3521
+ mcpServer . server . connect ( serverTransport ) ,
3522
+ ] ) ;
3523
+
3524
+ const result = await client . request (
3525
+ {
3526
+ method : "resources/list" ,
3527
+ } ,
3528
+ ListResourcesResultSchema ,
3529
+ ) ;
3530
+
3531
+ expect ( result . resources ) . toHaveLength ( 2 ) ;
3532
+
3533
+ // Resource 1 should have its own metadata
3534
+ expect ( result . resources [ 0 ] . name ) . toBe ( "Resource 1" ) ;
3535
+ expect ( result . resources [ 0 ] . description ) . toBe ( "Individual resource description" ) ;
3536
+ expect ( result . resources [ 0 ] . mimeType ) . toBe ( "text/plain" ) ;
3537
+
3538
+ // Resource 2 should inherit template metadata
3539
+ expect ( result . resources [ 1 ] . name ) . toBe ( "Resource 2" ) ;
3540
+ expect ( result . resources [ 1 ] . description ) . toBe ( "Template description" ) ;
3541
+ expect ( result . resources [ 1 ] . mimeType ) . toBe ( "application/json" ) ;
3542
+ } ) ;
3543
+
3544
+ /***
3545
+ * Test: Resource Template Metadata Overrides All Fields
3546
+ */
3547
+ test ( "should allow resource to override all template metadata fields" , async ( ) => {
3548
+ const mcpServer = new McpServer ( {
3549
+ name : "test server" ,
3550
+ version : "1.0" ,
3551
+ } ) ;
3552
+ const client = new Client ( {
3553
+ name : "test client" ,
3554
+ version : "1.0" ,
3555
+ } ) ;
3556
+
3557
+ mcpServer . resource (
3558
+ "test" ,
3559
+ new ResourceTemplate ( "test://resource/{id}" , {
3560
+ list : async ( ) => ( {
3561
+ resources : [
3562
+ {
3563
+ name : "Overridden Name" ,
3564
+ uri : "test://resource/1" ,
3565
+ description : "Overridden description" ,
3566
+ mimeType : "text/markdown" ,
3567
+ // Add any other metadata fields if they exist
3568
+ } ,
3569
+ ] ,
3570
+ } ) ,
3571
+ } ) ,
3572
+ {
3573
+ name : "Template Name" ,
3574
+ description : "Template description" ,
3575
+ mimeType : "application/json" ,
3576
+ } ,
3577
+ async ( uri ) => ( {
3578
+ contents : [
3579
+ {
3580
+ uri : uri . href ,
3581
+ text : "Test content" ,
3582
+ } ,
3583
+ ] ,
3584
+ } ) ,
3585
+ ) ;
3586
+
3587
+ const [ clientTransport , serverTransport ] =
3588
+ InMemoryTransport . createLinkedPair ( ) ;
3589
+
3590
+ await Promise . all ( [
3591
+ client . connect ( clientTransport ) ,
3592
+ mcpServer . server . connect ( serverTransport ) ,
3593
+ ] ) ;
3594
+
3595
+ const result = await client . request (
3596
+ {
3597
+ method : "resources/list" ,
3598
+ } ,
3599
+ ListResourcesResultSchema ,
3600
+ ) ;
3601
+
3602
+ expect ( result . resources ) . toHaveLength ( 1 ) ;
3603
+
3604
+ // All fields should be from the individual resource, not the template
3605
+ expect ( result . resources [ 0 ] . name ) . toBe ( "Overridden Name" ) ;
3606
+ expect ( result . resources [ 0 ] . description ) . toBe ( "Overridden description" ) ;
3607
+ expect ( result . resources [ 0 ] . mimeType ) . toBe ( "text/markdown" ) ;
3608
+ } ) ;
3469
3609
} ) ;
0 commit comments