MCP Database Access: What "Read-Only" Must Actually Block (Hosted Gateway vs Self-Hosted)
· AI2SQL
Teams treat “read-only MCP” as the finish line. For production agent SQL, it is the floor.
A SELECT-only Postgres role plus a local Postgres MCP server is fine for a scratch database. It is not a complete answer to “is this actually safe?” once Cursor, Claude, or a custom agent can generate and run SQL against real data. This page is a threat-model checklist of what “read-only” must still block, then a neutral decision between hosted governed MCP / SQL gateway and self-hosted / raw Postgres MCP. For a short definition of the category, see What is a database MCP server?.
What “MCP database access” means for Cursor, Claude, and agents
MCP database access means an AI client talks to your database through the Model Context Protocol. The MCP server (or hosted gateway) exposes tools — typically schema inspection and query execution — so the model can ask for table shapes and run SQL without you pasting dumps into chat.
Cursor, Claude Code, Claude Desktop, ChatGPT with developer-mode MCP, and custom agents that speak MCP over HTTP are the usual clients. The model’s intentions are not a security boundary. Safety lives in the database role, the MCP server or gateway that sits in front of it, and the ops controls around credentials, limits, audit, and revoke.
The default advice (and why production teams outgrow it)
The default SERP and assistant answer is familiar: create a SELECT-only role (often with statement_timeout), put DATABASE_URL in env or .cursor/mcp.json, run something like @modelcontextprotocol/server-postgres via npx, enable MCP, verify SELECT works and INSERT fails.
That path is legitimate for local and throwaway databases. Least privilege at the role is the right first step. Production teams outgrow it when they need enforceable statement policy, blocking of dangerous functions inside SELECT, credentials that are not copied onto every laptop, bounded reads, an audit trail, and a kill switch for one agent without rotating the database password.
This page starts where that default answer stops.
Threat model: what “read-only” must actually block
Think in terms of classes of harm: prompt injection that steers tool use, confused or overprivileged tokens, and honest mistakes from a model that invents a destructive statement. “Read-only” only holds if each class below is blocked or bounded — not merely discouraged in a prompt.
Writes, DDL, and multi-statement / transaction tricks
Block INSERT, UPDATE, DELETE, MERGE, and DDL such as DROP, ALTER, TRUNCATE, and CREATE. Also watch for multi-statement or transaction patterns that try to escape a naïve “starts with SELECT” string check.
A read-only transaction alone is not enough. The archived official Postgres MCP server shipped a documented SQL-injection style bypass of its read-only transaction — already discussed on AI2SQL’s safety pages and industry write-ups such as Datadog Security Labs. Defense in depth means classify the statement before it runs, then still execute inside a read-only transaction. For the layer-by-layer version of that argument, see How to give an AI agent read-only database access.
Dangerous functions inside an otherwise valid SELECT
Statement type alone ≠ safe. Dialects expose functions that read files, talk to the network or another database, shell out, or sleep long enough to DoS a connection pool. A SELECT that calls those functions is still a SELECT.
The deep dialect list belongs on Read-only database MCP is not actually read-only. The checklist item here is simpler: if your path only checks statement type, assume dangerous functions are still open until you prove otherwise.
Credential exposure and confused-deputy / overprivileged tokens
Pasting a production DSN into every developer’s mcp.json spreads the database password to every laptop that runs the agent. The agent (or anything that can use that config) then holds the same secret as a DBA connection string.
A better pattern: the database password stays in a vault or server-side store; the agent holds a scoped, revocable key to a gateway or hardened server. Overprivileged tokens and confused-deputy failure modes are covered in more depth in MCP confused deputy / overprivileged tokens.
Unbounded reads and agent loops
Read-only does not stop a full-table scan storm. Cap rows, set statement timeouts, and bound connection or call rates. An agent in a loop can still hurt availability and cost without ever writing a row.
No attribution, no kill switch
Without an audit log keyed by agent identity, you cannot answer “what did the agent run?” Without per-agent revocation, stopping one misbehaving client means rotating the shared database password and breaking everyone else. Attribution and a kill switch are part of “read-only for agents,” not nice-to-haves.
Hosted governed MCP / SQL gateway vs self-hosted / raw Postgres MCP
Same core job: expose schema and query tools over MCP. Different everything around the connection. Stay honest about both sides — the longer head-to-head is AI2SQL Gateway vs a raw Postgres MCP server, and the wider field is in Postgres MCP server options compared (2026).
Self-hosted / raw: when it wins
Self-hosted wins when data must never leave your network. OSS servers are free. Multi-engine options such as DBHub cover Postgres, MySQL, SQL Server, MariaDB, and SQLite. Postgres MCP Pro adds index-health and performance tooling that a pure access gateway does not try to replace.
You own the lockdown: dedicated role, parser or classifier if the server has one, timeouts, your own logging, your own patching. Hardened OSS READMEs (AST checks, grant-aware modes, credentials kept out of chat) are real options when residency or self-operation is the priority.
Hosted governed gateway: when it wins
A hosted governed MCP SQL gateway wins when you want zero ops: connect the database, mint a key, paste one MCP config. Statement classification plus a read-only transaction, vaulted credentials, per-agent keys, query audit, and metering come as the product.
Honest costs: queries and results transit the vendor. AI2SQL Gateway is PostgreSQL-first today (MySQL rolling out). It is not a substitute for air-gapped requirements. If residency is non-negotiable, self-host.
Side-by-side control checklist
| Must block / control | Typical raw / local MCP setup | Hardened self-hosted (OSS with AST / grants) | Hosted governed gateway (e.g. AI2SQL Gateway) |
|---|---|---|---|
| Writes / DDL | Depends on DB role; many servers run whatever SQL the model produces | Often GRANT + optional AST / classifier — you configure and verify | Classify before run + read-only transaction |
| Dangerous functions inside SELECT | Usually not blocked unless you add it | Possible if the server’s policy / AST covers them — confirm per project | Blocked at gateway as part of classification |
| Credentials on every laptop | Common: DSN in mcp.json / env | You can keep secrets in your vault / sidecars — still your design | DB password vaulted server-side; agent holds revocable key |
| Row caps / timeouts | Often only what you set on the role or server | You set and operate them | Built-in row cap and statement timeout |
| Audit by agent key | Usually absent | You wire logging yourself | Every tool call logged with key and outcome |
| Instant revoke of one agent | Rotate shared DSN / restart configs | Depends on how you issued tokens | Revoke or rotate one API key |
| Ops burden | Low day-one, weak defaults | You run, patch, and secure the process | Hosted; no local MCP process for the DB path |
| Data residency | Stays in your network if the server does | Stays in your network | Queries transit vendor — disqualifying if air-gap is required |
How to verify “read-only” before you trust it
Do not trust a README claim. Run an adversarial mini-suite against a replica or throwaway database first:
- Attempt a write and a DDL statement — both must fail closed.
- Attempt a SELECT that calls a dangerous function for your dialect (for Postgres, something in the spirit of
pg_read_fileor a dialect twin) — must be rejected if your policy claims to block it. - Attempt a long sleep or an unbounded scan — timeout and row cap must fire.
- Confirm the audit log (or your logging stack) captured the attempts and the key or identity that made them.
Buyer guides such as Pondero’s Postgres MCP lockdown checklist push the same mindset: treat lockdown as something you test, not something you assume. Prefer a replica for the first evaluation.
Where AI2SQL Gateway fits
Map the checklist to the hosted path without rewriting the product page:
- Classify every statement before run; block writes, DDL, and dangerous functions.
- Execute inside a read-only transaction as a second layer.
- Apply row caps and statement timeouts.
- Keep connection credentials encrypted server-side; agents authenticate with revocable keys.
- Expose MCP tools
run_query,describe_schema, andlist_connections. - Log each tool call with the SQL, key, and outcome.
PostgreSQL is live on the gateway today; MySQL is rolling out. Roadmap items such as table-level allowlists and approval flows are called out on the product page — do not treat them as shipped until they are.
CTA: AI2SQL Gateway — connect database → key → one MCP config. If you are air-gapped or must self-host, use the comparison and matrix pages above instead of forcing a hosted path.
For the production narrative beyond this checklist, see Let an AI agent query a production database safely. For the risk FAQ framing, see Is it safe to connect AI to a database?.
What is MCP database access?
MCP database access is agent tooling that lets Cursor, Claude, ChatGPT, or a custom agent inspect schema and run SQL through Model Context Protocol tools. It is not automatic safety. A serious path combines a least-privilege database role with statement classification, limits, credential isolation, audit, and revoke — whether you assemble those layers yourself on a self-hosted Postgres MCP server or buy them as a hosted governed MCP SQL gateway.
FAQ
How do I give Cursor or Claude safe read-only access to Postgres?
Safe MCP database access means the agent never holds your database password and cannot run destructive SQL. Use a dedicated SELECT-only role (ideally on a replica), connect through an MCP server or hosted MCP SQL gateway that classifies statements before execution, blocks writes/DDL and dangerous functions, caps rows and timeouts, and logs every query under a revocable key. Local “paste DATABASE_URL into mcp.json” setups can work for scratch databases; for production, prefer a governed path you can audit and kill instantly.
Is read-only MCP enough for an AI agent on a production database?
No — read-only is necessary but not sufficient. A SELECT-only role stops many writes, but it does not by itself block dangerous functions inside SELECT, stop expensive full-table scans, keep credentials off every laptop, or give you per-agent revocation and an audit trail. Treat “read-only MCP” as the floor: add statement classification, resource limits, credential isolation, logging, and a kill switch before production.
Hosted governed MCP SQL gateway vs self-hosted / raw Postgres MCP — which should I use?
Choose self-hosted or raw Postgres MCP when data must stay in your network, you want free OSS multi-engine or DBA tooling, and your team will operate lockdown (roles, timeouts, audit) yourselves. Choose a hosted governed MCP SQL gateway when you want zero ops, statement-aware read-only, vaulted credentials, revocable per-agent keys, and query audit by default — accepting that queries transit the vendor. AI2SQL Gateway is the hosted path; hardened OSS servers remain valid when residency or self-operation is the priority.
How should a team test that “read-only” holds?
On a replica: attempt writes and DDL, attempt dangerous-function SELECTs, attempt sleep or unbounded reads, and confirm audit captured the attempts. Fail closed on each. If any step succeeds, the path is not ready for production data.
Does “MCP database access” require Cursor specifically?
No. MCP is the bridge. Cursor, Claude Code / Desktop, ChatGPT developer-mode MCP, and custom HTTP MCP clients can all use the same kind of server or gateway. Client setup guides live on the product pages; this article is the threat model and decision, not another install walkthrough.
Connect a database, mint a key, paste one MCP config when the hosted path fits: AI2SQL Gateway. For the six layers of real read-only, start with AI read-only database access. For risk framing, see Is it safe to connect AI to a database?. If air-gap wins, self-host — and pick from the comparison and matrix links above.