Hardened, read-only Postgres MCP server with credential isolation
Wellknown found it in public sources; nobody has proven control of it yet. Claiming takes one click if the repository is under your GitHub account, or a small file on your domain otherwise. Verified owners get the badge, 15-minute checks, status alerts, edits that outrank crawled data, and a ranking boost.
Agents can do it too: POST https://wellknown.network/api/v1/claims with {"agent":"psql-mcp","method":"well_known_file"} — machine-readable steps at claim.json, guide at /docs/claim.
Everything here was measured by our prober or read from a registry. Nothing is self-reported.
Attributed to the source that supplied each field. Treated as claims, not facts.
# psql-mcp A hardened, **read-only** Postgres [MCP](https://modelcontextprotocol.io) server. Give an LLM (Claude Code, etc.) safe query access to one or more databases — without giving it the ability to write, run DDL, shell out, read server files, or see your connection credentials. Extracted and generalized from a per-repo server used in production. The security core (`psql_mcp/hardening.py`) is unit-tested and unchanged from that origin. ## What it guarantees Every query is validated and then wrapped so the **Postgres engine itself** — not this Python — enforces read-only: ```sql SET default_transaction_read_only = on; BEGIN READ ONLY; <your SQL> ; ROLLBACK; ``` On top of that, pre-flight validation rejects: - **psql meta-commands** (`\!`, `\copy`, `\g`, `\gexec`, …) anywhere they'd be interpreted — including mid-line after SQL — closing the `\!` shell-escape. - **Read-only escapes**: `RESET`, `DISCARD`, `SET SESSION AUTHORIZATION`, `SET ... READ WRITE`, `transaction_read_only`, `SESSION CHARACTERISTICS`, and transaction control (`BEGIN`/`COMMIT`/`ROLLBACK`/`SAVEPOINT`/`START TRANSACTION`). `CASE … END` is unaffected. - **Filesystem / shell reach**: `COPY … PROGRAM`, non-`STDOUT` `COPY`, `pg_read_file` and the `pg_ls_*dir` family, `lo_import`/`lo_export`. - **Obfuscation**: `U&'…'` unicode-escape introducers and dynamic-SQL executors (`dblink*`, `query_to_xml*`) that could assemble a blocked name at runtime. Output is streamed under a 60 KB cap and a 60s timeout, killing the whole psql process group (not just a wrapping `bash`) so a runaway `SELECT` can't exhaust memory or hang the server. stderr is always surfaced so a blocked write never looks like a silent no-op. > These are defence-in-depth guardrails, not a substitute for least privilege. > Point each environment at a **role that only has `SELECT`**; the server then > just keeps the model from fighting that role. ## Install Requires `psql` on `PATH`. Then either: ```bash # one-off,…
Mapped onto the structured taxonomy from declared text and observed tool names. Confidence shown for derived entries.
Every source is kept verbatim. Field changes are logged as events.