postgres-mcp
Read-only-by-default MCP server for PostgreSQL. Query, introspect schemas, explain plans, health checks.
Install / Use
claude mcp add YawLabs -- npx -y github:YawLabs/postgres-mcpIf the server publishes to npm under a different name, use that package instead — check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
AI & Machine LearningSupported Platforms
Our assessment of postgres-mcp
postgres-mcp scores 72/100 on our quality scale, 855th of 941 AI & Machine Learning skills we index.
Its MCP Server is 48 KB long, well organised into 18 sections with 14 code examples: long enough that it reads more like full documentation than a focused instruction file, which agents can find harder to follow.
It has 10 GitHub stars, so there is little community track record yet; judge it on its content.
Maintenance, license and trust
- The repository was last updated 8 days ago, so postgres-mcp is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 97/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
postgres-mcp compared with similar skills
All 4 of these similar skills score higher than postgres-mcp; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| postgres-mcp (this skill)by YawLabs | 72 | 10 | 8d ago | MCP Server |
| claude-memby thedotmack | 100 | 102.4k | today | CLAUDE.md |
| Agent-Reachby Panniantong | 100 | 101.2k | today | CLAUDE.md |
| Understand-Anythingby Egonex-AI | 100 | 87.8k | 1d ago | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 77.6k | 1d ago | CLAUDE.md |
Frequently asked questions
- How do I install postgres-mcp?
- Run
claude mcp add YawLabs -- npx -y github:YawLabs/postgres-mcp. The install tabs above show the steps for each supported agent. - Which AI agents does postgres-mcp work with?
- It is written for Claude Code, Claude Desktop and Cursor, as a MCP Server file. Other agents that read the same format can often use it too.
- Is postgres-mcp safe to use?
- It is MIT-licensed and scores 97/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is postgres-mcp still maintained?
- The repository was last updated 8 days ago, so postgres-mcp is actively maintained.
Skill content
View source on GitHub@yawlabs/postgres-mcp
One click adds this to your local Yaw MCP config so it's available in every Yaw Terminal session. Or install manually below.
Query a PostgreSQL database from Claude Code, Cursor, and any MCP client. Read-only by default - writes opt in via a single env var - so an agent can't silently drop your tables.
Built and maintained by Yaw Labs.
What's new in 0.12
An index advisor, opt-in audit logging, structured tool output, and support for current-revision MCP clients. Full detail in the CHANGELOG.
pg_index_advisorrecommends indexes for a workload and keeps only the ones that measurably lower estimated cost. Candidates are costed with HypoPG hypothetical indexes, never created on disk, and the search knows that PostgreSQL 18's skip scan changes which multi-column indexes are useful.- Opt-in audit logging of the SQL tools send: one JSON line per audited statement, to stderr or a file. Bound parameter values are never recorded. Off by default, and not a complete record -- see Audit logging.
- Structured tool output. Every tool declares an
outputSchemaand returnsstructuredContentalongside the unchanged text block, so anything reading the text today keeps working. - Both MCP protocol eras. The server used to speak only the legacy (2025) protocol revisions, which a client on the current 2026-07-28 revision fails against. It now serves both.
On 0.12.0? Upgrade. 0.12.1 closes a stacked-query hole in pg_index_advisor: SQL passed in its statements argument ran on a protocol that accepts several commands in one string, so SELECT 1; COMMIT; DROP SCHEMA public CASCADE; escaped the read-only transaction. The tool is annotated read-only, so hosts often auto-allow it. The same release stops pg_inspect_locks attributing a lock held in another database to whichever local table shares its OID, fixes the advisor's greedy search, and makes audit lines carry the tool field they were missing.
Coming from 0.10.x? 0.11.0 has three breaking changes: pg_seq_scan_tables, pg_unused_indexes and pg_top_queries return an envelope (read data.rows where you used to read data), pg_explain with analyze: true emits BUFFERS (pass buffers: false for the old output), and Node 22 is the floor. Details in the 0.11.0 changelog entry.
Backstory
Anthropic's reference Postgres MCP server, @modelcontextprotocol/server-postgres, was archived in May 2025 and marked deprecated on npm in July 2025. Anthropic has not shipped a replacement. Despite the deprecation, the last published version (v0.6.2) is still pulled ~20,000 times per week - a lot of agents are pointed at an unmaintained package.
That unmaintained package also has a known, publicly documented stacked-query SQL injection (Datadog Security Labs) that bypasses its BEGIN READ ONLY wrapper with input like COMMIT; DROP SCHEMA public CASCADE;. It has never been patched at npm.
A handful of community forks have appeared, but each fills a narrow slice:
@zeddotdev/postgres-context-server- Zed's fork, primarily a security patch on the original shape.- Postgres MCP Pro (Crystal DBA) - focused on index tuning and hypothetical-index / buffer-cache diagnostics.
- AWS Labs Postgres MCP - tied to Aurora / RDS Data API + Secrets Manager.
None of them position themselves as a general-purpose daily driver you'd hand to Claude Code or Cursor against an arbitrary Postgres: modern introspection, perf helpers, role/privilege awareness, and a write-safety posture out of the box. That's the gap @yawlabs/postgres-mcp fills.
Why this one?
- Read-only by default, with an unconditional read-only tool too -
pg_queryruns user SQL in aBEGIN READ ONLYtransaction, so postgres itself (not string parsing) blocks writes; opt in to writes withALLOW_WRITES=1.pg_readonlyis a separate tool that stays read-only regardless ofALLOW_WRITES, so hosts that gate tools individually (Claude Code permissions, mcp.hosting) can auto-allow it -- paired with a least-privileged role, sinceREAD ONLYbounds writes to the database rather than every side effect (details). - Role-based access as the primary control - the recommended posture is to use a least-privileged postgres role in
DATABASE_URL(e.g. one withGRANT pg_read_all_data); postgres itself then enforces the boundary, no env var needed. See Configuring access. - Extended query protocol for all user SQL -
pg_querysends user input withqueryMode: 'extended', which restricts each request to a single statement. This closes the stacked-query injection class (COMMIT; DROP SCHEMA x CASCADE;) that defeated the reference server'sBEGIN READ ONLYwrapper. Integration test asserts the rejection. - Parameterized queries -
pg_querytakes aparamsarray for$1,$2, etc. No string-interpolated SQL in our code path. - Written from scratch, actively maintained - not a fork of the deprecated code. Unit + integration tests (
npm test,npm run test:integration) run against a real Postgres; releases cut viarelease.sh. - Schema introspection built in -
pg_list_schemas,pg_list_tables,pg_describe_tablereturn columns, primary keys, foreign keys, and indexes without the agent having to rememberpg_catalogjoins. EXPLAINas a first-class tool - text or JSON format, with optionalANALYZE. ANALYZE for non-SELECT statements requiresALLOW_WRITES=1and always rolls back, so the plan is real but the written rows don't persist. (What Postgres never rolls back still sticks: a sequence the statement advanced stays advanced.)- Perf diagnostics the deprecated server never had -
pg_top_queries(frompg_stat_statements),pg_seq_scan_tables,pg_unused_indexes,pg_table_bloat,pg_inspect_locks,pg_replication_status. Answer "why is this slow?" in one tool call. - Health snapshot -
pg_healthreturns version, db size, connection counts, and the 10 longest-running active queries in one call. - Role and privilege awareness -
pg_list_rolesandpg_table_privilegesfor the common "who can touch what?" questions. - Instant startup - ships as a single bundled file with zero runtime dependencies. No multi-minute
node_modulesinstall on everynpxcold start. - Result truncation - large result sets are capped at
POSTGRES_MAX_ROWS(default 1000) with atruncated: trueflag, so a straySELECT * FROM eventsdoesn't blow out the model context.
Quick start
1. Create .mcp.json in your project root
macOS / Linux / WSL:
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["-y", "@yawlabs/postgres-mcp@latest"],
"env": {
"DATABASE_URL": "postgres://user:password@host:5432/dbname"
}
}
}
}
Windows:
{
"mcpServers": {
"postgres": {
"command": "cmd",
"args": ["/c", "npx", "-y", "@yawlabs/postgres-mcp@latest"],
"env": {
"DATABASE_URL": "postgres://user:password@host:5432/dbname"
}
}
}
}
Why the extra step on Windows? Since Node 20,
child_process.spawncannot directly execute.cmdfiles (that's whatnpxis on Windows). Wrapping withcmd /cis the standard workaround.
2. Restart and approve
Restart Claude Code (or your MCP client) and approve the postgres MCP server when prompted.
3. (Optional) Enable writes
Read-only is the default. If you want the agent to be able to INSERT, UPDATE, DELETE, or run DDL, add ALLOW_WRITES=1 to the env block:
"env": {
"DATABASE_URL": "postgres://...",
"ALLOW_WRITES": "1"
}
Prefer scoping this to dev/test databases - for production, leave writes off and use migration tools out-of-band.
Configuring access
The role in DATABASE_URL is the primary access control. Postgres has had a battle-tested permission system for 30 years; lean on it instead of relying on ALLOW_WRITES alone. A least-privileged role makes writes server-rejected no matter what tools or env vars are configured.
Read-only agent (recommended default):
CREATE ROLE mcp_reader LOGIN PASSWORD 'change-me';
GRANT CONNECT ON DATABASE your_db TO mcp_reader;
GRANT USAGE ON SCHEMA public TO mcp_reader;
GRANT pg_read_all_data TO mcp_reader;
Point DATABASE_URL at mcp_reader. Postgres rejects every write, every DDL, every privilege change - regardless of ALLOW_WRITES. No app-level guard to bypass; the database is the boundary.
Scoped write agent (dev/test or narrow production use):
CREATE ROLE mcp_writer LOGIN PASSWORD 'change-me';
GRANT CONNECT ON DATABASE your_db TO mcp_writer;
GRANT USAGE ON SCHEMA public TO mcp_writer;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO mcp_writer;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO mcp_writer;
-- DDL not granted -- the agent can change data but not schema.
Set ALLOW_WRITES=1 so pg_query will issue writes, and rely on the role to keep the agent away from DDL and other schemas.
<a id="per-tool-gating-in-the-host"></a>Per-tool gating in the host:
Tools split cleanly across two authority classes:
- Auto-allow:
pg_readonly(server-sideBEGIN READ ONLY, unconditional),pg_index_advisor(only ever EXPLAINs the statements it is given, never with ANALYZE, insideBEGIN READ ONLY), plus the introspection and diagnostics tools (pg_list_*,pg_describe_table,pg_search_columns,pg_health,pg_inspect_locks,pg_table_bloat,pg_unused_indexes,pg_seq_scan_tables,pg_top_queries,pg_io_stats,pg_replication_status,pg_advisor,pg_table_privileges). - Always prompt:
pg_query(writes whenALLOW_WRITES=1is set and the role allows it),pg_explain(analyze: trueexecutes the statement; withALLOW_WRITES=1that includes writes, which are rolled back, and without it the tool has the same reach aspg_readonly),pg_kill(changes session state; requiresALLOW_WRITES=1).
The split follows each tool's readOnlyHint annotation, and Claude Code's permissions block and mcp.hosting's per-tool toggle both honor it.
What
READ ONLYdoes and does not cover. ABEGIN READ ONLYtransaction blocks writes to the database -- INSERT/UPDATE/DELETE, DDL,nextval/setval. It does not block functions whose effect lands outside the table data.SELECT pg_terminate_backend(...),pg_cancel_backend,pg_read_file,lo_export, andCOPY ... TO PROGRAMall run to completion insidepg_readonly, which means auto-allowingpg_readonlyreaches the same capability thatpg_killputs behindALLOW_WRITES=1. Every one of them still requires a privilege theDATABASE_URLrole must actually hold (pg_signal_backend,pg_read_server_files, superuser), so **the role is the contro
Truncated for display — read the full file on GitHub.
Related Skills
claude-mem
102.4kPersistent Context Across Sessions for Every Agent – Captures everything your agent does during sessions, compresses it with AI, and injects relevant context back into future sessions. Works with Claude Code, OpenClaw, Codex, Gemini, Hermes, Copilot, OpenCode + More
Agent-Reach
101.2kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
Understand-Anything
87.8kGraphs that teach > graphs that impress. Turn any code into an interactive knowledge graph you can explore, search, and ask questions about. Works with Claude Code, Codex, Cursor, Copilot, Gemini CLI, and more.
headroom
77.6kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
