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