DATA

postgres-mcp

Reference MCP server for PostgreSQL access. Read-first by design — schema introspection plus a configured-by-you query tool. Part of modelcontextprotocol/servers.

Alive Recommended REVIEWED 2026-05-07
VERDICT

Default for read-only agentic SQL. For write workloads, prefer your app layer with proper migrations — not an LLM.

What it does

Three core tools: list_tables (every table the role can see), describe_table (columns, types, comments, indexes), and query (run an arbitrary SELECT). Some forks add execute (DDL / DML) and transaction wrappers. The canonical version stays close to read.

When you actually need it

Plain-English questions over your own database. “How many users signed up last week, broken down by source?” — the agent calls list_tables, picks the right table from the schema, drafts the query, runs it, returns the answer with the SQL it ran. The honesty of having the agent show its query is the whole point.

Setup

"postgres": {
  "command": "npx",
  "args": [
    "-y",
    "@modelcontextprotocol/server-postgres",
    "postgresql://agent:password@localhost:5432/mydb"
  ]
}

The connection string carries the credentials. Two non-negotiables:

  1. Use a dedicated role. Not postgres. Not your app’s role. A new role with only CONNECT to the database, only SELECT on the tables you’ve thought about, and a statement_timeout set short.
  2. Default to read-only. Add default_transaction_read_only = on for the role.
CREATE ROLE agent_reader LOGIN PASSWORD 'rotate-this';
GRANT CONNECT ON DATABASE mydb TO agent_reader;
GRANT USAGE ON SCHEMA public TO agent_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO agent_reader;
ALTER ROLE agent_reader SET default_transaction_read_only = on;
ALTER ROLE agent_reader SET statement_timeout = '30s';

Now even if the agent invents a DROP TABLE users, Postgres refuses.

The catch

The agent will sometimes write a query that returns a million rows. It will sometimes run a query that takes ten minutes. The MCP server doesn’t paginate — it returns whatever Postgres returns, and your context window is the limit.

Defensive moves: the role-level statement_timeout, plus a prompt rule (“if a query would return more than 200 rows, narrow it first”), plus a follow-the-money habit of watching pg_stat_activity while the agent is exploring an unfamiliar database.

▸ MCP SECURITY SCORECARD Methodology v1.0 · Confidence HIGH · Reviewed 2026-05-07 · Next review due 2026-08-07
METHODOLOGY ↗
ADOPT WITH LIMITS

FOR: Read-only agentic SQL over a Postgres database.

Use a dedicated Postgres role with SELECT-only and a short `statement_timeout`. Never connect with the `postgres` superuser or your app's role. For DDL/DML workloads, prefer migrations and code review — not an LLM with database write access.

Maintainer corp

Anthropic + the modelcontextprotocol working group.

Licence MIT

Inherited from the modelcontextprotocol/servers monorepo.

Code review yes
Secrets handling scoped

Connection string carries credentials. Pass via env / args; the server doesn't persist or log it.

Sandbox process
Filesystem access none

No filesystem operations.

Shell access no
Network egress allow-list

Only the configured Postgres host.

OAuth handling n/a

Plain Postgres auth via connection string.

Default permissions moderate

Whatever the connecting role can do. With a properly-scoped read-only role, this is small. With a default `postgres` superuser, this is everything.

Prompt-injection exposure high

Row contents the agent reads back can contain hostile instructions. Common in any user-generated text column (comments, descriptions). Treat all query output as untrusted text.

Supply chain surface low

Direct deps are MCP SDK and pg (the canonical Node Postgres client). Both have strong release hygiene.

Dep CVE surface clean
Rate-limit risk medium

No MCP-layer rate limit. A long-running agent can run expensive queries; mitigations are at the Postgres role level (statement_timeout) not the MCP server.

Signed releases yes

npm package published with provenance attestations.

Security policy yes
Telemetry none
Data residency mixed

Wherever your Postgres lives. Query results enter the LLM context — pay attention to data-classification before pointing this at production.

Credential storage memory

Connection string lives in process env / args. No on-disk credential cache.

DESTRUCTIVE TOOLS

1 present · human approval optional

  • query

NOT A FORMAL SECURITY AUDIT · Adoption posture based on public-source review · See methodology for what's measured and what isn't