How DBX Performs AI-Driven SQL Generation with Built-in Safety Checks
DBX uses a dedicated AI skill to generate SQL via LLM prompts and enforces read-only safety checks through a centralized sqlSafetyFromEnv evaluator that blocks dangerous keywords and multi-statements unless explicitly overridden by environment variables.
The DBX project (t8y2/dbx) implements a secure AI-driven SQL generation system that prevents accidental data destruction while maintaining flexibility for power users. By combining structured prompt engineering with a centralized safety evaluator, DBX ensures that generated SQL never executes destructive operations without explicit user consent.
The AI Skill Architecture for SQL Generation
DBX ships a dedicated AI skill for the generate action. When users request query generation through the CLI, desktop UI, or an AI-agent, the system constructs a system prompt that instructs the LLM to return a single fenced SQL code block containing the statement.
Prompt Engineering and the Generate Skill
In apps/desktop/src/lib/ai/aiSkills.ts, the skill definition builds prompts that require the model to output strictly formatted SQL within triple-backtick blocks. This structured approach ensures predictable parsing while the accompanying risk policy (readonly_preferred) signals the system's security posture to downstream components. The skill can be invoked via aiSkillForAction('generate'), which returns the configuration used by executeAiSkill to orchestrate the LLM call.
The SQL Safety Evaluation Pipeline
Before any generated SQL executes, DBX runs the SQL safety evaluator (sqlSafetyFromEnv) defined in packages/node-core/src/sql-safety.ts. This centralized function enforces four critical policies that apply universally across the codebase.
Read-Only Default Policy
By default, DBX operates in read-only mode. The evaluator returns "MCP SQL execution is read-only for this session. Set DBX_MCP_ALLOW_WRITES=1 to allow write statements." whenever a write operation is detected in a session not explicitly authorized for mutations.
Dangerous Keyword Detection
The system maintains a blocklist of destructive operations. If the generated SQL contains keywords such as DROP, DELETE, ALTER, or TRUNCATE, the evaluator immediately returns "Dangerous SQL keyword \"DROP\" is blocked." (or the specific keyword detected), halting execution before the query reaches the database.
Multi-Statement Restrictions
DBX prohibits multiple SQL statements within a single query to prevent injection-style attacks or unintended chained operations. Attempting to submit multiple statements returns "Only one SQL statement is allowed per query." unless explicitly overridden.
Environment-Controlled Overrides
Power users can bypass restrictions using environment variables parsed via parseBooleanEnv:
DBX_MCP_ALLOW_WRITES=1— Permits write operations while maintaining other safety checksDBX_MCP_ALLOW_DANGEROUS_SQL=1— Allows dangerous keywords and multi-statement blocks
When these variables are set, the safety layer relaxes the corresponding checks but continues to surface clear warnings to the user.
Safety Enforcement Across All Execution Paths
The sqlSafetyFromEnv check is invoked everywhere DBX may execute SQL, ensuring consistent policy enforcement regardless of the entry point.
MCP Server Endpoint Protection
In packages/mcp-server/src/index.ts, the dbx_execute_query endpoint passes every request through the safety evaluator before execution. If the check returns allowed: false, the server responds with a structured error object containing code: "SQL_BLOCKED" and the specific safety violation message, preventing the query from reaching the database driver.
CLI Safety Integration
The CLI implementation in packages/cli/src/cli.ts runs the same safety routine before transmitting queries to the backend. When a check fails, the CLI prints a JSON error to stderr with code: "SQL_BLOCKED", allowing scripts to programmatically detect and handle safety violations.
AI-Agent Auto-Execution Logic
For AI-agent workflows, the runner evaluates safety results before auto-executing generated SQL. As implemented in the test suite at packages/app-tests/aiAgentStepPresentation.test.ts, when allowed is false, the agent falls back to "show-only" mode, displaying the generated SQL and the safety reason without executing it. Only when allowed is true does the agent proceed with automatic execution.
Working with DBX SQL Generation
Generate SQL from the CLI (Read-Only Default)
$ dbx generate "show me the top 10 customers by order total"
Result (stdout):
SELECT c.id, c.name, SUM(o.amount) AS total
FROM customers c
JOIN orders o ON o.customer_id = c.id
GROUP BY c.id, c.name
ORDER BY total DESC
LIMIT 10;
Attempt a Dangerous Write Without Override
$ dbx generate "delete all rows from users"
Result (stderr):
{
"error": {
"code": "SQL_BLOCKED",
"message": "Dangerous SQL keyword \"DELETE\" is blocked."
}
}
Enable Dangerous SQL via Environment Variable
$ DBX_MCP_ALLOW_DANGEROUS_SQL=1 dbx generate "delete all rows from users"
With this flag, the SQL is returned and the CLI proceeds to execute it if the --run flag is supplied.
AI-Agent Auto-Execution (Generate Mode)
import { executeAiSkill } from '@/lib/ai/ai';
const result = await executeAiSkill('generate', 'show me revenue per region');
if (result.type === 'sql' && result.safety.allowed) {
// DBX will automatically run the query and display the result.
}
The executeAiSkill function internally calls aiSkillForAction('generate'), builds the prompt, receives the LLM response, then runs sqlSafetyFromEnv before any database execution occurs.
Summary
- DBX generates SQL through a dedicated AI skill defined in
apps/desktop/src/lib/ai/aiSkills.tsthat instructs LLMs to return fenced SQL code blocks. - The
sqlSafetyFromEnvevaluator inpackages/node-core/src/sql-safety.tsenforces read-only defaults and blocks dangerous keywords likeDROPandDELETE. - Multi-statement queries are prohibited unless
DBX_MCP_ALLOW_DANGEROUS_SQL=1is set. - Safety checks run in the MCP server (
packages/mcp-server/src/index.ts), CLI (packages/cli/src/cli.ts), and AI-agent execution paths, returning structuredSQL_BLOCKEDerrors when violated. - The risk policy
readonly_preferredensures generated SQL defaults to safe, read-only operations while allowing explicit user overrides.
Frequently Asked Questions
What happens if DBX generates a DROP statement?
The safety evaluator detects the dangerous keyword and returns a structured error with code SQL_BLOCKED, preventing execution unless DBX_MCP_ALLOW_DANGEROUS_SQL=1 is explicitly configured in the environment.
How do I enable write operations in DBX?
Set the environment variable DBX_MCP_ALLOW_WRITES=1 to allow write statements for the session. To bypass all restrictions including multi-statement blocks, set DBX_MCP_ALLOW_DANGEROUS_SQL=1, though this requires explicit acknowledgment of the security risks.
Can DBX execute multiple SQL statements in one query?
By default, no. The system restricts queries to single statements to prevent injection attacks. Enable multi-statement support by setting DBX_MCP_ALLOW_DANGEROUS_SQL=1, though this is strongly discouraged for production environments.
Where is the safety check implemented in the codebase?
The core logic resides in packages/node-core/src/sql-safety.ts as the sqlSafetyFromEnv function. This module is imported and invoked by the MCP server entry point (packages/mcp-server/src/index.ts), the CLI handler (packages/cli/src/cli.ts), and the AI-agent runner components.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →