PostgreSQL MCP: configure and check read-only access
Read PostgreSQL through MCP with scoped roles, schemas and query limits. Use a practical setup checklist and diagnose common permission failures.
Still choosing an access path? The database planner builds a test plan; the database comparison explains file, role and project boundaries.
A PostgreSQL MCP server connects a client to database operations. Whether access remains read-only depends on effective permissions and the implementation. “Read-only” in a project name is not sufficient verification. Start with a test database or an explicitly approved subset. Define which tables, columns and result sizes your task needs before entering connection details.
Choose the intended PostgreSQL capability
The PostgreSQL search lists registry matches for this term. Check whether a project exposes arbitrary SQL, predefined operations or only metadata. Reading a schema and querying arbitrary table contents are different capabilities. Compare candidates with the attribute comparison, then read the documentation for the exact version you intend to use.
Record where the MCP process runs and how it reaches the database. “localhost” refers to different environments in a local process, container or remote service. A working connection from your terminal does not prove the same network path exists from the server environment. Record the target host, database and role, while leaving the password out of your review notes. This makes a failed connection easier to investigate without sharing credentials.
Enforce the boundary in the database
PostgreSQL distinguishes connection privileges, schema access and table read privileges. A dedicated role should receive only what the task requires. Have inherited roles and existing grants reviewed as well. A newly created role is not restricted merely because it has a suitable name. Avoid owner or superuser credentials for this purpose, and keep the intended access boundary explicit in your setup record.
| Layer | Your decision | Check |
|---|---|---|
| Database | Approved test target | Connection reaches the right instance |
| Schema | Required namespace | Role can access the schema |
| Data | Tables or bounded views | Only required read privileges |
| Query | Bound size and duration | Result size and termination |
| Output | Required columns | Exclude unnecessary confidential fields |
Create the configuration and first query
Open the configuration builder for an entry with a declared launch template. Compare its variables with the project documentation.
Store connection credentials in the designated location. Do not share a complete connection URI when it contains a password.
Using the intended role, query a small known table. Select the required columns explicitly and bound the returned row count.
Compare the result with your expectation. Have permissions and a controlled rejection case checked in a test environment before approving routine use.
Separate read-only mode from query limits
The PostgreSQL setting default_transaction_read_only establishes the initial read-only mode of new transactions. It does not replace a reviewed role design. Read access can still disclose confidential information or run an expensive query. PostgreSQL also documents statement_timeout for limiting statement duration. Agree on an appropriate value with database operations instead of applying a blanket setting to every application.
A SQL LIMIT bounds the returned row count but does not itself establish a cheap execution plan. Check output size and duration separately. For recurring reports, defined views and known queries can be easier to review than constantly changing arbitrary queries. Document which data you intentionally exclude and who owns any later access expansion. Keep the test query and expected result together so a later permission change can be checked against the same task.
- Is a server named “read-only” sufficiently restricted?
- Check effective database permissions and the behavior of the actual implementation. Its name is not evidence of enforcement.
- Why does SELECT fail after a successful connection?
- Connection, schema access and table privileges are separate layers. Also check the selected schema and effective role.
- Should I use production credentials for the first test?
- Start with an intended test environment or an explicitly approved subset with bounded permissions.
- What belongs in the review record?
- Project version, target environment, role without secrets, queried data scope, expected output, observed result and remaining limits.
Sources checked on 1 October 2026. The checklists are editorial suggestions for your own environment.
- PostgreSQL 18: GRANT
Show retrieval command
curl -s https://www.postgresql.org/docs/18/sql-grant.html - PostgreSQL 18: client connection defaults
Show retrieval command
curl -s https://www.postgresql.org/docs/18/runtime-config-client.html