pub struct ToolMeta {
pub name: &'static str,
pub needs_db: bool,
pub write: bool,
}
#[rustfmt::skip]
pub const ALL_TOOLS: &[ToolMeta] = &[
ToolMeta { name: "add_column", needs_db: true, write: true },
ToolMeta { name: "add_compression_policy", needs_db: true, write: true },
ToolMeta { name: "add_continuous_aggregate", needs_db: true, write: true },
ToolMeta { name: "add_foreign_key", needs_db: true, write: true },
ToolMeta { name: "add_retention_policy", needs_db: true, write: true },
ToolMeta { name: "add_unique_constraint", needs_db: true, write: true },
ToolMeta { name: "alter_column_type", needs_db: true, write: true },
ToolMeta { name: "alter_index", needs_db: true, write: true },
ToolMeta { name: "alter_role", needs_db: true, write: true },
ToolMeta { name: "alter_user", needs_db: true, write: true },
ToolMeta { name: "alter_view", needs_db: true, write: true },
ToolMeta { name: "analyze_db_health", needs_db: true, write: false },
ToolMeta { name: "analyze_table", needs_db: true, write: true },
ToolMeta { name: "analyze_table_bloat", needs_db: true, write: false },
ToolMeta { name: "async_batch_delete", needs_db: true, write: true },
ToolMeta { name: "async_batch_insert", needs_db: true, write: true },
ToolMeta { name: "async_batch_insert_copy", needs_db: true, write: true },
ToolMeta { name: "async_batch_update", needs_db: true, write: true },
ToolMeta { name: "async_execute_delete", needs_db: true, write: true },
ToolMeta { name: "async_execute_insert", needs_db: true, write: true },
ToolMeta { name: "async_execute_update", needs_db: true, write: true },
ToolMeta { name: "audit_role_usage", needs_db: true, write: false },
ToolMeta { name: "backup_table", needs_db: true, write: true },
ToolMeta { name: "bm25_force_merge", needs_db: true, write: true },
ToolMeta { name: "bm25_index_stats", needs_db: true, write: false },
ToolMeta { name: "cancel_query", needs_db: true, write: true },
ToolMeta { name: "clone_table_schema", needs_db: true, write: true },
ToolMeta { name: "compress_chunk", needs_db: true, write: true },
ToolMeta { name: "create_bm25_index", needs_db: true, write: true },
ToolMeta { name: "create_database", needs_db: true, write: true },
ToolMeta { name: "create_extension", needs_db: true, write: true },
ToolMeta { name: "create_hypertable", needs_db: true, write: true },
ToolMeta { name: "create_index", needs_db: true, write: true },
ToolMeta { name: "create_partition", needs_db: true, write: true },
ToolMeta { name: "create_role", needs_db: true, write: true },
ToolMeta { name: "create_schema", needs_db: true, write: true },
ToolMeta { name: "create_sequence", needs_db: true, write: true },
ToolMeta { name: "create_table", needs_db: true, write: true },
ToolMeta { name: "create_user", needs_db: true, write: true },
ToolMeta { name: "create_vector_index", needs_db: true, write: true },
ToolMeta { name: "create_view", needs_db: true, write: true },
ToolMeta { name: "describe_table", needs_db: true, write: false },
ToolMeta { name: "drop_bm25_index", needs_db: true, write: true },
ToolMeta { name: "drop_column", needs_db: true, write: true },
ToolMeta { name: "drop_constraint", needs_db: true, write: true },
ToolMeta { name: "drop_extension", needs_db: true, write: true },
ToolMeta { name: "drop_foreign_key", needs_db: true, write: true },
ToolMeta { name: "drop_index", needs_db: true, write: true },
ToolMeta { name: "drop_partition", needs_db: true, write: true },
ToolMeta { name: "drop_role", needs_db: true, write: true },
ToolMeta { name: "drop_schema", needs_db: true, write: true },
ToolMeta { name: "drop_sequence", needs_db: true, write: true },
ToolMeta { name: "drop_table", needs_db: true, write: true },
ToolMeta { name: "drop_user", needs_db: true, write: true },
ToolMeta { name: "drop_view", needs_db: true, write: true },
ToolMeta { name: "execute_delete", needs_db: true, write: true },
ToolMeta { name: "execute_insert", needs_db: true, write: true },
ToolMeta { name: "execute_query", needs_db: true, write: false },
ToolMeta { name: "execute_update", needs_db: true, write: true },
ToolMeta { name: "explain_query", needs_db: true, write: false },
ToolMeta { name: "export_csv", needs_db: true, write: false },
ToolMeta { name: "find_missing_fk_indexes", needs_db: true, write: false },
ToolMeta { name: "find_tables_without_pk", needs_db: true, write: false },
ToolMeta { name: "generate_create_index_ddl", needs_db: true, write: false },
ToolMeta { name: "generate_create_table_ddl", needs_db: true, write: false },
ToolMeta { name: "get_cache_hit_ratio", needs_db: true, write: false },
ToolMeta { name: "get_index_stats", needs_db: true, write: false },
ToolMeta { name: "get_object_details", needs_db: true, write: false },
ToolMeta { name: "get_pg_stat_statements", needs_db: true, write: false },
ToolMeta { name: "get_setting", needs_db: true, write: false },
ToolMeta { name: "get_table_stats", needs_db: true, write: false },
ToolMeta { name: "grant_privileges", needs_db: true, write: true },
ToolMeta { name: "import_from_url", needs_db: true, write: true },
ToolMeta { name: "list_bm25_indexes", needs_db: true, write: false },
ToolMeta { name: "list_connections", needs_db: true, write: false },
ToolMeta { name: "list_database_privileges", needs_db: true, write: false },
ToolMeta { name: "list_databases", needs_db: true, write: false },
ToolMeta { name: "list_duplicate_indexes", needs_db: true, write: false },
ToolMeta { name: "list_extensions", needs_db: true, write: false },
ToolMeta { name: "list_indexes", needs_db: true, write: false },
ToolMeta { name: "list_partitions", needs_db: true, write: false },
ToolMeta { name: "list_replication_slots", needs_db: true, write: false },
ToolMeta { name: "list_role_memberships", needs_db: true, write: false },
ToolMeta { name: "list_schemas", needs_db: false, write: false },
ToolMeta { name: "list_standby_servers", needs_db: true, write: false },
ToolMeta { name: "list_tables", needs_db: false, write: false },
ToolMeta { name: "list_triggers", needs_db: true, write: false },
ToolMeta { name: "list_unused_indexes", needs_db: true, write: false },
ToolMeta { name: "list_user_privileges", needs_db: true, write: false },
ToolMeta { name: "list_users", needs_db: true, write: false },
ToolMeta { name: "list_vector_columns", needs_db: true, write: false },
ToolMeta { name: "reindex_database", needs_db: true, write: true },
ToolMeta { name: "reindex_table", needs_db: true, write: true },
ToolMeta { name: "rename_column", needs_db: true, write: true },
ToolMeta { name: "rename_index", needs_db: true, write: true },
ToolMeta { name: "rename_schema", needs_db: true, write: true },
ToolMeta { name: "rename_table", needs_db: true, write: true },
ToolMeta { name: "reset_statistics", needs_db: true, write: true },
ToolMeta { name: "revoke_privileges", needs_db: true, write: true },
ToolMeta { name: "sample_data", needs_db: true, write: false },
ToolMeta { name: "search_bm25", needs_db: true, write: false },
ToolMeta { name: "security_audit", needs_db: true, write: false },
ToolMeta { name: "show_active_transactions", needs_db: true, write: false },
ToolMeta { name: "show_all_settings", needs_db: true, write: false },
ToolMeta { name: "show_autocommit_status", needs_db: true, write: false },
ToolMeta { name: "show_base_backup_progress", needs_db: true, write: false },
ToolMeta { name: "show_blocked_queries", needs_db: true, write: false },
ToolMeta { name: "show_chunks", needs_db: true, write: false },
ToolMeta { name: "show_connection_summary", needs_db: true, write: false },
ToolMeta { name: "show_constraints", needs_db: false, write: false },
ToolMeta { name: "show_current_user", needs_db: true, write: false },
ToolMeta { name: "show_database_size", needs_db: true, write: false },
ToolMeta { name: "show_deadlocks", needs_db: true, write: false },
ToolMeta { name: "show_hypertable_details", needs_db: true, write: false },
ToolMeta { name: "show_locks", needs_db: true, write: false },
ToolMeta { name: "show_log_settings", needs_db: true, write: false },
ToolMeta { name: "show_memory_settings", needs_db: true, write: false },
ToolMeta { name: "show_performance_settings", needs_db: true, write: false },
ToolMeta { name: "show_replication_status", needs_db: true, write: false },
ToolMeta { name: "show_running_queries", needs_db: true, write: false },
ToolMeta { name: "show_session_info", needs_db: true, write: false },
ToolMeta { name: "show_table_size", needs_db: true, write: false },
ToolMeta { name: "show_transaction_isolation", needs_db: true, write: false },
ToolMeta { name: "show_transaction_timeout", needs_db: true, write: false },
ToolMeta { name: "show_vacuum_progress", needs_db: true, write: false },
ToolMeta { name: "show_waiting_locks", needs_db: true, write: false },
ToolMeta { name: "show_wal_info", needs_db: true, write: false },
ToolMeta { name: "suggest_indexes", needs_db: true, write: false },
ToolMeta { name: "table_dependencies", needs_db: true, write: false },
ToolMeta { name: "terminate_connection", needs_db: true, write: true },
ToolMeta { name: "truncate_table", needs_db: true, write: true },
ToolMeta { name: "vacuum", needs_db: true, write: true },
ToolMeta { name: "vacuum_analyze", needs_db: true, write: true },
ToolMeta { name: "vacuum_full", needs_db: true, write: true },
ToolMeta { name: "vector_search", needs_db: true, write: false },
];
#[inline]
pub fn tool_exists(name: &str) -> bool {
ALL_TOOLS.binary_search_by(|t| t.name.as_bytes().cmp(name.as_bytes())).is_ok()
}
#[inline]
pub fn is_write_tool(name: &str) -> bool {
ALL_TOOLS.binary_search_by(|t| t.name.as_bytes().cmp(name.as_bytes()))
.map(|i| ALL_TOOLS[i].write)
.unwrap_or(false)
}
#[inline]
pub fn needs_db(name: &str) -> bool {
ALL_TOOLS.binary_search_by(|t| t.name.as_bytes().cmp(name.as_bytes()))
.map(|i| ALL_TOOLS[i].needs_db)
.unwrap_or(false)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_all_tools_unique() {
let mut names: Vec<&str> = ALL_TOOLS.iter().map(|t| t.name).collect();
names.sort();
names.dedup();
assert_eq!(names.len(), ALL_TOOLS.len(), "Duplicate tool names in ALL_TOOLS");
}
#[test]
fn test_tool_exists_known() {
assert!(tool_exists("execute_query"));
assert!(tool_exists("list_tables"));
assert!(tool_exists("import_from_url"));
}
#[test]
fn test_tool_exists_unknown() {
assert!(!tool_exists("nonexistent_tool"));
}
#[test]
fn test_is_write_tool() {
assert!(is_write_tool("create_table"));
assert!(is_write_tool("import_from_url"));
assert!(!is_write_tool("execute_query"));
assert!(!is_write_tool("list_tables"));
}
#[test]
fn test_needs_db() {
assert!(needs_db("execute_query"));
assert!(!needs_db("list_tables"));
assert!(!needs_db("list_schemas"));
assert!(!needs_db("show_constraints"));
}
#[test]
fn test_all_tools_registered_in_tools_json() {
let content = std::fs::read_to_string("tools.json")
.expect("Failed to read tools.json");
let json: serde_json::Value = serde_json::from_str(&content)
.expect("tools.json is not valid JSON");
let json_tools = json.as_array().expect("tools.json must be an array");
let json_names: Vec<&str> = json_tools.iter()
.filter_map(|t| t.get("name").and_then(|n| n.as_str()))
.collect();
for meta in ALL_TOOLS {
assert!(
json_names.contains(&meta.name),
"Tool '{}' is in ALL_TOOLS but missing from tools.json",
meta.name,
);
}
for name in &json_names {
assert!(
tool_exists(name),
"Tool '{}' is in tools.json but missing from ALL_TOOLS",
name,
);
}
assert_eq!(json_names.len(), ALL_TOOLS.len(),
"tools.json has {} tools but ALL_TOOLS has {}",
json_names.len(), ALL_TOOLS.len());
}
}