@@ -5,21 +5,43 @@ use tracing::debug;
55use crate :: util:: MCP_SERVER_TOOL_DELIMITER ;
66use crate :: util:: pattern_matching:: matches_any_pattern;
77
8+ const BUILT_IN_PREFIX : & str = "@builtin" ;
9+ const BUILT_IN_PREFIX_WITH_SLASH : & str = "@builtin/" ;
10+
811/// Checks if a tool is allowed based on the agent's allowed_tools configuration.
912/// This function handles both native tools and MCP tools with wildcard pattern support.
1013pub fn is_tool_in_allowlist ( allowed_tools : & HashSet < String > , tool_name : & str , server_name : Option < & str > ) -> bool {
11- let filter_patterns = |predicate : fn ( & str ) -> bool | -> HashSet < String > {
14+ let filter_patterns = |predicate : fn ( & str ) -> bool | -> HashSet < & str > {
1215 allowed_tools
1316 . iter ( )
1417 . filter ( |pattern| predicate ( pattern) )
15- . cloned ( )
18+ . map ( String :: as_str )
1619 . collect ( )
1720 } ;
1821
1922 match server_name {
2023 // Native tool
2124 None => {
22- let patterns = filter_patterns ( |p| !p. starts_with ( '@' ) ) ;
25+ for name in allowed_tools {
26+ if name
27+ . strip_prefix ( BUILT_IN_PREFIX )
28+ . is_some_and ( |n| n. is_empty ( ) || n == "/" || n == "/*" )
29+ {
30+ return true ;
31+ }
32+ }
33+
34+ let patterns = allowed_tools
35+ . iter ( )
36+ . filter_map ( |p| {
37+ if !p. starts_with ( '@' ) {
38+ Some ( p. as_str ( ) )
39+ } else {
40+ p. strip_prefix ( BUILT_IN_PREFIX_WITH_SLASH )
41+ }
42+ } )
43+ . collect :: < HashSet < _ > > ( ) ;
44+
2345 debug ! ( "Native patterns: {:?}" , patterns) ;
2446 let result = matches_any_pattern ( & patterns, tool_name) ;
2547 debug ! ( "Native tool '{}' permission check result: {}" , tool_name, result) ;
@@ -79,4 +101,30 @@ mod tests {
79101 assert ! ( is_tool_in_allowlist( & allowed, "read_file" , Some ( "git" ) ) ) ;
80102 assert ! ( !is_tool_in_allowlist( & allowed, "write_file" , Some ( "git" ) ) ) ;
81103 }
104+
105+ #[ test]
106+ fn test_builtin_namespace ( ) {
107+ let mut allowed = HashSet :: new ( ) ;
108+ allowed. insert ( "@builtin" . to_string ( ) ) ;
109+ allowed. insert ( "@builtin/" . to_string ( ) ) ;
110+ allowed. insert ( "@builtin/*" . to_string ( ) ) ;
111+
112+ // @builtin should allow all native tools
113+ assert ! ( is_tool_in_allowlist( & allowed, "fs_read" , None ) ) ;
114+
115+ // But should not allow MCP tools
116+ assert ! ( !is_tool_in_allowlist( & allowed, "tool" , Some ( "server" ) ) ) ;
117+
118+ allowed. clear ( ) ;
119+ allowed. insert ( "@builtin/fs_read" . to_string ( ) ) ;
120+
121+ assert ! ( is_tool_in_allowlist( & allowed, "fs_read" , None ) ) ;
122+ assert ! ( !is_tool_in_allowlist( & allowed, "fs_write" , None ) ) ;
123+
124+ allowed. clear ( ) ;
125+ allowed. insert ( "@builtin/fs_*" . to_string ( ) ) ;
126+
127+ assert ! ( is_tool_in_allowlist( & allowed, "fs_read" , None ) ) ;
128+ assert ! ( is_tool_in_allowlist( & allowed, "fs_write" , None ) ) ;
129+ }
82130}
0 commit comments