Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

io.github.YawLabs/postgres-mcp

NPM · @YAWLABS/POSTGRES-MCP · SCANNED AUG 6

PostgreSQL MCP server - query, schema introspection, explain, and health checks for AI assistants

+13 this week 68 Trust /100
Trust breakdown (6 categories)

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score →

Supply Chain Security100
  • No malware found by supply-chain analysis.Pass
  • No known CVEs affecting this package version or its production dependencies.Pass
  • No install/post-install scripts declared.Pass
  • No production dependencies, so there is no dependency health to assess. View diagnostics → Pass
Provenance & Transparency19
Schema Quality & AI Usability71
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 3398 tokens (~161/item across 21 items; 21 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management33
  • Stability observed for 10 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 100% of tool parameters carry a description.Pass
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Install

Add this component to your MCP client. Where a client-specific snippet is available, pick your client below and copy it straight into your config; otherwise use the connection detail shown.

npm · @yawlabs/postgres-mcp

# add to Claude Code
claude mcp add yawlabs-postgres-mcp -- npx -y @yawlabs/postgres-mcp
# add to Codex CLI
codex mcp add yawlabs-postgres-mcp -- npx -y @yawlabs/postgres-mcp
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "yawlabs-postgres-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@yawlabs/postgres-mcp"
      ],
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add yawlabs-postgres-mcp --command npx --arg -y --arg @yawlabs/postgres-mcp
# ~/.hermes/config.yaml
mcp_servers:
  yawlabs-postgres-mcp:
    command: "npx"
    args: ["-y", "@yawlabs/postgres-mcp"]
// mcp.json
{
  "mcpServers": {
    "yawlabs-postgres-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@yawlabs/postgres-mcp"
      ]
    }
  }
}
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 5 Aug 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 27 to 30. That category is still filling its 30-day observation window: 8 days of observed history at the previous scan, 9 at this one. The score rises as the window fills, whether or not the server changes.

  • 4 Aug 26 +4
    • Stability: unverified → 0.27 functional
  • 2 Aug 26 +15
    • Malware scan: unverified → pass security
  • 31 Jul 26 −7
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 30 Jul 26 −18
    • Malware scan: pass → unverified security
  • 27 Jul 26 +32
    • Tool coverage: unverified → 100 functional
    • First check of Schema quality: fail functional
    • First check of Tool coverage: 100 functional
    • First check of Schema quality: fail functional
    • First check of Schema quality: excellent functional
  • 26 Jul 26 41

    First indexed and scored.

    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 6 Aug 2026 · Analysed npm/@yawlabs/[email protected]

Provenance No attestation

The registry publishes no build provenance for this version, so there is nothing to verify.

Result No attestation
Ecosystem npm
Dependencies 0 packages
Packages resolved 0
Tree resolution Complete
MCP tools — 21 exposed · ~3,398 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability.

Tool Tokens
pg_advisor ~267

Rolled-up DBA lint pass. One call returns three categories of findings: - sequence_exhaustion: SERIAL / BIGSERIAL / IDENTITY sequences whose `last_value` is above `seqExhaustionThreshold` of `max_value`. The classic incident class. - tables_without_primary_key: user tables (plain and partitioned) with no PK defined. Bloat candidates and a sign of design drift; some replication setups also need PKs. Foreign tables are excluded -- PostgreSQL forbids declaring PKs on foreign tables. - public_tables_without_rls: tables in `public` (or any schema in `rlsSchemas`) with row-level security disabled. Useful as a security baseline check. Use this as the 'what should I be looking at?' starting point, then drill into `pg_unused_indexes`, `pg_table_bloat`, `pg_seq_scan_tables` for the perf side.

NameTypeReqDescription
limitintegerMax rows per category (default 50).
rlsSchemasarraySchemas where RLS-missing should be flagged. Defaults to ['public'].
seqExhaustionThresholdnumberMinimum used-fraction (last_value / max_value) to flag a sequence (default 0.5 = 50%).

No output schema declared.

No examples provided.

pg_describe_table ~162

