On this page#
What changes when an agent does this#
A sql mcp server lets an AI coding agent inspect database structure and execute permitted SQL through the Model Context Protocol. It removes the copy-and-paste bottleneck, but it moves risk into tool permissions, environment selection, and review discipline. The agent becomes faster; the database becomes easier to damage quietly.
MCP separates the agent-facing client from servers that expose tools and context, as described in the MCP architecture. That boundary is useful, but it is not a security boundary by itself. A tool named query can still expose everything its database credential can reach.
The right setup for a real repository has four properties:
- A repository-local configuration describes how to start the server.
- Credentials come from the environment or a secret manager, never committed files.
- The database role can read only the schemas and objects needed for the task.
- Mutation is performed through a separate, explicit path—not a general-purpose query tool.
Do not give the agent the same credential used by the application. That common shortcut is wrong. Application roles often have broader privileges than code investigation requires, and their permissions tend to expand over time.
A defensible repository configuration looks conceptually like this:
{
"mcpServers": {
"project-db-readonly": {
"command": "/absolute/path/to/sql-mcp-wrapper",
"args": ["--mode", "read-only"],
"env": {
"DATABASE_URL": "${PROJECT_DB_READONLY_URL}"
}
}
}
}The wrapper should fail closed if the variable is missing, reject non-read-only operations, and identify the selected environment before accepting a query. Reference servers in the official MCP servers repository can clarify the protocol shape, but a reference implementation is not your production permission model.
Photo by Christina Morillo on Pexels.
The prompt chain#
Use a staged prompt chain: establish scope, inspect evidence, propose a change, and only then prepare execution. One large prompt encourages the model to blur observations, assumptions, and actions. A large language model generates likely text from context; it does not acquire database intent merely because a tool call succeeds.
Stage 1: Fix the scope before querying#
Tell the agent exactly which repository question it is answering and prohibit mutation. This forces it to connect database inspection to a code-level decision instead of wandering through schemas and returning an impressive but irrelevant inventory.
Investigate why <repository behavior> occurs.
Use project-db-readonly only. Do not execute writes, DDL, migrations,
maintenance commands, or transaction-control statements.
First inspect the relevant code paths. Then list the minimum database
objects you need to examine. Before each query, state what uncertainty
the query resolves.“Minimum” matters. Without it, agents often inspect every related table because discovery is cheap. That increases exposure and fills the context window with columns, constraints, and sample values that do not affect the decision.
Stage 2: Separate facts from inference#
Require a compact evidence record. The agent must distinguish repository facts, database facts, and conclusions so a reviewer can identify where an unsupported leap entered the chain.
Return findings in three groups:
1. Repository facts, with file locations.
2. Database facts, with the exact read-only SQL used.
3. Inferences that connect those facts.
Mark anything not established by code or query output as unknown.
Do not propose a fix yet.For PostgreSQL behavior, verify assumptions against the PostgreSQL documentation rather than treating successful execution as proof of correct semantics. A query can run and still misunderstand null handling, locks, visibility, constraints, or transaction behavior.
Stage 3: Design the smallest change#
Ask for a patch plan that preserves explicit invariants. The important move is naming what must remain true; otherwise the agent optimizes for the visible symptom and may break an implicit contract elsewhere.
Propose the smallest repository change that explains and fixes the issue.
Preserve these invariants:
- <invariant>
- <invariant>
Include:
- files that would change;
- database assumptions the patch relies on;
- tests that prove each invariant;
- a rollback boundary.
Do not edit files or execute SQL.If your team needs a repeatable review structure for this stage, Review & Repair is the relevant PairFoundry workflow. The point is not more prompting; it is making evidence, invariants, and approval boundaries visible to the second engineer.
Stage 4: Produce an execution packet#
Have the agent prepare artifacts for review without applying them. The packet should contain the proposed code diff, migration text if required, validation queries, and an ordered rollback procedure.
Prepare an execution packet, but apply nothing.
Show:
1. the proposed diff;
2. any migration as a separate artifact;
3. pre-change validation queries;
4. post-change validation queries;
5. rollback steps;
6. every action that requires human approval.This staged approach fits the broader PairFoundry workflow library. Engineers who want the underlying habits before adopting a packaged workflow can start with the free foundations track.
The gate#
The human gate belongs between “execution packet” and “apply.” A reviewer must verify the target environment, effective database role, SQL scope, expected lock or transaction behavior, invariant coverage, and rollback path. Approval of the prose summary is insufficient; the reviewer must inspect the actual statements and proposed diff.
Stop and check these items:
- Identity: Which host, database, and role will receive the connection?
- Authority: What can that role actually read or change?
- Scope: Do the statements touch only named objects?
- Semantics: Does the SQL preserve constraints and application invariants?
- Operational effect: Could it block, scan, rewrite, or expose more than intended?
- Recovery: Is rollback executable without asking the same agent to reconstruct the previous state?
The MCP specification standardizes communication between participants. It does not certify that a tool is safe, that a server enforces read-only behavior, or that the reviewer selected the correct database.
For teams, commit a sanitized server definition and a short operating policy, but keep credentials outside the repository. Document which tool is allowed during investigation and which separate workflow owns migrations. Browse all PairFoundry workflow packs in the packs overview if the team needs a shared boundary beyond database work.
Photo by panumas nikhomkhai on Pexels.
What it gets wrong#
The most dangerous failures are plausible, internally consistent, and only partly grounded. They rarely look like random SQL. They look like a clean explanation built on the wrong environment, an incomplete schema model, misleading sample data, or a repository path that is no longer authoritative.
| Failure mode | How to recognize it | |---|---| | Wrong database | Object names look right, but expected rows, constraints, or recent migrations are absent. | | Privilege illusion | A query fails and the agent concludes an object does not exist instead of recognizing restricted visibility. | | Sample-to-rule leap | The explanation relies on observed rows rather than constraints or code-enforced invariants. | | Schema-only reasoning | The agent ignores application validation, background jobs, triggers, or migration order. | | Broad “read-only” access | The role cannot write but can still retrieve sensitive columns unrelated to the task. | | Semantic query drift | A later query answers a subtly different question from the uncertainty originally stated. | | Hidden mutation | A generic SQL tool accepts statements beyond the investigation policy. |
MCP’s client-server structure explains how capabilities reach the model, not whether those capabilities are appropriately narrow; review the architecture description with that distinction in mind.
A second engineer is most likely to stumble over undocumented local assumptions: a credential loaded by a shell profile, an absolute executable path, a server alias that differs between editors, or a “read-only” guarantee enforced only by prompt text. Put startup requirements and permission expectations beside the configuration. If safety exists only in the original author’s head, the setup is not team-ready.
Rollback#
Rollback starts before the first write: preserve the current repository state, capture the exact proposed SQL, define the reversal, and validate that the database change is actually reversible. If those conditions are missing, do not execute. Asking the agent to “undo what you did” is not a rollback plan.
Use this sequence:
- Disable the SQL MCP server or remove it from the active agent session.
- Revert the code change through the repository’s normal reviewed mechanism.
- Apply only the pre-reviewed database reversal, if one exists.
- Run the recorded validation queries.
- Re-check the named application invariants.
- Rotate the credential if it was exposed, mis-scoped, or used against the wrong environment.
- Correct the configuration and policy before reconnecting the tool.
Database rollback is not synonymous with reversing text. Data may have changed after a migration, and a reverse statement may destroy valid new state. Consult the PostgreSQL documentation for the actual database behavior involved, and prefer forward repair when reversal would discard information.
Photo by Christina Morillo on Pexels.
Related reading#
- API vs MCP — where the agent helps and where it quietly hurts
- Claude Code code review — where the agent helps and where it quietly hurts
FAQ#
Should a production database ever be connected to an AI coding agent?#
Only through a separately approved, narrowly scoped, read-only role when production evidence is genuinely necessary. The server should expose only required objects, omit unrelated sensitive columns, identify the environment clearly, and reject mutation independently of the prompt. If a sanitized replica answers the question, use that instead.
Is a read-only database role enough protection?#
No. Read-only access prevents one class of damage but does not prevent confidential data exposure, expensive queries, incorrect conclusions, or access to irrelevant schemas. Combine database grants, server-side statement restrictions, environment separation, timeouts where your system defines them, and a human review gate.
How is this different from following the official MCP setup?#
Official material explains protocol participants, capability exchange, and reference implementations. A repository integration must additionally define credential handling, object-level permissions, environment identity, review ownership, and recovery. Those operational controls are local engineering decisions; protocol compliance does not supply them.
What usually breaks when a second engineer uses the setup?#
Machine-specific paths, unshared environment variables, inconsistent server names, and undocumented permission assumptions break first. Commit a sanitized configuration plus a short runbook that names the required credential, expected role, permitted tools, prohibited actions, and approval gate. Never make prompt wording the only enforcement layer.
When should I avoid a sql mcp server entirely?#
Avoid it when the task can be resolved from migrations, fixtures, tests, or application code; when the available credential is broader than the investigation; when sensitive columns cannot be excluded; or when no reviewer can inspect the execution packet. Convenience is not a sufficient reason to widen database access.