Code and dense tables are folded away. Open any of them on demand.
Example check
A user asked for last month’s cancelled orders; the agent proposed a DELETE on production.
Show it as a curl commandHide technical details· shell
What can go wrong with a database agent
A text-to-SQL or data-ops agent turns a request into statements and runs them. The failure modes are well known:
DROP TABLEorTRUNCATEwhile "cleaning up" a schema.DELETE FROM ordersorUPDATE users SET plan = 'free'with a missing or too-broadWHEREclause.- The right statement against the wrong database: production instead of staging.
SELECT email, phone FROM customerswith no limit, followed by a tool call that writes the result to a file or sends it somewhere (data exfiltration).- Statements proposed after reading a cell or a comment that contained instructions (indirect prompt injection).
What to send the guard
Check each statement before execution:
action:{ tool: "sql.execute", args: { database: "prod", sql: "DELETE FROM orders" } }.intent: the user’s question or task.constraints: rules such as "read-only on prod" or "never export more than 100 rows of customer data".context: the environment, the role the agent connects with and what the tables contain.trigger:tool_resultwhen the statement was proposed after reading query results.
Including the environment in context matters: the same TRUNCATE is routine on a scratch schema and serious on production.
Acting on the verdict
By default the server returns block when P(unsafe) is at least 0.8 or the approval_policy head says reject, ask when P(unsafe) is at least 0.3, the policy head says require_human, or args_grounded is below 0.5, and allow otherwise. You can ignore the default verdict and apply your own thresholds to the scores.
For database agents the useful scores are destructive (data removed or overwritten), blast_radius (read-only, local or reversible write, or production-mutating), exfiltration (personal data leaving where it should), scope_violation via the violation head (acting outside the stated task) and args_grounded (a table name or id the user never mentioned). A common policy: auto-run reads that match the question, ask a human before any production write, block schema drops outright.
Controls to keep alongside the guard
Database permissions are the strongest control you have, and they are deterministic:
- Connect the agent with a read-only role by default; grant write roles per task.
- Point analytical questions at a read replica.
- Keep point-in-time recovery and tested backups.
- Enforce a statement timeout and row limits at the connection level.
The guard reduces risk in the gap between what the role allows and what the user actually asked for. It does not guarantee a bad statement is caught, so the recovery path still matters. See blast radius and reversibility.
Frequently asked questions
Should I send query results to the guard?
Can the guard parse SQL exactly?
Sources
Last updated . MCP Guard reduces the risk of harmful agent actions; it does not guarantee safety. Keep deterministic controls in place alongside it. Third-party names are used only to describe their products; we are not affiliated with them.