Describe a relation: kind (table / view / materialized_view / partitioned_table / foreign_table), columns (name, type, nullable, default), primary key, foreign keys (outgoing), `referenced_by` (other tables whose FKs point at this one), `constraints` (CHECK / UNIQUE non-PK / EXCLUDE), indexes, and partition info (`partition_of` parent, `partitions` children). Works on views and materialized views too -- PK/FK/constraint/index lists will simply be empty for a plain view. Use `kind` to disambiguate before assuming you can write to the relation.

NameTypeReqDescription
schemastringSchema name (defaults to 'public').
tablestringyesTable name.

No output schema declared.

No examples provided.

pg_explain ~313

Get the query plan for a SQL statement. By default, this uses plain EXPLAIN (no execution). Set `analyze: true` to run the query with EXPLAIN ANALYZE - for non-SELECT statements, ALLOW_WRITES=1 is required (since ANALYZE actually executes the statement). Writes executed during EXPLAIN ANALYZE are always rolled back, so you can inspect a plan for an INSERT/UPDATE/DELETE without persisting the mutation. Format is `text` (default) or `json`. Pass the raw SQL (not an EXPLAIN-prefixed statement). Set `hypothetical_indexes` to a list of `{table, columns, using?}` to ask the planner 'what would the plan be if these indexes existed?' -- requires the HypoPG extension (`CREATE EXTENSION hypopg`). The hypothetical indexes are torn down at the end of the call, never touching real disk.

NameTypeReqDescription
analyzebooleanRun EXPLAIN ANALYZE (actually executes the query).
formatstringOutput format.
hypothetical_indexesarrayList of indexes the planner should pretend exist for this EXPLAIN. Requires the HypoPG extension. Indexes are session-scoped and reset at the end of the call.
paramsarrayPositional parameters referenced as $1, $2, ... in the SQL.
sqlstringyesThe SQL statement to explain. Do NOT prefix with EXPLAIN.

No output schema declared.

No examples provided.

pg_health ~62

Quick health snapshot: server version, database size, connection count, active queries, and table count. Useful as a connection sanity check and to spot runaway queries.

NameTypeReqDescription
activeQueryLimitintegerMax active queries to return (default 10, max 100).

No output schema declared.

No examples provided.

pg_inspect_locks ~210

Show current lock contention: which sessions are blocked and who is blocking them. Returns blocked PID, blocking PID, lock types, relation being contested, and the queries involved. Use this first when a tool call hangs or the app feels stuck - it's the fastest way to identify a long-held transaction holding a lock. Row shape: one row per (blocked_pid, blocking_pid) pair. A session waiting on multiple blockers appears on multiple rows -- group/deduplicate by `blocked_pid` if you want a per-blocked-session count. Caveat on `relation`: for non-relation waits (transactionid/virtualxid, where the wait is on the blocker's xid rather than a table) `relation` is a best-effort hint -- an alphabetical guess among the blocker's held write-intent locks -- not authoritative. Use the blocked/blocking query text to disambiguate which table is actually contested.

NameTypeReqDescription
limitintegerMax blocked/blocker pairs (default 50).

No output schema declared.

No examples provided.

pg_kill ~226

Cancel a running query (SIGINT-equivalent) or terminate a backend connection (SIGTERM-equivalent) by PID. Find the PID via `pg_health` active_queries or `pg_inspect_locks`. Requires ALLOW_WRITES=1 since this changes database session state. The role in DATABASE_URL must have permission - cancelling another user's query needs the `pg_signal_backend` role or superuser. Note: `pg_signal_backend` does NOT cover superuser-owned backends - only a superuser can signal another superuser's session. Cancel is graceful; terminate is forceful. When `signaled=false`, the `note` field surfaces postgres's NOTICE explaining why (e.g. 'not a PostgreSQL backend process' for a non-pg PID, 'must be a member of...' for permission denial) so an agent can act on the specific cause rather than guess from a three-way list.

NameTypeReqDescription
modestring`cancel` aborts the current query; `terminate` closes the connection entirely.
pidintegeryesBackend PID to signal.

No output schema declared.

No examples provided.

pg_list_extensions ~54

List installed PostgreSQL extensions. Returns name, version, schema, and description. Useful to check for pgvector, postgis, pg_stat_statements, uuid-ossp, etc. before writing queries that rely on them.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

pg_list_functions ~55

List functions, procedures, and aggregates in a schema. Returns name, arguments, return type, kind (function/procedure/aggregate/window), and implementation language.

