@@ -270,6 +270,7 @@ func TestCreateEntitiesForRequest_GroupsAsParents(t *testing.T) {
270270 map [string ]interface {}{"sub" : "user1" },
271271 map [string ]interface {}{"name" : "weather" },
272272 tt .groups ,
273+ "" ,
273274 )
274275 require .NoError (t , err )
275276 require .NotNil (t , entities )
@@ -387,7 +388,7 @@ func TestCreateCedarEntities(t *testing.T) {
387388 factory := NewEntityFactory ()
388389
389390 // Create Cedar entities (no groups for these test cases)
390- entities , err := factory .CreateEntitiesForRequest (tc .principal , tc .action , tc .resource , tc .claimsMap , tc .attributes , nil )
391+ entities , err := factory .CreateEntitiesForRequest (tc .principal , tc .action , tc .resource , tc .claimsMap , tc .attributes , nil , "" )
391392
392393 // Check error expectations
393394 if tc .expectErr {
@@ -463,3 +464,94 @@ func TestCreateCedarEntities(t *testing.T) {
463464 })
464465 }
465466}
467+
468+ // TestCreateEntitiesForRequest_MCPParent verifies that CreateEntitiesForRequest
469+ // sets an MCP parent UID on the resource entity when serverName is non-empty,
470+ // and leaves the resource parentless when serverName is empty.
471+ func TestCreateEntitiesForRequest_MCPParent (t * testing.T ) {
472+ t .Parallel ()
473+
474+ factory := NewEntityFactory ()
475+
476+ tests := []struct {
477+ name string
478+ resource string
479+ serverName string
480+ wantParentCount int
481+ wantMCPParentID string
482+ }{
483+ {
484+ name : "empty_serverName_no_parent" ,
485+ resource : "Tool::weather" ,
486+ serverName : "" ,
487+ wantParentCount : 0 ,
488+ },
489+ {
490+ name : "serverName_sets_MCP_parent_on_Tool" ,
491+ resource : "Tool::weather" ,
492+ serverName : "github" ,
493+ wantParentCount : 1 ,
494+ wantMCPParentID : "github" ,
495+ },
496+ {
497+ name : "serverName_sets_MCP_parent_on_Prompt" ,
498+ resource : "Prompt::greeting" ,
499+ serverName : "github" ,
500+ wantParentCount : 1 ,
501+ wantMCPParentID : "github" ,
502+ },
503+ {
504+ name : "serverName_sets_MCP_parent_on_Resource" ,
505+ resource : "Resource::readme" ,
506+ serverName : "github" ,
507+ wantParentCount : 1 ,
508+ wantMCPParentID : "github" ,
509+ },
510+ {
511+ name : "serverName_with_special_characters" ,
512+ resource : "Tool::weather" ,
513+ serverName : "my-server.example.com" ,
514+ wantParentCount : 1 ,
515+ wantMCPParentID : "my-server.example.com" ,
516+ },
517+ }
518+
519+ for _ , tt := range tests {
520+ t .Run (tt .name , func (t * testing.T ) {
521+ t .Parallel ()
522+
523+ entities , err := factory .CreateEntitiesForRequest (
524+ "Client::user1" ,
525+ "Action::call_tool" ,
526+ tt .resource ,
527+ map [string ]interface {}{"sub" : "user1" },
528+ map [string ]interface {}{},
529+ nil ,
530+ tt .serverName ,
531+ )
532+ require .NoError (t , err )
533+ require .NotNil (t , entities )
534+
535+ // Find the resource entity by scanning for a non-Client, non-Action UID.
536+ var resourceEntity cedar.Entity
537+ var found bool
538+ for uid , ent := range entities {
539+ if string (uid .Type ) != "Client" && string (uid .Type ) != "Action" {
540+ resourceEntity = ent
541+ found = true
542+ break
543+ }
544+ }
545+ require .True (t , found , "resource entity not found in map" )
546+
547+ assert .Equal (t , tt .wantParentCount , resourceEntity .Parents .Len (),
548+ "unexpected number of parents on resource entity" )
549+
550+ if tt .wantMCPParentID != "" {
551+ mcpUID := cedar .NewEntityUID ("MCP" , cedar .String (tt .wantMCPParentID ))
552+ assert .True (t , resourceEntity .Parents .Contains (mcpUID ),
553+ "expected MCP::%q in resource.Parents" , tt .wantMCPParentID )
554+ }
555+ })
556+ }
557+ }
0 commit comments