How to Connect PostgreSQL to Claude — Safely
Claude can answer questions about your data the moment it can query your database. The wrong way is handing an agent a raw connection string. The right way takes five minutes and gives you read-only access, approvals for writes and a full audit trail.
list_tables, describe_table and query (SELECT-only) — over standard MCP. No code, no custom MCP server.Why you shouldn't connect Claude to Postgres directly
Model Context Protocol (MCP) is how Claude talks to external systems. There are quick-and-dirty MCP servers that pipe SQL straight through — which means one hallucinated DROP TABLE or an unbounded SELECT * on a 50M-row table is one tool call away. For anything beyond a toy project you want a governed layer in between:
- Read-only by default — agents get SELECT; DDL is blocked outright.
- Guardrails — single-statement enforcement, row limits, query timeouts, mandatory WHERE on opt-in writes.
- Human approval — opt-in write access can require a person to approve each execution.
- Audit — every query, caller and result size is logged.
- Scoped keys — the key you give Claude works for this connector only, revocable any time.
Step 1 — Run PlugMCP (one binary)
# Docker
docker run -d -p 8080:8080 -v plugmcp:/data ghcr.io/plugmcp/plugmcp
# …or the single binary (Linux/macOS/Windows, no dependencies)
./plugmcp
✓ PlugMCP listening on :8080 — admin UI ready
Open http://localhost:8080, log in with the admin token from the startup log.
Step 2 — Add the database connector
In the admin UI: Connectors → Add → Database, then paste a connection string:
postgres://claude_ro:•••@db.internal:5432/crm?sslmode=require
CREATE ROLE claude_ro LOGIN PASSWORD '…';
GRANT CONNECT ON DATABASE crm TO claude_ro;
GRANT USAGE ON SCHEMA public TO claude_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO claude_ro;PlugMCP instantly creates three MCP tools:
| Tool | What Claude can do | Guardrails |
|---|---|---|
crm_list_tables | Discover schema | read-only |
crm_describe_table | Inspect columns & types | read-only |
crm_query | Run SELECT queries | single statement, row limit, timeout |
MySQL/MariaDB and SQLite work identically — just paste the respective connection string or file path.
Step 3 — Mint a scoped, read-only API key
Keys → New key → scope it to the crm connector and tick read-only. The key can never touch other connectors, and you can revoke it without affecting anything else.
Step 4 — Connect Claude
Claude Desktop / claude.ai: Settings → Connectors → Add custom connector → URL https://your-gateway/mcp with the API key as bearer token.
Claude Code:
claude mcp add --transport http plugmcp https://your-gateway/mcp \
--header "Authorization: Bearer pmcp_…"
Then just ask: “Which customers churned last quarter, and what did they have in common?” — Claude will discover the schema, write the SQL and explain the result. Cursor, ChatGPT and any other MCP client connect the same way.
Optional: writes with human approval
If you enable the execute tool on the connector, UPDATE/INSERT/DELETE become available — with a mandatory WHERE clause, and (with PLUGMCP_REQUIRE_APPROVAL=1) each write paused until a human approves it in the UI. The agent waits; you stay in control.
FAQ
Is it safe to connect Claude to a production database?
Only through a governed layer. With read-only tools, row limits, timeouts and audit logging, exposure is bounded and observable. Never give an agent a superuser connection string.
Does this work with MySQL or SQLite?
Yes — PostgreSQL, MySQL/MariaDB and SQLite are all supported with the same three tools.
Do I need to write an MCP server?
No. That's the point of a gateway: the database tooling ships ready-made, and the same gateway also turns REST (OpenAPI → MCP), SOAP (SOAP → MCP) and GraphQL systems into tools.
What does it cost?
Nothing — PlugMCP is 100% open source (AGPL-3.0), self-hosted, with no license keys and no phone-home.