@@ -366,6 +366,109 @@ func TestDirectModeHandler_DestructiveToolNeedsDestructivePermission(t *testing.
366366 assert .Contains (t , result .Content [0 ].(mcp.TextContent ).Text , "destructive" )
367367}
368368
369+ func TestFilterDirectModeToolsForAuth_AgentServerAndPermissionScope (t * testing.T ) {
370+ proxy := & MCPProxyServer {}
371+
372+ githubRead := FormatDirectToolName ("github" , "get_issue" )
373+ githubWrite := FormatDirectToolName ("github" , "create_issue" )
374+ githubDestroy := FormatDirectToolName ("github" , "delete_repo" )
375+ gitlabRead := FormatDirectToolName ("gitlab" , "get_issue" )
376+
377+ proxy .setDirectToolPermissions (map [string ]string {
378+ githubRead : auth .PermRead ,
379+ githubWrite : auth .PermWrite ,
380+ githubDestroy : auth .PermDestructive ,
381+ gitlabRead : auth .PermRead ,
382+ })
383+
384+ tools := []mcp.Tool {
385+ {Name : githubRead },
386+ {Name : githubWrite },
387+ {Name : githubDestroy },
388+ {Name : gitlabRead },
389+ }
390+
391+ agentCtx := auth .WithAuthContext (context .Background (), & auth.AuthContext {
392+ Type : auth .AuthTypeAgent ,
393+ AgentName : "test-agent" ,
394+ AllowedServers : []string {"github" },
395+ Permissions : []string {auth .PermRead , auth .PermWrite },
396+ })
397+
398+ filtered := proxy .filterDirectModeToolsForAuth (agentCtx , tools )
399+
400+ assert .Equal (t , []string {githubRead , githubWrite }, directToolNamesForTest (filtered ))
401+ }
402+
403+ func TestFilterDirectModeToolsForAuth_NonAgentUnchanged (t * testing.T ) {
404+ proxy := & MCPProxyServer {}
405+ tools := []mcp.Tool {
406+ {Name : FormatDirectToolName ("github" , "get_issue" )},
407+ {Name : FormatDirectToolName ("gitlab" , "get_issue" )},
408+ }
409+
410+ assert .Equal (t , tools , proxy .filterDirectModeToolsForAuth (context .Background (), tools ))
411+
412+ adminCtx := auth .WithAuthContext (context .Background (), auth .AdminContext ())
413+ assert .Equal (t , tools , proxy .filterDirectModeToolsForAuth (adminCtx , tools ))
414+ }
415+
416+ func TestFilterDirectModeToolsForAuth_FailsClosedOnMissingPermissionMetadata (t * testing.T ) {
417+ proxy := & MCPProxyServer {}
418+
419+ visible := FormatDirectToolName ("github" , "get_issue" )
420+ missing := FormatDirectToolName ("github" , "unknown" )
421+ proxy .setDirectToolPermissions (map [string ]string {
422+ visible : auth .PermRead ,
423+ })
424+
425+ ctx := auth .WithAuthContext (context .Background (), & auth.AuthContext {
426+ Type : auth .AuthTypeAgent ,
427+ AgentName : "test-agent" ,
428+ AllowedServers : []string {"github" },
429+ Permissions : []string {auth .PermRead },
430+ })
431+
432+ filtered := proxy .filterDirectModeToolsForAuth (ctx , []mcp.Tool {
433+ {Name : visible },
434+ {Name : missing },
435+ })
436+
437+ assert .Equal (t , []string {visible }, directToolNamesForTest (filtered ))
438+ }
439+
440+ func TestFilterDirectModeToolsForAuth_KeepsNonDirectTools (t * testing.T ) {
441+ proxy := & MCPProxyServer {}
442+
443+ direct := FormatDirectToolName ("github" , "get_issue" )
444+ nonDirect := "retrieve_tools"
445+ proxy .setDirectToolPermissions (map [string ]string {
446+ direct : auth .PermRead ,
447+ })
448+
449+ ctx := auth .WithAuthContext (context .Background (), & auth.AuthContext {
450+ Type : auth .AuthTypeAgent ,
451+ AgentName : "test-agent" ,
452+ AllowedServers : []string {"github" },
453+ Permissions : []string {auth .PermRead },
454+ })
455+
456+ filtered := proxy .filterDirectModeToolsForAuth (ctx , []mcp.Tool {
457+ {Name : direct },
458+ {Name : nonDirect },
459+ })
460+
461+ assert .Equal (t , []string {direct , nonDirect }, directToolNamesForTest (filtered ))
462+ }
463+
464+ func directToolNamesForTest (tools []mcp.Tool ) []string {
465+ names := make ([]string , 0 , len (tools ))
466+ for _ , tool := range tools {
467+ names = append (names , tool .Name )
468+ }
469+ return names
470+ }
471+
369472func TestDirectModeHandler_NoAuthContext (t * testing.T ) {
370473 logger , _ := zap .NewDevelopment ()
371474 proxy := & MCPProxyServer {
0 commit comments