The Postgres connector lets a block read from your own database with a SQL query you write. The platform wraps every customer query in a read-only safety envelope, defeats SSRF and DNS rebinding, and refreshes on a cron cadence.Documentation Index
Fetch the complete documentation index at: https://docs.chatblocks.ai/llms.txt
Use this file to discover all available pages before exploring further.
Add a Postgres data source
Paste a postgres:// connection string
A standard Postgres URI. The connection string is envelope-encrypted with your workspace’s DEK before it’s written to Convex.The SSRF check (see below) runs synchronously on the URL — bad URLs (private IPs,
localhost, plaintext schemes) are rejected immediately.Click Test Connection
Optional but recommended. The wizard runs a one-off connection probe (admin-gated) against your database with the same safety envelope it uses for every refresh. You get back
{ ok: true } or a useful error.The SQL safety envelope
Every query you write — every refresh, every preview — is wrapped server-side in this transaction:- Read-only.
BEGIN TRANSACTION READ ONLYrejects any write at the Postgres level. INSERT, UPDATE, DELETE, DDL — all fail with a Postgres error. - 5-second statement timeout. A runaway query kills itself instead of holding the connection.
- Hard 10 000 row cap. No accidental million-row pull.
- Subquery wrapper. Your SQL is parenthesized as a derived table. You write
SELECT ... FROM ... WHERE ...and the platform plugs it in.
- Trailing
;on your SQL — stripped automatically. - Inner
;— rejected as potential statement chaining. - Empty SQL — rejected.
WITH ... SELECT ...) work because they’re valid inside the subquery position. Window functions, joins, subqueries — all fine. Multi-statement scripts won’t fit.
SSRF protection
Two-layer defense before the platform connects to your database:- Synchronous (at add time)
- Async (every connect)
The wizard validates the connection string the moment you paste it:
- Scheme must be
postgres:orpostgresql:— nohttp:, nofile:, nointernal:. - Hostname blocklist:
localhost, anything ending in.local. - Literal IP check: IPv4 private ranges (
10/8,172.16/12,192.168/16,127/8,169.254/16,0.0.0.0), IPv6 private ranges (::1,fc00::/7,fe80::/10).
postgres://postgres@localhost/db is rejected up front.Bind a block
{ rows: Row[], rowCount: number }. The projection paths into rows.0.signups to pluck the count.
Agent-driven schema introspection
Your coding agent can discover your database structure through two MCP tools without seeing the connection string. Useful when telling an agent “build me a block off my Postgres” and letting it figure out what to query:dataSources.introspectSchema
dataSources.introspectSchema
Lists the top 50 tables sorted by activity (from
pg_stat_user_tables). Returns table name, schema, and approximate row count.Postgres-only — other source types return isError: true.dataSources.introspectTable
dataSources.introspectTable
Lists columns + types for a given table (from
information_schema.columns).Postgres-only.auditLog row before connecting.
Credential storage
A single-secret credential (just the connection string). Encrypted via the workspace DEK. Every decryption is audit-logged with the calling actor.What’s next
Webhook
Push-mode delivery from your own systems.
Outbound MCP
Point at a third-party MCP server (Linear, GitHub, Notion).