Database Tool
Configure database tools to let your AI agent query and update data in your databases.
Overview
The Database tool enables your AI agent to interact with your databases - querying data, inserting records, updating information, and more. This powerful tool connects your agent to live data while maintaining security and access control.
Supported Databases
| Database | Type | Status |
|---|---|---|
| PostgreSQL | Relational | Full Support |
| MySQL | Relational | Full Support |
| MariaDB | Relational | Full Support |
| SQLite | Relational | Full Support |
| MongoDB | Document | Full Support |
| Redis | Key-Value | Read Support |
| Supabase | PostgreSQL | Full Support |
| PlanetScale | MySQL | Full Support |
Configuration
Database Connection
First, create a database connection in your Credentials Vault:
json{ "name": "production_db", "type": "postgresql", "config": { "host": "db.example.com", "port": 5432, "database": "myapp", "username": "agent_user", "password": "{{vault.db_password}}", "ssl": true } }
Basic Database Tool
json{ "name": "lookup_customer", "type": "database", "description": "Look up customer information by email or ID", "config": { "connection": "production_db", "operation": "select", "table": "customers", "columns": ["id", "name", "email", "plan", "created_at"], "where": { "or": [ { "email": "{{parameters.email}}" }, { "id": "{{parameters.customer_id}}" } ] } }, "parameters": { "type": "object", "properties": { "email": { "type": "string", "description": "Customer email address" }, "customer_id": { "type": "string", "description": "Customer ID" } } } }
Operations
SELECT (Query)
json{ "config": { "operation": "select", "table": "orders", "columns": ["id", "status", "total", "created_at"], "where": { "customer_id": "{{parameters.customer_id}}", "status": "{{parameters.status}}" }, "order_by": [ { "column": "created_at", "direction": "desc" } ], "limit": 10 } }
Advanced Filtering
json{ "where": { "and": [ { "status": { "in": ["pending", "processing"] } }, { "created_at": { "gte": "{{parameters.start_date}}" } }, { "total": { "gt": 100 } } ] } }
Operators:
| Operator | Description | Example |
|---|---|---|
eq | Equal (default) | {"status": "active"} |
ne | Not equal | {"status": {"ne": "deleted"}} |
gt | Greater than | {"amount": {"gt": 100}} |
gte | Greater or equal | {"date": {"gte": "2025-01-01"}} |
lt | Less than | {"age": {"lt": 18}} |
lte | Less or equal | {"priority": {"lte": 3}} |
in | In list | {"status": {"in": ["a", "b"]}} |
like | Pattern match | {"name": {"like": "%john%"}} |
is_null | Is NULL | {"deleted_at": {"is_null": true}} |
INSERT
json{ "name": "create_note", "type": "database", "description": "Create a note for a customer", "config": { "operation": "insert", "table": "customer_notes", "values": { "customer_id": "{{parameters.customer_id}}", "content": "{{parameters.note}}", "created_by": "agent", "created_at": "{{now}}" }, "returning": ["id", "created_at"] }, "parameters": { "type": "object", "properties": { "customer_id": { "type": "string" }, "note": { "type": "string" } }, "required": ["customer_id", "note"] } }
UPDATE
json{ "name": "update_ticket_status", "type": "database", "description": "Update a support ticket's status", "config": { "operation": "update", "table": "tickets", "set": { "status": "{{parameters.new_status}}", "updated_at": "{{now}}", "updated_by": "agent" }, "where": { "id": "{{parameters.ticket_id}}" }, "returning": ["id", "status", "updated_at"] }, "parameters": { "type": "object", "properties": { "ticket_id": { "type": "string" }, "new_status": { "type": "string", "enum": ["open", "in_progress", "resolved", "closed"] } }, "required": ["ticket_id", "new_status"] } }
DELETE
json{ "name": "delete_draft", "type": "database", "description": "Delete a draft document", "config": { "operation": "delete", "table": "documents", "where": { "id": "{{parameters.document_id}}", "status": "draft" }, "returning": ["id"] }, "parameters": { "type": "object", "properties": { "document_id": { "type": "string" } }, "required": ["document_id"] } }
Raw SQL (Advanced)
For complex queries, use raw SQL with parameterized queries:
json{ "name": "sales_report", "type": "database", "description": "Generate sales report for a date range", "config": { "operation": "raw", "query": "SELECT DATE(created_at) as date, COUNT(*) as orders, SUM(total) as revenue FROM orders WHERE created_at BETWEEN $1 AND $2 AND status = 'completed' GROUP BY DATE(created_at) ORDER BY date DESC", "params": [ "{{parameters.start_date}}", "{{parameters.end_date}}" ] }, "parameters": { "type": "object", "properties": { "start_date": { "type": "string", "format": "date", "description": "Start date (YYYY-MM-DD)" }, "end_date": { "type": "string", "format": "date", "description": "End date (YYYY-MM-DD)" } }, "required": ["start_date", "end_date"] } }
Joins and Relations
Simple Join
json{ "config": { "operation": "select", "table": "orders", "columns": [ "orders.id", "orders.total", "customers.name as customer_name", "customers.email" ], "joins": [ { "table": "customers", "on": "orders.customer_id = customers.id" } ], "where": { "orders.status": "pending" } } }
Multiple Joins
json{ "config": { "operation": "select", "table": "order_items", "columns": [ "orders.id as order_id", "products.name as product_name", "order_items.quantity", "order_items.price" ], "joins": [ { "table": "orders", "on": "order_items.order_id = orders.id" }, { "table": "products", "on": "order_items.product_id = products.id" } ] } }
Aggregations
json{ "name": "customer_stats", "type": "database", "description": "Get statistics for a customer", "config": { "operation": "select", "table": "orders", "columns": [ { "raw": "COUNT(*)", "as": "total_orders" }, { "raw": "SUM(total)", "as": "total_spent" }, { "raw": "AVG(total)", "as": "average_order" }, { "raw": "MAX(created_at)", "as": "last_order" } ], "where": { "customer_id": "{{parameters.customer_id}}", "status": "completed" } } }
MongoDB Support
Find Documents
json{ "name": "find_products", "type": "database", "config": { "connection": "mongodb_prod", "operation": "find", "collection": "products", "filter": { "category": "{{parameters.category}}", "price": { "$lte": "{{parameters.max_price}}" } }, "projection": { "name": 1, "price": 1, "description": 1 }, "sort": { "price": 1 }, "limit": 20 } }
Insert Document
json{ "config": { "operation": "insertOne", "collection": "logs", "document": { "event": "{{parameters.event}}", "data": "{{parameters.data}}", "timestamp": { "$date": "{{now}}" } } } }
Update Document
json{ "config": { "operation": "updateOne", "collection": "users", "filter": { "_id": "{{parameters.user_id}}" }, "update": { "$set": { "preferences": "{{parameters.preferences}}", "updated_at": { "$date": "{{now}}" } } } } }
Security
Read-Only Access
Restrict to SELECT operations:
json{ "security": { "allowed_operations": ["select"], "max_rows": 100 } }
Table Allowlist
Limit accessible tables:
json{ "security": { "allowed_tables": [ "customers", "orders", "products" ], "denied_tables": [ "users", "api_keys", "payments" ] } }
Column Masking
Hide sensitive columns:
json{ "security": { "masked_columns": { "customers": ["ssn", "credit_card"], "users": ["password_hash", "api_key"] } } }
Row-Level Security
Filter by tenant:
json{ "security": { "row_filter": { "tenant_id": "{{context.tenant_id}}" } } }
Best Practices
1. Use Parameterized Queries
Never concatenate user input:
json// Good - Parameterized { "where": { "email": "{{parameters.email}}" } } // Bad - String concatenation { "raw_query": "SELECT * FROM users WHERE email = '" + email + "'" }
2. Limit Results
Always set limits to prevent large result sets:
json{ "config": { "limit": 50, "max_limit": 100 } }
3. Use Indexes
Ensure WHERE clause columns are indexed:
sqlCREATE INDEX idx_orders_customer_id ON orders(customer_id); CREATE INDEX idx_orders_status ON orders(status);
4. Minimal Permissions
Create a dedicated database user with minimal permissions:
sqlCREATE USER agent_user WITH PASSWORD 'secure_password'; GRANT SELECT ON customers, orders, products TO agent_user; GRANT INSERT ON customer_notes TO agent_user; REVOKE ALL ON users, api_keys FROM agent_user;
5. Audit Logging
Enable query logging:
json{ "logging": { "log_queries": true, "log_parameters": false, "log_results": false } }
Testing
Test Query
bashcurl -X POST "https://api.arcanflows.com/api/v1/agents/{agent_id}/tools/{tool_id}/test" \ -H "X-API-Key: your_api_key" \ -H "Content-Type: application/json" \ -d '{ "parameters": { "customer_id": "cust_123" }, "dry_run": true }'
Dry Run Mode
Preview the query without executing:
json{ "test_options": { "dry_run": true, "explain": true } }
Troubleshooting
Connection Errors
- Verify database credentials
- Check network connectivity/firewall
- Confirm SSL settings
Query Timeouts
- Add appropriate indexes
- Reduce result set size
- Optimize query structure
Permission Denied
- Check user permissions
- Verify table access
- Review row-level security
Data Type Errors
- Match parameter types to column types
- Handle NULL values appropriately
- Use proper date/time formats