Ask Your Database in Plain English: A Claude PostgreSQL Walkthrough
This Claude PostgreSQL walkthrough starts with a question: “How many customers signed up last month who haven’t placed an order yet?” For someone who writes SQL every day, that is a two-minute query. For everyone else on the team it is a ticket that waits until that person has time. The Database add-on for MCP Self-hosted lets anyone ask it directly.
Below: the setup, a read-only user, and the limits of the tool.
What do you need for a Claude PostgreSQL setup?
Three things: MCP Self-hosted running with the Database add-on on your license, a PostgreSQL user for Claude, and a seat in My Account that has the Database tool ticked. The add-on also supports MySQL and MariaDB-compatible databases; only DB_TYPE changes.
The connection values go in .env or under the Tools tab of your license, where they are stored encrypted:
DB_TYPE=postgres
DB_HOST=db.internal.example.com
DB_NAME=shop
DB_USER=claude_ro
DB_PASSWORD=...
# DB_PORT=5432
# DB_SSL=true
DB_PORT defaults to 5432 for PostgreSQL and 3306 for MySQL. Set DB_SSL=true when your server requires an encrypted connection. Note that for PostgreSQL the tool then encrypts the connection but does not verify the server certificate. Run docker exec mcp-core npm run refresh-license after you change login details. Full reference: Database MCP setup.
Why does a Claude PostgreSQL connection need a read-only user?
Because the database user is the real protection. The tool has its own checks, but they work on keywords in the SQL text. They catch the obvious cases; they are a safety net, not a wall. A user that can only run SELECT can’t change anything, whatever query reaches the server.
A minimal PostgreSQL role for a Claude PostgreSQL connection looks like this:
CREATE ROLE claude_ro LOGIN PASSWORD 'choose-a-long-password';
GRANT CONNECT ON DATABASE shop TO claude_ro;
GRANT USAGE ON SCHEMA public TO claude_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO claude_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO claude_ro;
Grant only the tables Claude should see. A read replica works too: point DB_HOST at it. The tool doesn’t distinguish between a primary and a replica.
What happens when you ask the question?
In a Claude PostgreSQL session, the add-on gives Claude three tools: list tables, describe a table, and run a query. You ask in plain English. Claude lists the tables, describes the ones that look relevant to learn the columns, writes the SQL, and runs it. On a typical schema the query for our question looks something like this:
SELECT count(*)
FROM customers c
WHERE c.created_at >= date_trunc('month', now()) - interval '1 month'
AND c.created_at < date_trunc('month', now())
AND NOT EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id);
Claude then answers in a sentence. The SQL is in the tool call, which Claude Desktop and Claude Code show you, and you can ask Claude to print it and explain its assumptions. Check those, especially what counts as “signed up” and “last month” in your data. The free plain-English query skill makes that a fixed habit: every answer comes with the exact SQL and the assumptions behind it.
Which limits apply to every Claude PostgreSQL query?
The Database tool applies a few rules on every call:
- One statement per call. A query with several statements is rejected.
- Schema changes are never allowed: CREATE, DROP, ALTER, TRUNCATE, GRANT and REVOKE are blocked in every mode.
- INSERT, UPDATE and DELETE are rejected unless the seat has Can make changes on. Read-only is the default; you set the mode per seat on the Seats tab of your license.
- Results are capped at
DB_MAX_ROWSrows, 200 by default. Claude is told how many rows there were in total, so it can narrow the query. - A query that runs longer than
DB_QUERY_TIMEOUT_MS, 10,000 ms by default, is stopped. Claude gets the error, not a partial result.
What should you know about PostgreSQL schemas?
Schemas need one extra step in a Claude PostgreSQL setup. The list of tables covers every schema except the system ones, and it shows table names without the schema. Describe table also matches on the name alone. If two schemas have a table with the same name, their columns appear together. In that case, tell Claude which schema you mean and ask it to use schema-qualified names, such as sales.orders, in its queries. Views are not in the table list, but Claude can query them when you name them.
Common misconceptions
“I need to know SQL.” You don’t. Knowing a little helps you check the query, which is why seeing it matters.
“It can change my data by accident.” Not on a read-only seat, and not with a SELECT-only user. Use both.
“MySQL and PostgreSQL need different setups.” Same variables, a different DB_TYPE, and a different default port.
FAQ
Does a Claude PostgreSQL connection see all my data?
It sees what the database user can read, and query results are sent to Claude to answer you. Limit the grants to the tables that matter.
Can I map out the schema first?
Yes. The free schema explainer skill turns your schema into a plain-language data dictionary. It reads structure only, never rows.
Wrapping up
A Claude PostgreSQL setup takes a read-only role, five environment values and one refresh. After that, the person with the question asks it directly, and the person who writes SQL reviews the query instead of writing it. Get the add-on on the Database MCP server page.