How to use Claude with Postgres
Connecting Claude to Postgres takes 10 minutes. Keeping it reliable for a team is the hard part. Here is what you need beyond the MCP connection.
Connecting Claude to Postgres takes 10 minutes. Keeping it reliable for a team is the hard part.
MCP gets you a working connection. But once your second teammate starts querying, you run into the real problems: inconsistent answers, no access control, credentials on every laptop, and no visibility into what queries are running. The connection isn't the bottleneck. The context around it is.

What you actually need for a team
Before getting into setup, here's what matters when more than one person is querying your Postgres database through an LLM:
- A read-only connection that your team never touches directly
- Shared business definitions so “revenue” means the same thing for everyone
- Table and column context so the model doesn't have to guess what
amt_netmeans - Per-user or per-group access control so sales can't see payroll tables
- Query logs and visibility so you know what questions are being asked and whether the answers are right
- A way to update context as the schema changes without manually editing prompts
MCP gives you #1. The rest is where teams get stuck.
The quick way: direct MCP
The fastest way to try Claude with Postgres is a direct MCP connection. Install the server, point it at your database, and Claude can run queries in minutes.
// claude_desktop_config.json
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://read_user:pass@host:5432/mydb"
]
}
}
}Security warning: this package is archived and has a known vulnerability
Anthropic archived @modelcontextprotocol/server-postgres in May 2025. The npm-published version (0.6.2) has a confirmed SQL injection vulnerability that allows an attacker to bypass the READ ONLY transaction guard and execute arbitrary write operations on your database. The package still receives ~21,000 weekly npm downloads despite being unpatched.
If you use this for quick testing, never point it at a production database. For anything beyond personal exploration, use a managed solution like Contextflo that connects via read-only service credentials.
Source: Datadog Security Labs: SQL injection in the PostgreSQL MCP server | GitHub: servers-archived
Once connected, Claude can list tables, inspect schemas, and run SQL. Ask “how many users signed up this week?” and it writes the query, runs it, and returns the answer. Fast, free, and useful for a solo dev exploring a schema they already know.
Tip: add context with Claude Projects
You can improve accuracy by creating a Claude Project, adding notes about your schema (table descriptions, metric definitions, business rules), and using that project when querying. This works well for one person, but the context lives in your Claude account and isn't shared with anyone else.
Important: use a read replica
Never point analytics queries at your production primary. A slow aggregation can lock tables and affect your app. RDS, Supabase, Neon, and most hosted Postgres providers offer read replicas.
Where it breaks for teams
The direct connection works for one person. When you hand it to a team, two things break: the answers become inconsistent, and the setup becomes unmanageable.
Inconsistent answers
Production Postgres schemas are messy. They evolve over years, with abbreviated column names, legacy tables, and implicit business logic. Claude sees this:
What Claude sees
usr_acct (id, sts, crt_at, upd_at, tier_id, ref_src, acq_ch) ord (id, usr_id, amt_gross, amt_net, disc_cd, sts, crt_at) sub (id, usr_id, plan_id, mrr_cents, churn_at, cancel_rsn)
Without context, Claude guesses. Is sts a status code or a string? Does amt_net include tax? What values of sts mean “completed”?
Your head of growth asks “what was revenue last week?” Claude computes it from ord.amt_net. Your finance lead asks the same question and gets a different number because their Claude Project has different notes. Now you don't have self-serve analytics. You have self-serve inconsistency.
The context maintenance trap
You can work around the messy schema by adding notes in a Claude Project. But now you're maintaining context manually. When a column gets renamed, a table gets added, or a metric definition changes, someone has to update those notes. And if your teammate has their own project with their own notes, you're back to inconsistent answers. This is the core problem: context becomes manually maintained, stale, and inconsistent across teammates.

The management overhead
- Everyone manages their own config. Each person edits a JSON file on their laptop with database credentials. Your head of ops isn't doing that.
- Everyone gets the same access. There's one connection string. Everyone sees everything. Unless you create separate database users for each person, there's no way to restrict who sees what.
- Credentials live on laptops. Database passwords in plaintext config files. No way to revoke access without changing the password for everyone.
- Switching providers breaks everything. If you move from Supabase to Neon, or RDS to Railway, every person on the team needs to update their config.
- No visibility. No audit log of what queries ran, who asked what, or whether the answers were correct.
The team-ready way: a context layer
You don't need another connector. You need a maintained context layer so Claude keeps giving the same trustworthy answer as your schema, team, and definitions change.
Contextflo connects to your Postgres database using read-only credentials. It scans your schema and auto-generates context: what every table and column actually means, how tables relate to each other, and how key metrics should be calculated. Your team still asks questions in Claude. The difference is what Claude knows.
| What Contextflo does | What your team gets |
|---|---|
| Auto-generates context | Claude knows what your tables and metrics mean without you writing a giant prompt |
| Shared definitions | Everyone gets the same answer for revenue, active users, churn |
| Access control | Sales can ask sales questions without seeing finance or payroll tables |
| Centralized connection | No database passwords on 10 laptops |
| Audit trail | You can see what people asked, what SQL ran, and where Claude failed |
| Provider change | Move Postgres providers once, not on every teammate's laptop |


Works with any hosted Postgres:
Which approach to use
If you just want Claude to query Postgres once, use MCP. If you want your team to rely on Claude for company data, you need a context layer in the middle.
| Direct MCP | Contextflo | |
|---|---|---|
| Setup | Edit JSON config per person | Connect once, invite team |
| Schema context | Raw table/column names | Auto-generated descriptions |
| Metric consistency | No | Shared definitions |
| Access control | Same DB user for everyone | Per-table, per-user ACL |
| Credentials | On every laptop | Centralized, never exposed |
| Provider change | Update every config | Update one connection |
| Audit trail | None | Full query log |
Related reading
- You don't need a data warehouse for analytics: query Postgres + SaaS tools directly
- You connected your warehouse to Claude, now what?: what every team needs beyond the MCP connection
- What it takes to maintain an agentic analytics stack: the 6 things that break over time