# Let Claude query Postgres

> People ask the engineering team for numbers that live in the database.

This setup is for engineering and data teams who keep answering the same database questions for colleagues. Claude connects to Postgres through an MCP server with a read-only role, writes and runs SQL, and posts recurring numbers to Slack. You end up with a safe way for people to ask questions in plain language without access to production.

## Steps

1. **Create a read-only role**: Create a dedicated Postgres role with LOGIN and grant it USAGE on the needed schemas and SELECT on the needed tables only. Set default_transaction_read_only and a statement_timeout on the role so long or writing queries fail fast. Never reuse your application's database user.
   Tip: Run SET ROLE to the new role and try an INSERT to confirm it fails.
2. **Point it at a replica**: Connect the agent to a read replica, or to a reporting database copied from production. If you only have a primary, use the read-only role plus a low connection limit. Restrict network access so only the machine running the MCP server can reach it.
   Tip: A statement_timeout of a few seconds stops a runaway join from hogging resources.
3. **Register it in Claude**: Add a Postgres MCP server, such as Postgres MCP Pro in restricted mode or another read-only server, with the read-only connection string. Register it in Claude Desktop's config, Cursor's MCP settings or with claude mcp add in Claude Code. Keep the connection string in an environment variable rather than a committed file.
   Tip: Check the server's docs for a read-only or restricted flag and turn it on.
4. **Describe the schema**: Write a short notes file that explains key tables, what a row represents, how tables join and which columns hold money or dates. Add it to a Claude project, CLAUDE.md or Cursor rules. Ask Claude to show the SQL it ran with every answer so someone can check it.
   Tip: Include definitions of business terms like active customer so numbers match your dashboards.
5. **Share the answers**: Connect the Slack MCP server and restrict it to one channel for metrics. Ask Claude to post the question, the number and the SQL used. For scheduled numbers, run Claude Code from cron or CI with the same configuration.
   Tip: Post the SQL alongside the answer so anyone can reproduce it.

## Prompts to try

- How many new accounts signed up each week for the last eight weeks? Show the SQL.
- Which ten customers had the highest order value last month, and how does that compare with the month before?
- Explain what the subscriptions table stores and how it relates to invoices.
- Find orders stuck in pending for more than 48 hours and post the count to #metrics.
- Write a query for weekly churn using our definition of an active customer, but don't run it yet.

## What you need

- A Postgres database where you can create roles and grants
- Ideally a read replica or reporting copy
- Claude Desktop, Claude Code or Cursor
- A Slack channel for shared metrics

## Limits

- Claude can write SQL that runs but answers the wrong question, so important numbers need a human check.
- Large result sets get truncated or summarised; ask for aggregates instead of raw rows.
- The agent knows only the schema and your notes; undocumented business logic in application code stays invisible to it.

## Security notes

- Read-only database role only.
- Exclude tables containing personal data unless strictly needed.
- Prefer a replica over the primary.

## MCP servers

- [Postgres MCP Server](https://github.com/modelcontextprotocol/servers-archived): database-read
- [Slack MCP Server](https://docs.slack.dev/ai/mcp-server): channel-read, message-write

## FAQ

**Can the agent change or delete data?**

Not if you follow the steps: the role has only SELECT grants and read-only transactions. Many MCP servers also offer a read-only mode, but treat the database role as the real guard.

**Which hosts work?**

Claude Desktop, Claude Code and Cursor all support local MCP servers configured with a command and environment variables. Claude Code is the easiest for scheduled runs.

**What about personal data?**

Query results pass through the model, so leave tables or columns with personal data out of the grants, or expose a view without them. Check your company's data policy before connecting customer data.

**What if the answers are wrong?**

Wrong numbers usually come from wrong joins or business definitions. Read the SQL Claude shows, then add the correction to your notes file so the next answer improves.

## Tools

- **[Supabase](https://suiteintent.com/t/supabase?m=GB)**: Hosted Postgres with auth and storage. · Best for: A backend for an app you built with AI · Free plan
- **[Slack](https://suiteintent.com/t/slack?m=GB)**: Team messaging organised in channels. · Best for: Moving team chat out of email · Free plan · Free for nonprofits
