~/web4w3psql-mcp-serverMCP Server
psql-mcp-server — README.md
cat README.md

# psql MCP Server

An MCP server that wraps the PostgreSQL psql CLI, giving AI clients the full backslash-command surface of psql — schema inspection, queries, EXPLAIN plans, COPY, roles, extensions — behind a small, risk-classified tool set. Every operation shells out to the real psql binary; this is a process wrapper, not a driver. Read-only by default: writes, local file I/O, and shell escapes are all disabled unless explicitly enabled.

cat psql-mcp-server/ARCHITECTURE.md

## How It Works

Every tool call shells out to the real psql binary rather than reimplementing a driver. Plain SQL sent to run_query runs with default_transaction_read_only=on, so PostgreSQL itself — not a regex — rejects any write attempt. On psql 18+, SQL is prefixed with a per-call \restrict key that disables every backslash command until a matching \unrestrict, so a \! smuggled inside a string or comment can't execute without guessing the key. Capabilities (writes, file I/O, shell) default to off and can be scoped per named connection, so a single config can keep dev writable and prod permanently read-only.

MCP Client (Claude) ──stdio──▶ psql MCP Server (Node.js)
                                       └── Risk classifier (safe/writes/fileIo/shell/session)
                                       └── spawn: psql ──▶ PostgreSQL
                                              └── \restrict guard (psql 18+)
                                              └── read-only session (run_query)
psql-mcp-server --demo

## Screenshots

psql-mcp — schema inspection
  list_objects  kind=table

   SCHEMA    NAME          KIND
   ──────────────────────────────
   public    users         table
   public    orders        table
   public    order_items   table

  describe_object  name=orders
   ✓  4 columns · 1 primary key · 2 indexes · 1 FK → users
psql-mcp — guarded write attempt
  run_query  sql="DELETE FROM orders WHERE id = 42"
   ✗  Rejected: session is read-only (default_transaction_read_only=on)

  run_statement  sql="DELETE FROM orders WHERE id = 42"  connection=dev
   ✗  Rejected: allowWrites is false for connection 'dev'

   (enable PSQL_MCP_ALLOW_WRITES to permit — off by default)
grep -n "## Features" psql-mcp-server/README.md

## Features

  • +Every backslash command classified by risk (safe / writes / fileIo / shell / session)
  • +Read-only by default — writes, file I/O, and shell escapes opt-in per connection
  • +\restrict-based injection protection on psql 18+ (scans for embedded commands on older versions)
  • +Full schema inspection: tables, views, functions, roles, extensions, definitions
  • +psql_meta escape hatch reaches every documented psql backslash command
  • +Named multi-connection registry — keep prod hard-read-only while allowing writes on dev
psql-mcp-server --compare

## vs. The Field

Featurepsql MCP ServerDirect pg driverDBeaver / pgAdmin
MCP protocol native
Read-only by default
SQL-injection-safe backslash guard✓ (\restrict)n/an/a
No GUI required
Per-connection write scopingpartial
cd psql-mcp-server && cat INSTALL.md

## Installation

1

Install psql client tools

macOS: brew install libpq (set PSQL_MCP_PSQL_PATH if not on PATH). psql 18+ recommended for \restrict support.

2

Install

No cloning or build step needed.

npx -y @web4w3/psql-mcp-server
3

Add to your MCP client config

Simplest setup — a single database, read-only.

{
  "mcpServers": {
    "psql": {
      "command": "npx",
      "args": ["-y", "@web4w3/psql-mcp-server"],
      "env": {
        "DATABASE_URL": "postgres://user:password@host:5432/dbname"
      }
    }
  }
}

For multiple named connections with per-connection write scoping, use PSQL_MCP_CONNECTIONS instead of DATABASE_URL.

cat psql-mcp-server/package.json | jq '.dependencies | keys'

## Tech Stack

Node.jsTypeScriptpsql CLIMCP SDK