NameTypeReqDescription
schemastringSchema name (defaults to 'public').

No output schema declared.

No examples provided.

pg_list_roles ~88

List database roles (users and groups) with their login/superuser/createdb/createrole attributes and inherited role memberships. Use this to answer 'who has access to this database?' without needing to read `pg_authid` directly.

NameTypeReqDescription
includeSystembooleanIf true, include built-in `pg_*` roles (pg_read_all_data, pg_monitor, etc.).

No output schema declared.

No examples provided.

pg_list_schemas ~37

List non-system schemas in the database. Excludes `pg_catalog`, `information_schema`, and other `pg_*` internals.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

pg_list_tables ~153

List tables (and optionally views) in a schema. Returns name, type (table/view/materialized view/foreign), and estimated row count (from `reltuples`; null = no ANALYZE yet on PG 14+; 0 may mean empty or unanalyzed on PG <= 13). Paginate via `limit`/`offset` on very large schemas.

NameTypeReqDescription
includeViewsbooleanIf true, include views and materialized views.
limitintegerMax rows to return (default 500, max 10000).
offsetintegerRows to skip for pagination (default 0).
schemastringSchema name (defaults to 'public').

No output schema declared.

No examples provided.

pg_list_views ~79

List views and materialized views in a schema with their SQL definitions. Use this over `pg_list_tables` with `includeViews: true` when you want the view body, not just names.

NameTypeReqDescription
includeMaterializedbooleanIf true, include materialized views.
schemastringSchema name (defaults to 'public').

No output schema declared.

No examples provided.

pg_query ~267

Run a SQL query against the configured PostgreSQL database. Postgres itself is the primary safety gate: the role in `DATABASE_URL` enforces what queries can succeed. The recommended posture is a least-privileged role (e.g. one granted `pg_read_all_data`), which makes writes server-rejected regardless of any env var. `ALLOW_WRITES=1` is a secondary belt-and-braces gate - it lifts the in-server `BEGIN READ ONLY` wrapper, but it cannot grant privileges the role lacks. Useful for managed databases where creating a second role is awkward. For read-only access where you want the guarantee in the tool name, prefer `pg_readonly`. Use `params` for parameterized queries to avoid SQL injection. Params can be strings, numbers, booleans, null, arrays (for postgres arrays / ANY), or objects (for json/jsonb columns). Dates and UUIDs can be passed as ISO strings. Large result sets are truncated to POSTGRES_MAX_ROWS (default 1000) with a `truncated: true` flag.

NameTypeReqDescription
paramsarrayPositional parameters referenced as $1, $2, ... in the SQL.
sqlstringyesThe SQL statement to execute. Hard cap of 1 MB.

No output schema declared.

No examples provided.

pg_readonly ~200

Run a SQL statement guaranteed read-only. Always executes inside a `BEGIN READ ONLY` transaction regardless of `ALLOW_WRITES`, so postgres itself rejects any write attempt. Use this whenever the goal is to read - SELECT, EXPLAIN, SHOW, VALUES, WITH ... SELECT, etc. Hosts that gate tools individually (Claude Code permissions, mcp.hosting) can safely auto-allow this one. Use `params` for parameterized queries to avoid SQL injection. Params can be strings, numbers, booleans, null, arrays (for postgres arrays / ANY), or objects (for json/jsonb columns). Large result sets are truncated to POSTGRES_MAX_ROWS (default 1000) with a `truncated: true` flag.

NameTypeReqDescription
paramsarrayPositional parameters referenced as $1, $2, ... in the SQL.
sqlstringyesThe SQL statement to execute. Hard cap of 1 MB.

No output schema declared.

No examples provided.

pg_replication_status ~70

Replication overview: configured replication slots, connected replicas (from `pg_stat_replication`), and current WAL position. Use on primary to spot lagging or disconnected replicas, on replicas to see upstream status. Returns empty arrays on a standalone (non-replicated) database rather than erroring.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

pg_search_columns ~121

Search for columns by name across all user schemas. Supports SQL LIKE patterns (`%` matches any substring, `_` matches one character). Case-insensitive. Use this instead of iterating `pg_describe_table` when the user asks 'which tables have X'.

