1pub struct ToolMeta {
12 pub name: &'static str,
13 pub needs_db: bool,
14 pub write: bool,
15}
16
17#[rustfmt::skip]
18pub const ALL_TOOLS: &[ToolMeta] = &[
19 ToolMeta { name: "add_column", needs_db: true, write: true },
21 ToolMeta { name: "add_compression_policy", needs_db: true, write: true },
23 ToolMeta { name: "add_continuous_aggregate", needs_db: true, write: true },
25 ToolMeta { name: "add_foreign_key", needs_db: true, write: true },
27 ToolMeta { name: "add_retention_policy", needs_db: true, write: true },
29 ToolMeta { name: "add_unique_constraint", needs_db: true, write: true },
31 ToolMeta { name: "alter_column_type", needs_db: true, write: true },
33 ToolMeta { name: "alter_index", needs_db: true, write: true },
35 ToolMeta { name: "alter_role", needs_db: true, write: true },
37 ToolMeta { name: "alter_user", needs_db: true, write: true },
39 ToolMeta { name: "alter_view", needs_db: true, write: true },
41 ToolMeta { name: "analyze_db_health", needs_db: true, write: false },
43 ToolMeta { name: "analyze_table", needs_db: true, write: true },
45 ToolMeta { name: "analyze_table_bloat", needs_db: true, write: false },
47 ToolMeta { name: "async_batch_delete", needs_db: true, write: true },
49 ToolMeta { name: "async_batch_insert", needs_db: true, write: true },
51 ToolMeta { name: "async_batch_insert_copy", needs_db: true, write: true },
53 ToolMeta { name: "async_batch_update", needs_db: true, write: true },
55 ToolMeta { name: "async_execute_delete", needs_db: true, write: true },
57 ToolMeta { name: "async_execute_insert", needs_db: true, write: true },
59 ToolMeta { name: "async_execute_update", needs_db: true, write: true },
61 ToolMeta { name: "audit_role_usage", needs_db: true, write: false },
63 ToolMeta { name: "backup_table", needs_db: true, write: true },
65 ToolMeta { name: "bm25_force_merge", needs_db: true, write: true },
67 ToolMeta { name: "bm25_index_stats", needs_db: true, write: false },
69 ToolMeta { name: "cancel_query", needs_db: true, write: true },
71 ToolMeta { name: "clone_table_schema", needs_db: true, write: true },
73 ToolMeta { name: "compress_chunk", needs_db: true, write: true },
75 ToolMeta { name: "create_bm25_index", needs_db: true, write: true },
77 ToolMeta { name: "create_database", needs_db: true, write: true },
79 ToolMeta { name: "create_extension", needs_db: true, write: true },
81 ToolMeta { name: "create_hypertable", needs_db: true, write: true },
83 ToolMeta { name: "create_index", needs_db: true, write: true },
85 ToolMeta { name: "create_partition", needs_db: true, write: true },
87 ToolMeta { name: "create_role", needs_db: true, write: true },
89 ToolMeta { name: "create_schema", needs_db: true, write: true },
91 ToolMeta { name: "create_sequence", needs_db: true, write: true },
93 ToolMeta { name: "create_table", needs_db: true, write: true },
95 ToolMeta { name: "create_user", needs_db: true, write: true },
97 ToolMeta { name: "create_vector_index", needs_db: true, write: true },
99 ToolMeta { name: "create_view", needs_db: true, write: true },
101 ToolMeta { name: "describe_table", needs_db: true, write: false },
103 ToolMeta { name: "drop_bm25_index", needs_db: true, write: true },
105 ToolMeta { name: "drop_column", needs_db: true, write: true },
107 ToolMeta { name: "drop_constraint", needs_db: true, write: true },
109 ToolMeta { name: "drop_extension", needs_db: true, write: true },
111 ToolMeta { name: "drop_foreign_key", needs_db: true, write: true },
113 ToolMeta { name: "drop_index", needs_db: true, write: true },
115 ToolMeta { name: "drop_partition", needs_db: true, write: true },
117 ToolMeta { name: "drop_role", needs_db: true, write: true },
119 ToolMeta { name: "drop_schema", needs_db: true, write: true },
121 ToolMeta { name: "drop_sequence", needs_db: true, write: true },
123 ToolMeta { name: "drop_table", needs_db: true, write: true },
125 ToolMeta { name: "drop_user", needs_db: true, write: true },
127 ToolMeta { name: "drop_view", needs_db: true, write: true },
129 ToolMeta { name: "execute_delete", needs_db: true, write: true },
131 ToolMeta { name: "execute_insert", needs_db: true, write: true },
133 ToolMeta { name: "execute_query", needs_db: true, write: false },
135 ToolMeta { name: "execute_update", needs_db: true, write: true },
137 ToolMeta { name: "explain_query", needs_db: true, write: false },
139 ToolMeta { name: "export_csv", needs_db: true, write: false },
141 ToolMeta { name: "find_missing_fk_indexes", needs_db: true, write: false },
143 ToolMeta { name: "find_tables_without_pk", needs_db: true, write: false },
145 ToolMeta { name: "generate_create_index_ddl", needs_db: true, write: false },
147 ToolMeta { name: "generate_create_table_ddl", needs_db: true, write: false },
149 ToolMeta { name: "get_cache_hit_ratio", needs_db: true, write: false },
151 ToolMeta { name: "get_index_stats", needs_db: true, write: false },
153 ToolMeta { name: "get_object_details", needs_db: true, write: false },
155 ToolMeta { name: "get_pg_stat_statements", needs_db: true, write: false },
157 ToolMeta { name: "get_setting", needs_db: true, write: false },
159 ToolMeta { name: "get_table_stats", needs_db: true, write: false },
161 ToolMeta { name: "grant_privileges", needs_db: true, write: true },
163 ToolMeta { name: "import_from_url", needs_db: true, write: true },
165 ToolMeta { name: "list_bm25_indexes", needs_db: true, write: false },
167 ToolMeta { name: "list_connections", needs_db: true, write: false },
169 ToolMeta { name: "list_database_privileges", needs_db: true, write: false },
171 ToolMeta { name: "list_databases", needs_db: true, write: false },
173 ToolMeta { name: "list_duplicate_indexes", needs_db: true, write: false },
175 ToolMeta { name: "list_extensions", needs_db: true, write: false },
177 ToolMeta { name: "list_indexes", needs_db: true, write: false },
179 ToolMeta { name: "list_partitions", needs_db: true, write: false },
181 ToolMeta { name: "list_replication_slots", needs_db: true, write: false },
183 ToolMeta { name: "list_role_memberships", needs_db: true, write: false },
185 ToolMeta { name: "list_schemas", needs_db: false, write: false },
187 ToolMeta { name: "list_standby_servers", needs_db: true, write: false },
189 ToolMeta { name: "list_tables", needs_db: false, write: false },
191 ToolMeta { name: "list_triggers", needs_db: true, write: false },
193 ToolMeta { name: "list_unused_indexes", needs_db: true, write: false },
195 ToolMeta { name: "list_user_privileges", needs_db: true, write: false },
197 ToolMeta { name: "list_users", needs_db: true, write: false },
199 ToolMeta { name: "list_vector_columns", needs_db: true, write: false },
201 ToolMeta { name: "reindex_database", needs_db: true, write: true },
203 ToolMeta { name: "reindex_table", needs_db: true, write: true },
205 ToolMeta { name: "rename_column", needs_db: true, write: true },
207 ToolMeta { name: "rename_index", needs_db: true, write: true },
209 ToolMeta { name: "rename_schema", needs_db: true, write: true },
211 ToolMeta { name: "rename_table", needs_db: true, write: true },
213 ToolMeta { name: "reset_statistics", needs_db: true, write: true },
215 ToolMeta { name: "revoke_privileges", needs_db: true, write: true },
217 ToolMeta { name: "sample_data", needs_db: true, write: false },
219 ToolMeta { name: "search_bm25", needs_db: true, write: false },
221 ToolMeta { name: "security_audit", needs_db: true, write: false },
223 ToolMeta { name: "show_active_transactions", needs_db: true, write: false },
225 ToolMeta { name: "show_all_settings", needs_db: true, write: false },
227 ToolMeta { name: "show_autocommit_status", needs_db: true, write: false },
229 ToolMeta { name: "show_base_backup_progress", needs_db: true, write: false },
231 ToolMeta { name: "show_blocked_queries", needs_db: true, write: false },
233 ToolMeta { name: "show_chunks", needs_db: true, write: false },
235 ToolMeta { name: "show_connection_summary", needs_db: true, write: false },
237 ToolMeta { name: "show_constraints", needs_db: false, write: false },
239 ToolMeta { name: "show_current_user", needs_db: true, write: false },
241 ToolMeta { name: "show_database_size", needs_db: true, write: false },
243 ToolMeta { name: "show_deadlocks", needs_db: true, write: false },
245 ToolMeta { name: "show_hypertable_details", needs_db: true, write: false },
247 ToolMeta { name: "show_locks", needs_db: true, write: false },
249 ToolMeta { name: "show_log_settings", needs_db: true, write: false },
251 ToolMeta { name: "show_memory_settings", needs_db: true, write: false },
253 ToolMeta { name: "show_performance_settings", needs_db: true, write: false },
255 ToolMeta { name: "show_replication_status", needs_db: true, write: false },
257 ToolMeta { name: "show_running_queries", needs_db: true, write: false },
259 ToolMeta { name: "show_session_info", needs_db: true, write: false },
261 ToolMeta { name: "show_table_size", needs_db: true, write: false },
263 ToolMeta { name: "show_transaction_isolation", needs_db: true, write: false },
265 ToolMeta { name: "show_transaction_timeout", needs_db: true, write: false },
267 ToolMeta { name: "show_vacuum_progress", needs_db: true, write: false },
269 ToolMeta { name: "show_waiting_locks", needs_db: true, write: false },
271 ToolMeta { name: "show_wal_info", needs_db: true, write: false },
273 ToolMeta { name: "suggest_indexes", needs_db: true, write: false },
275 ToolMeta { name: "table_dependencies", needs_db: true, write: false },
277 ToolMeta { name: "terminate_connection", needs_db: true, write: true },
279 ToolMeta { name: "truncate_table", needs_db: true, write: true },
281 ToolMeta { name: "vacuum", needs_db: true, write: true },
283 ToolMeta { name: "vacuum_analyze", needs_db: true, write: true },
285 ToolMeta { name: "vacuum_full", needs_db: true, write: true },
287 ToolMeta { name: "vector_search", needs_db: true, write: false },
289];
290
291#[inline]
292pub fn tool_exists(name: &str) -> bool {
293 ALL_TOOLS.binary_search_by(|t| t.name.as_bytes().cmp(name.as_bytes())).is_ok()
294}
295
296#[inline]
297pub fn is_write_tool(name: &str) -> bool {
298 ALL_TOOLS.binary_search_by(|t| t.name.as_bytes().cmp(name.as_bytes()))
299 .map(|i| ALL_TOOLS[i].write)
300 .unwrap_or(false)
301}
302
303#[inline]
304pub fn needs_db(name: &str) -> bool {
305 ALL_TOOLS.binary_search_by(|t| t.name.as_bytes().cmp(name.as_bytes()))
306 .map(|i| ALL_TOOLS[i].needs_db)
307 .unwrap_or(false)
308}
309
310#[cfg(test)]
311mod tests {
312 use super::*;
313
314 #[test]
315 fn test_all_tools_unique() {
316 let mut names: Vec<&str> = ALL_TOOLS.iter().map(|t| t.name).collect();
317 names.sort();
318 names.dedup();
319 assert_eq!(names.len(), ALL_TOOLS.len(), "Duplicate tool names in ALL_TOOLS");
320 }
321
322 #[test]
323 fn test_tool_exists_known() {
324 assert!(tool_exists("execute_query"));
325 assert!(tool_exists("list_tables"));
326 assert!(tool_exists("import_from_url"));
327 }
328
329 #[test]
330 fn test_tool_exists_unknown() {
331 assert!(!tool_exists("nonexistent_tool"));
332 }
333
334 #[test]
335 fn test_is_write_tool() {
336 assert!(is_write_tool("create_table"));
337 assert!(is_write_tool("import_from_url"));
338 assert!(!is_write_tool("execute_query"));
339 assert!(!is_write_tool("list_tables"));
340 }
341
342 #[test]
343 fn test_needs_db() {
344 assert!(needs_db("execute_query"));
345 assert!(!needs_db("list_tables"));
346 assert!(!needs_db("list_schemas"));
347 assert!(!needs_db("show_constraints"));
348 }
349
350 #[test]
351 fn test_all_tools_registered_in_tools_json() {
352 let content = std::fs::read_to_string("tools.json")
353 .expect("Failed to read tools.json");
354 let json: serde_json::Value = serde_json::from_str(&content)
355 .expect("tools.json is not valid JSON");
356 let json_tools = json.as_array().expect("tools.json must be an array");
357
358 let json_names: Vec<&str> = json_tools.iter()
359 .filter_map(|t| t.get("name").and_then(|n| n.as_str()))
360 .collect();
361
362 for meta in ALL_TOOLS {
363 assert!(
364 json_names.contains(&meta.name),
365 "Tool '{}' is in ALL_TOOLS but missing from tools.json",
366 meta.name,
367 );
368 }
369
370 for name in &json_names {
371 assert!(
372 tool_exists(name),
373 "Tool '{}' is in tools.json but missing from ALL_TOOLS",
374 name,
375 );
376 }
377
378 assert_eq!(json_names.len(), ALL_TOOLS.len(),
379 "tools.json has {} tools but ALL_TOOLS has {}",
380 json_names.len(), ALL_TOOLS.len());
381 }
382}