use std::collections::HashSet;
pub const MCP_PROXY_PREFIX: &str = "mcp__";
pub const DYNAMIC_TOOL_PREFIX: &str = "dyn__";
#[inline]
pub fn is_mcp_proxy_tool(name: &str) -> bool {
name.starts_with(MCP_PROXY_PREFIX)
}
#[inline]
pub fn is_dynamic_tool_name(name: &str) -> bool {
name.starts_with(DYNAMIC_TOOL_PREFIX)
}
#[inline]
pub fn tool_name_allowed_by_turn_allowlist(name: &str, allow: Option<&HashSet<String>>) -> bool {
let Some(set) = allow else {
return true;
};
if is_mcp_proxy_tool(name) {
return set.contains("mcp") || set.contains(name);
}
set.contains(name)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn turn_allowlist_mcp_token_and_exact_name() {
let mut by_token = HashSet::new();
by_token.insert("mcp".to_string());
assert!(tool_name_allowed_by_turn_allowlist(
"mcp__fanalyzer__fanalyzer_watchlist_list",
Some(&by_token)
));
let mut by_exact = HashSet::new();
by_exact.insert("mcp__fanalyzer__fanalyzer_watchlist_list".to_string());
assert!(tool_name_allowed_by_turn_allowlist(
"mcp__fanalyzer__fanalyzer_watchlist_list",
Some(&by_exact)
));
assert!(!tool_name_allowed_by_turn_allowlist(
"mcp__fanalyzer__fanalyzer_analyze",
Some(&by_exact)
));
assert!(!tool_name_allowed_by_turn_allowlist(
"read_file",
Some(&by_exact)
));
}
}