@@ -3499,4 +3499,144 @@ describe("prompt()", () => {
3499
3499
expect ( typeof receivedRequestId === 'string' || typeof receivedRequestId === 'number' ) . toBe ( true ) ;
3500
3500
expect ( result . messages [ 0 ] . content . text ) . toContain ( "Received request ID:" ) ;
3501
3501
} ) ;
3502
+
3503
+ /***
3504
+ * Test: Resource Template Metadata Priority
3505
+ */
3506
+ test ( "should prioritize individual resource metadata over template metadata" , async ( ) => {
3507
+ const mcpServer = new McpServer ( {
3508
+ name : "test server" ,
3509
+ version : "1.0" ,
3510
+ } ) ;
3511
+ const client = new Client ( {
3512
+ name : "test client" ,
3513
+ version : "1.0" ,
3514
+ } ) ;
3515
+
3516
+ mcpServer . resource (
3517
+ "test" ,
3518
+ new ResourceTemplate ( "test://resource/{id}" , {
3519
+ list : async ( ) => ( {
3520
+ resources : [
3521
+ {
3522
+ name : "Resource 1" ,
3523
+ uri : "test://resource/1" ,
3524
+ description : "Individual resource description" ,
3525
+ mimeType : "text/plain" ,
3526
+ } ,
3527
+ {
3528
+ name : "Resource 2" ,
3529
+ uri : "test://resource/2" ,
3530
+ // This resource has no description or mimeType
3531
+ } ,
3532
+ ] ,
3533
+ } ) ,
3534
+ } ) ,
3535
+ {
3536
+ description : "Template description" ,
3537
+ mimeType : "application/json" ,
3538
+ } ,
3539
+ async ( uri ) => ( {
3540
+ contents : [
3541
+ {
3542
+ uri : uri . href ,
3543
+ text : "Test content" ,
3544
+ } ,
3545
+ ] ,
3546
+ } ) ,
3547
+ ) ;
3548
+
3549
+ const [ clientTransport , serverTransport ] =
3550
+ InMemoryTransport . createLinkedPair ( ) ;
3551
+
3552
+ await Promise . all ( [
3553
+ client . connect ( clientTransport ) ,
3554
+ mcpServer . server . connect ( serverTransport ) ,
3555
+ ] ) ;
3556
+
3557
+ const result = await client . request (
3558
+ {
3559
+ method : "resources/list" ,
3560
+ } ,
3561
+ ListResourcesResultSchema ,
3562
+ ) ;
3563
+
3564
+ expect ( result . resources ) . toHaveLength ( 2 ) ;
3565
+
3566
+ // Resource 1 should have its own metadata
3567
+ expect ( result . resources [ 0 ] . name ) . toBe ( "Resource 1" ) ;
3568
+ expect ( result . resources [ 0 ] . description ) . toBe ( "Individual resource description" ) ;
3569
+ expect ( result . resources [ 0 ] . mimeType ) . toBe ( "text/plain" ) ;
3570
+
3571
+ // Resource 2 should inherit template metadata
3572
+ expect ( result . resources [ 1 ] . name ) . toBe ( "Resource 2" ) ;
3573
+ expect ( result . resources [ 1 ] . description ) . toBe ( "Template description" ) ;
3574
+ expect ( result . resources [ 1 ] . mimeType ) . toBe ( "application/json" ) ;
3575
+ } ) ;
3576
+
3577
+ /***
3578
+ * Test: Resource Template Metadata Overrides All Fields
3579
+ */
3580
+ test ( "should allow resource to override all template metadata fields" , async ( ) => {
3581
+ const mcpServer = new McpServer ( {
3582
+ name : "test server" ,
3583
+ version : "1.0" ,
3584
+ } ) ;
3585
+ const client = new Client ( {
3586
+ name : "test client" ,
3587
+ version : "1.0" ,
3588
+ } ) ;
3589
+
3590
+ mcpServer . resource (
3591
+ "test" ,
3592
+ new ResourceTemplate ( "test://resource/{id}" , {
3593
+ list : async ( ) => ( {
3594
+ resources : [
3595
+ {
3596
+ name : "Overridden Name" ,
3597
+ uri : "test://resource/1" ,
3598
+ description : "Overridden description" ,
3599
+ mimeType : "text/markdown" ,
3600
+ // Add any other metadata fields if they exist
3601
+ } ,
3602
+ ] ,
3603
+ } ) ,
3604
+ } ) ,
3605
+ {
3606
+ name : "Template Name" ,
3607
+ description : "Template description" ,
3608
+ mimeType : "application/json" ,
3609
+ } ,
3610
+ async ( uri ) => ( {
3611
+ contents : [
3612
+ {
3613
+ uri : uri . href ,
3614
+ text : "Test content" ,
3615
+ } ,
3616
+ ] ,
3617
+ } ) ,
3618
+ ) ;
3619
+
3620
+ const [ clientTransport , serverTransport ] =
3621
+ InMemoryTransport . createLinkedPair ( ) ;
3622
+
3623
+ await Promise . all ( [
3624
+ client . connect ( clientTransport ) ,
3625
+ mcpServer . server . connect ( serverTransport ) ,
3626
+ ] ) ;
3627
+
3628
+ const result = await client . request (
3629
+ {
3630
+ method : "resources/list" ,
3631
+ } ,
3632
+ ListResourcesResultSchema ,
3633
+ ) ;
3634
+
3635
+ expect ( result . resources ) . toHaveLength ( 1 ) ;
3636
+
3637
+ // All fields should be from the individual resource, not the template
3638
+ expect ( result . resources [ 0 ] . name ) . toBe ( "Overridden Name" ) ;
3639
+ expect ( result . resources [ 0 ] . description ) . toBe ( "Overridden description" ) ;
3640
+ expect ( result . resources [ 0 ] . mimeType ) . toBe ( "text/markdown" ) ;
3641
+ } ) ;
3502
3642
} ) ;
0 commit comments