The terminal and database dilemma
Developers increasingly rely on autonomous terminal agents such as Claude Code, Cursor, and Codex CLI to debug systems, generate migrations, and run administrative scripts.1
When coding agents have read-only access to source code, the risk is contained to git diffs that a human reviews before committing. However, as soon as an agent is configured with database connection strings or Model Context Protocol (MCP) servers that connect to PostgreSQL, MySQL, or cloud databases, the blast radius expands dramatically.
An agent tasked with debugging an authentication issue can easily decide to run TRUNCATE sessions, alter table constraints, or issue an UPDATE users SET status = 'active' without a WHERE clause.
Unlike code modifications, database writes take effect immediately. Once a table is truncated or an unconstrained update commits, git revert cannot help. If triggers or cascading foreign keys run during the transaction, the actual storage mutation often diverges from the agent’s stated intention.
Deedglass
A tool call meets your rules before it runs
Asks to run
DELETE FROM visits;
Deletes every row in visits
Deedglass checks your rules
- Reading dataAllowed
- Deleting a whole table (DROP, TRUNCATE)Never
- Changing or deleting rows without saying which (WHERE)This one
- Other changesWait for a person
Why auto-approve modes are dangerous
Autonomous coding tools frequently offer auto-approve flags or bypass options, such as --dangerously-skip-permissions or setting default mode to auto.4
While these flags eliminate interactive prompts during repetitive tasks, they remove the only checkpoint between an agent hallucination and persistent data loss.
Even when an agent appears to generate a safe query, database triggers, cascade relations, and foreign keys mean that deleting a single parent row can remove hundreds of related child records. Input text inspection alone cannot predict the storage-layer effect of a SQL statement.
Under default terminal settings, an autonomous agent executes commands under the developer’s credentials. When connected to a PostgreSQL database via an MCP server, that connection frequently uses superuser or table-owner permissions. Without explicit policy checks, the agent can drop schemas, overwrite production configurations, or alter access roles without human intervention.
Pattern 1: Wrap MCP database tools
The most reliable way to govern database operations in Claude Code and Cursor is placing a policy guard in front of the database MCP server.2
Instead of referencing the raw database MCP server directly in your configuration, wrap it with Deedglass:
Code Commands typed in a terminal. The text around it says what happens.
deedglass mcp wrap --connector db -- npx -y @modelcontextprotocol/server-postgres "postgresql://user:pass@localhost:5432/app"
In your Claude Code settings or Cursor mcpServers configuration, point the tool execution to the wrapped command. The agent retains full access to list tables, inspect schemas, and run permitted SELECT queries, while any mutation must pass policy evaluation.
When wrapped, Deedglass acts as a local interceptor between the LLM client and the underlying database server. It parses tool invocations before they reach the socket, decodes the SQL payload, and tests the target table against declarative Common Expression Language (CEL) conditions.
Pattern 2: Enforce CEL policy rules
With the MCP server wrapped, define explicit policies in deedglass: policy/v1 format using Common Expression Language (CEL) conditions:
Code A settings file: the rules a tool reads before it acts.
deedglass: policy/v1
name: developer-database-guard
description: "Protect development and staging databases from destructive autonomous writes."
defaults:
decision: deny
reason: "No rule matched this action. Set an explicit rule in your policy."
rules:
# Allow all read queries
- id: allow-selects
match: { tool: "db.query", connector_type: mcp }
when: "sql.kind == 'select'"
decision: allow
reason: "Read-only queries are permitted without interactive holds."
# Require human approval for updates and deletes
- id: hold-writes
match: { tool: "db.query", connector_type: mcp }
when: "sql.kind in ['update', 'delete']"
decision: require_approval
reason: "Database mutations require human confirmation before execution."
approval: { approvers: [role:admin], required: 1, expires_in: 15m }
# Block destructive DDL completely
- id: block-drops
match: { tool: "db.query", connector_type: mcp }
when: "sql.kind in ['drop', 'truncate', 'alter']"
decision: deny
reason: "Destructive DDL is blocked for autonomous coding agents."
When Claude Code or Cursor attempts an unconstrained write, Deedglass intercepts the tool call, displays the SQL statement and target tables, and holds execution until a developer confirms the action.
If an agent attempts to drop a table or run an unauthorized administrative script, the call is rejected immediately with an explanatory error code returned to the agent context. The agent can then reconsider its approach or request explicit developer elevation rather than silently executing dangerous commands.
Pattern 3: Logical decoding verification
For PostgreSQL environments with wal_level=logical, Deedglass provides change log verification by reading PostgreSQL’s write-ahead log directly through logical decoding.3
Code What the screen or file shows, copied as is.
[ Claude Code / Cursor ]
│
▼ (MCP Tool Call)
[ Deedglass Policy Engine ] ──► (Evaluates CEL Rule: Allow / Hold / Deny)
│
▼ (Authorized SQL Execution)
[ PostgreSQL Database ]
│
▼ (Logical Decoding / WAL Output)
[ Deedglass Verifier ] ──► (Compares Claimed Row Count vs Committed WAL Diffs)
│
▼
[ Sealed Record (Ed25519) ]
When an agent claims that an update modified 1 row, Deedglass checks the committed transaction log.3 If a trigger silently modified 301 rows, Deedglass flags the mismatch and allows a developer to roll the affected rows back after countersigning the undo.
Because logical decoding reads directly from the database engine’s storage log, it cannot be spoofed by an agent crafting deceptive status strings. Even if the agent reports that an operation succeeded cleanly, the verifier inspects the exact row deltas emitted by the storage layer before marking the verification complete.
Testing unconstrained writes in the playground
Before applying policies to production databases, developers can experiment with simulated agent actions in the Deedglass interactive playground.
The playground provides an interactive environment running an in-browser SQLite database and simulated change log. You can feed an agent prompt such as an unconstrained update, view the parsed SQL AST, observe how CEL policy rules evaluate the mutation, and watch the verifier catch the mismatch between expected and actual row modifications.
Running these scenarios in the playground allows engineering teams to design tight policy rules without risking live application data or setting up local test containers.
Configuring Cursor and Claude Code
Setting up Deedglass with your daily developer tools requires only updating your MCP configuration files.
For Cursor, edit .cursor/mcp.json in your workspace root:
Code Data in JSON, the format software uses to pass records and settings.
{
"mcpServers": {
"postgres": {
"command": "deedglass",
"args": [
"mcp",
"wrap",
"--connector",
"db",
"--",
"npx",
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://developer@localhost:5432/development_db"
]
}
}
}
For Anthropic Claude Code, edit your project configuration or global settings file at ~/.claude.json:
Code Data in JSON, the format software uses to pass records and settings.
{
"mcpServers": {
"postgres": {
"command": "deedglass",
"args": [
"mcp",
"wrap",
"--connector",
"db",
"--",
"npx",
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://developer@localhost:5432/development_db"
]
}
}
}
Once configured, restart your coding assistant session. Every database tool call initiated by the assistant will route through the Deedglass wrapper. Read operations continue uninterrupted, while write and schema operations display clear approval dialogs with parsed SQL targets.
Measuring blast radius with the scan
To check your local coding setup before running agents against real data, run the local scanner:4
Code Commands typed in a terminal. The text around it says what happens.
npx deedglass scan --postgres-dsn-env DATABASE_URL
The scanner runs locally on your machine, evaluates your Cursor and Claude Code configurations, checks role attributes (such as superuser status or BYPASSRLS), and calculates your blast radius grade from A to F based on open write paths.4
If your agent runs with superuser privileges or if auto-approval flags are active without policy rules in place, the scan warns you before an incident occurs.
Verifying records offline
Every action permitted through Deedglass is sealed into a hash-linked chain with an Ed25519 signature.2
Anyone with the public key can verify the integrity of the execution record offline without connecting to a remote server:
Code Commands typed in a terminal. The text around it says what happens.
deedglass verify action.deed.jsonl --public-key key.pub
This creates an immutable audit trail for team leads, security officers, and internal reviews, recording exactly which agent ran, what statement was executed, who approved it, and what row changes PostgreSQL committed to disk.
Written with AI assistance and checked against our claims register.