NameTypeReqDescription
limitintegerMax rows to return (default 100).
patternstringyesLIKE pattern. Use '%' for wildcard: 'user_id', '%email%', 'created_%'.
schemastringLimit to this schema. If omitted, searches all user schemas.

No output schema declared.

No examples provided.

pg_seq_scan_tables ~146

Tables with high sequential-scan counts relative to index scans - the first place to look for missing-index candidates. Returns seq_scans, idx_scans, live tuples, and the ratio. A high ratio on a large table usually means a query is reading the whole table where an index would suffice. Pair with `pg_top_queries` to find which query is doing it.

NameTypeReqDescription
limitintegerMax rows to return (default 20).
minSizeintegerMinimum live tuple count to include (default 1000, filters out tiny/empty tables).
schemastringLimit to one schema. If omitted, all user schemas are included.

No output schema declared.

No examples provided.

pg_table_bloat ~362

Estimate table bloat (dead tuples + free space) for tables in a schema. Returns live tuples, dead tuples, dead-tuple ratio, last_vacuum / last_autovacuum timestamps, and total relation size. A high dead_ratio with a stale last_autovacuum is a sign a table needs VACUUM. Three methods are available via the `method` parameter: - `estimate` (default): reads pg_stat_user_tables -- fast, no extensions, ANALYZE-driven approximations. Use this first. - `approx`: uses pgstattuple_approx() -- fast sampling pass, more accurate than estimates, requires the pgstattuple extension. - `exact`: uses pgstattuple() -- full table scan, exact counts, slow on large tables, requires the pgstattuple extension. Always pass `schema` with method='exact' -- scanning all user tables in one statement will hit statement_timeout on non-trivial databases. Install pgstattuple with `CREATE EXTENSION pgstattuple` (requires superuser).

NameTypeReqDescription
limitintegerMax rows to return (default 50).
methodstringBloat measurement method. 'estimate' (default) uses pg_stat_user_tables (fast, no extensions). 'approx' uses pgstattuple_approx() (fast sampling, more accurate). 'exact' uses pgstattuple() (full scan…
minDeadRationumberMinimum dead-tuple fraction to include - dead / (live + dead). Default 0.1 = 10%.
schemastringLimit to one schema. If omitted, all user schemas are included.

No output schema declared.

No examples provided.

pg_table_privileges ~185

Show which roles have which privileges (SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER) on a table or on every table in a schema. If `table` is omitted, the result spans every table in `schema`, ordered by table then grantee. Use this to answer 'who can write to this table?' or to audit schema-wide access before a migration. Visibility caveat: backed by `information_schema.table_privileges`, which postgres filters by what the calling role can see. A least-privileged role may not see grants involving unrelated third-party roles. For a complete picture, run as a superuser or a member of `pg_read_all_data`.

NameTypeReqDescription
schemastringSchema name (defaults to 'public').
tablestringTable name. Omit to list privileges for all tables in the schema.

No output schema declared.

No examples provided.

pg_top_queries ~204

Top N queries by total or mean execution time. Requires the `pg_stat_statements` extension to be installed and enabled (most managed Postgres providers have it on by default). Returns normalized query text (constants replaced with `?`), call count, total/mean/min/max time in ms, rows returned, and cache hit ratio. Use this to find slow queries worth optimizing. On pg_stat_statements >= 1.10 (Postgres 15+), also returns `io_read_time_ms` and `io_write_time_ms` to separate IO-bound from CPU-bound queries (null when track_io_timing = off or the query did no measurable IO -- enable track_io_timing in postgresql.conf to get non-null values).

NameTypeReqDescription
limitintegerNumber of rows to return (default 20).
orderBystringRanking: total_time (cumulative impact), mean_time (worst per-call), or calls (hottest).

No output schema declared.

No examples provided.

pg_unused_indexes ~137

Indexes that have never been scanned or have very low usage. Each unused index costs write amplification (every INSERT/UPDATE maintains it) and disk space. Excludes primary keys and unique constraints (which are load-bearing even with zero scans). Use this before adding new indexes - sometimes the fix is to drop a dead one.

NameTypeReqDescription
limitintegerMax rows to return (default 50).
maxScansintegerInclude indexes with scan count <= this (default 10). Use 0 for 'never scanned'.
schemastringLimit to one schema. If omitted, all user schemas are included.

No output schema declared.

No examples provided.