postgres-mcp-server

A secure MCP server for PostgreSQL.

Connect Claude, Cursor, or any MCP client to your database with read-only access, column filtering, and query limits. Open source, self-hostable, one small TypeScript server.

$npx @querybear/postgres-mcp-server View on GitHub

Works with Claude Desktop, Cursor, Windsurf, Zed, and any MCP-compatible client.

Tools

Four tools for reading a database.

query{ sql, schema? }

Run a read-only SELECT. Returns rows, column names, and a row count. Anything that isn't a SELECT is rejected before it reaches the database.

list_tables{ schema? }

List every table in a schema (default: public) so the assistant can learn the shape of your database.

describe_table{ table, schema? }

Return column names, data types, nullability, and defaults for a table.

list_schemas( )

List all non-system schemas — useful for multi-tenant or large databases.

Security

Read-only by default. No unsafe opt-in.

Every query runs through a security pipeline before it touches your database. The controls below are always on.

SELECT-only enforcement

INSERT, UPDATE, DELETE, DROP, TRUNCATE, and all DDL are rejected before execution.

Injection guards

Statement stacking (;), line and block comments, and EXEC-style calls are blocked at the parser level.

Column filtering

Sensitive columns — passwords, tokens, secrets — are stripped from every result. Configurable via BLOCKED_COLUMNS.

Row limits

Results are capped at MAX_ROWS with a truncation flag, so an assistant can't dump an entire table by accident.

Query timeouts

A statement_timeout from QUERY_TIMEOUT_MS kills runaway queries and protects the database under load.

Quick start

Add it to your MCP client.

Point it at a connection string and you're done. For Claude Desktop, add this to claude_desktop_config.json:

claude_desktop_config.json
{
  "mcpServers": {
    "postgres": {
      "command": "npx",
      "args": ["@querybear/postgres-mcp-server"],
      "env": {
        "DATABASE_URL": "postgresql://user:pass@host:5432/db"
      }
    }
  }
}

Optional environment variables:

env
DATABASE_URL      postgresql://…   # required
MAX_ROWS          500              # default 1000
QUERY_TIMEOUT_MS  15000            # default 30000
BLOCKED_COLUMNS   password,token   # comma-separated

Full configuration and adapters for other clients are in the README.

For teams

Need this on a production database?

QueryBear is the managed version. Same security model, plus per-user RBAC, column-level access control, table allow-lists, audit trails, and SSO — with nothing to host.

Try QueryBear