CM

corporatepiyush/mcp-pg-rust

Developer tools
22 stars 0 forks Quality 53 Trend 31

Postgresql MCP server written in Rust

Overview

is a high-performance MCP server that brings PostgreSQL into Claude Desktop and any MCP-compatible AI tool. 133 PostgreSQL tools, lock-free connection pooling, sub-10ms latency. No tools are exposed by default. You enable them one category at a time with --enable- flags (or --enable-all). A server started with no enable flags advertises an tool list and rejects every tools/call. See Tool Exposure. One of four high-performance MCP servers written in Rust — mcp-postgres · mcp-filesystem · mcp-memory · mcp-web-search. All implement MCP protocol revision . Tools are opt-in — pass one or more --enable- flags (or --enable-all). Without them the server exposes no tools. The HTTP/2 transport can be served over TLS (rustls, ring provider — the same provider used for sslmode-gated PostgreSQL connections, no OpenSSL/aws-lc).

README

mcp-postgres

mcp-postgres is a high-performance MCP server that brings PostgreSQL into Claude Desktop and any MCP-compatible AI tool. 133 PostgreSQL tools, lock-free connection pooling, sub-10ms latency.

Tools are opt-in (5.2.0+). No tools are exposed by default. You enable them one category at a time with --enable- flags (or --enable-all). A server started with no enable flags advertises an empty tool list and rejects every tools/call. See Tool Exposure.

MCP suite. One of four high-performance MCP servers written in Rust — mcp-postgres · mcp-filesystem · mcp-memory · mcp-web-search. All implement MCP protocol revision 2025-11-25.

Quick Start

Install

# From crates.io
cargo install mcp-postgres

# Or from Homebrew (macOS)
brew tap corporatepiyush/mcp-postgres
brew install mcp-postgres

Run

Tools are opt-in — pass one or more --enable- flags (or --enable-all). Without them the server exposes no tools.

# Stdio mode (for Claude Desktop) — expose read-only query + schema tools
mcp-postgres --database-url "postgres://user:pass@localhost:5432/mydb" --stdio \
  --enable-query --enable-schema

# TCP server (port 3000) — expose everything
mcp-postgres --database-url "postgres://user:pass@localhost:5432/mydb" --enable-all

# HTTP/2 server (port 3001) — query + monitoring only
mcp-postgres --database-url "postgres://user:pass@localhost:5432/mydb" --http-port 3001 \
  --enable-query --enable-monitoring

Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "postgres": {
      "command": "mcp-postgres",
      "args": ["--database-url", "postgres://user:pass@localhost:5432/mydb", "--stdio", "--enable-all"]
    }
  }
}

Complete setup guide →


Why mcp-postgres?

Feature mcp-postgres DIY / psql
133 purpose-built tools Schema inspection, DDL, monitoring, replication, batch ops, security audit, text search, extensions, maintenance, and more You build every query from scratch
Lock-free connection pool Zero-mutex crossbeam::ArrayQueue — pure CAS loops, no kernel overhead Deadpool or manual Mutex
Dual-protocol TCP (3000) + HTTP/2 (3001) + stdio — one binary, three transports Multiple servers to wire up
Sub-10ms latency Allocated for AI interactivity — hot path is allocation-free Unpredictable
SQL injection prevention Every identifier validated, quote_ident sanitization, structured predicates Manual parameterization
PG version-aware Queries verified against PG 16–18 docs, graceful fallbacks for version differences Version-specific failures

Command-Line Options

Usage: mcp-postgres [OPTIONS]

Options:
  -d, --database-url        PostgreSQL connection string
  -H, --host               TCP server host             [127.0.0.1]
  -p, --port               TCP server port             [3000]
      --http-port          HTTP/2 server port          [3001]
      --min-connections       Min pool connections        [5]
      --max-connections       Max pool connections        [20]
      --log-level         Log level                   [info]
      --enable-metrics           Prometheus /metrics endpoint
      --metrics-port       Metrics port                [9090]
      --stdio                    Stdio mode (Claude Desktop)
      --access-mode        unrestricted, restricted    [unrestricted]
      --tls-cert           PEM cert chain to serve HTTP over TLS (HTTPS)
      --tls-key            PEM private key matching --tls-cert

  Tool exposure (none enabled by default — see "Tool Exposure"):
      --enable-all               Expose every category (overrides the flags below)
      --enable-query             Query: execute/explain/async-execute + sampling
      --enable-batch             Batch: bulk insert/update/delete + COPY
      --enable-schema            Schema: read-only inspection + DDL generation
      --enable-ddl               DDL: create/drop/alter/rename objects
      --enable-admin             Admin: vacuum/reindex/analyze/truncate + sessions
      --enable-monitoring        Monitoring: stats, conns, txns, replication, config
      --enable-security          Security: roles, users, privileges, audits
      --enable-data-io           Data I/O: CSV export + URL/file import
      --enable-extensions        Extensions: pgvector, TimescaleDB, BM25, ext mgmt

  -h, --help                     Print help
  -V, --version                  Print version

TLS (HTTPS)

The HTTP/2 transport can be served over TLS (rustls, ring provider — the same provider used for sslmode-gated PostgreSQL connections, no OpenSSL/aws-lc). Provide a PEM certificate chain and private key via --tls-cert/--tls-key or the MCP_TLS_CERT/MCP_TLS_KEY environment variables and the HTTP server speaks HTTPS instead of plaintext. The two must be supplied together or startup is refused; when neither is set the HTTP transport stays plaintext (the default). The raw TCP transport is unaffected.

mcp-postgres --http-port 3001 --tls-cert ./cert.pem --tls-key ./key.pem

MCP Compliance

Implements the Model Context Protocol revision 2025-11-25 over JSON-RPC 2.0, via TCP, HTTP/2, or stdio.

Area Support
Transports stdio, TCP (3000), HTTP/2 (3001)
Protocol version 2025-11-25, negotiates down to 2025-06-18 / 2025-03-26 / 2024-11-05
initialize ✅ version negotiation + instructions
tools/list, tools/call ✅ (133 tools)
CallToolResult ✅ content[] + structuredContent + isError
Capabilities advertised tools only — nothing is advertised that isn’t implemented
resources · prompts · logging · completion ❌ roadmap — see MIGRATION.md

Request:

{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": { "name": "list_tables", "arguments": {} },
  "id": 1
}

Result — a spec-compliant CallToolResult. The payload is available as a machine-readable structuredContent object and as serialized text; tool failures come back with isError: true (not as JSON-RPC protocol errors) so the model can self-correct:

{
  "content": [{ "type": "text", "text": "{\"tables\":[\"users\",\"orders\"]}" }],
  "structuredContent": { "tables": ["users", "orders"] },
  "isError": false
}

Upgrading from 4.x? The result shape changed — see MIGRATION.md.


Tool Exposure (opt-in by category)

Every tool belongs to exactly one of 9 categories. Nothing is exposed until you enable its category at startup — disabled tools are hidden from tools/list and rejected from tools/call as if they did not exist. This lets you hand an agent precisely the surface area it needs (e.g. read-only query + monitoring) and nothing more.

Flag Category What it exposes
--enable-query Query execute_query, execute_insert/update/delete, async_execute_*, explain_query, sample_data
--enable-batch Batch async_batch_insert/update/delete, async_batch_insert_copy
--enable-schema Schema (read) list_tables, describe_table, list_indexes/schemas/triggers/partitions, show_constraints, get_object_details, list_databases, table_dependencies, generate_create_*_ddl
--enable-ddl DDL (write) create/drop/alter table·view·schema·sequence·index·partition, backup_table, add/drop/rename_column, alter_column_type, rename_table/index/schema, FK & constraint ops, clone_table_schema, create_database
--enable-admin Admin vacuum, vacuum_full, vacuum_analyze, analyze_table, reindex_table/database, reset_statistics, truncate_table, cancel_query, terminate_connection
--enable-monitoring Monitoring (read) table/index stats, sizes, cache ratio, pg_stat_statements, connections, running/blocked queries, transactions, locks, deadlocks, replication, WAL, settings, health checks, suggest_indexes, bloat
--enable-security Security list/create/alter/drop_user, role ops, grant/revoke_privileges, privilege listings
--enable-data-io Data I/O export_csv, import_from_url (also gated behind --allow-url-import)
--enable-extensions Extensions pgvector (vector_search, create_vector_index, list_vector_columns), TimescaleDB (create_hypertable, show_chunks, retention/compression policies, continuous aggregates), BM25 full-text, and generic create/drop/list_extension
--enable-all (all of the above) Every category. Overrides the individual flags.
# Read-only analyst: inspect schema and run SELECTs, nothing else
mcp-postgres -d "$DATABASE_URL" --stdio --enable-query --enable-schema --enable-monitoring

# Full access
mcp-postgres -d "$DATABASE_URL" --stdio --enable-all

Category gating composes with the existing --access-mode restricted (which additionally blocks all write tools) and --allow-url-import controls.


Tools (133 Total)

The headings below are the human-readable groupings. To map each one to the --enable- flag that exposes it, see the Tool Exposure table above.


Performance

Lock-Free Connection Pool (v4.0.0)

No mutexes. No semaphores. Just CAS loops.

┌─────────────┐     ┌──────────────────┐     ┌─────────────┐
│  Task 1     │     │  crossbeam::     │     │  Task 2     │
│  (acquire)  │────▶│  ArrayQueue      │◀────│  (release)  │
└─────────────┘     │  CachePadded     │     └─────────────┘
                    │  Head/Tail       │
                    │  (CAS only)      │
                    └──────────────────┘
Metric Deadpool (v3.x) LockFreePool (v4.0.0)
Lock acquisitions per acquire+release 3+ (Mutex + Semaphore) 0
Allocation on hot path Yes (VecDeque growth) Zero (pre-allocated)
False sharing Likely (adjacent fields) Cache-padded atomics
Inlining Cross-crate, opaque Monomorphic, LTO-friendly
Dependencies 2 (deadpool + deadpool-postgres) 0 external (crossbeam already in tree)

Sub-10ms latency is guaranteed by design: zero allocation on the hot path, monomorphic dispatch, cache-line-isolated atomics, and a single-pointer CAS for connection handoff.

Architecture

┌─────────────────┐         ┌─────────────────┐
│   TCP Client    │         │   HTTP Client   │
│  (port 3000)    │         │  (port 3001)    │
└────────┬────────┘         └────────┬────────┘
         └─────────────┬─────────────┘
                       │
              ┌────────┴────────┐
              │   JSON-RPC 2.0  │
              │  (MCP Protocol) │
              └────────┬────────┘
                       │
          ┌────────────┴────────────┐
           │   Tool Dispatcher       │
           │   (133 tools)           │
          └────────────┬────────────┘
                       │
          ┌────────────┴────────────┐
          │   Connection Pool       │
          │   (lock-free, CAS-only) │
          │   Min: 5, Max: 20       │
          └────────────┬────────────┘
                       │
              ┌────────┴────────┐
              │  PostgreSQL DB  │
              └─────────────────┘

Key Design Principles

  • Stateless HTTP — Each request is independent. Transaction state isolated per-connection.
  • Lock-free pooling — crossbeam::ArrayQueue with CachePadded atomics. Zero mutex acquisitions.
  • Input validation at the boundary — SQL capped at 10K chars, identifiers at 255, batch rows at 1K. SQL injection prevention via quote_ident.
  • PG version-aware queries — Verified against PG 16–18. Graceful fallbacks when views/columns differ across versions.

Versioning & Compatibility

Follows Semantic Versioning. The current line is 5.x, which targets MCP revision 2025-11-25. The 5.0.0 release changed the tools/call result shape to be spec-compliant — see MIGRATION.md and the CHANGELOG.

mcp-postgres MCP revision (default) Negotiates
5.x 2025-11-25 2025-06-18, 2025-03-26, 2024-11-05
≤ 4.x 2024-11-05 —

License

Apache-2.0

Support

GitHub Issues

View the full README on GitHub

Install

This server does not publish a one-line install command.

Open the repository installation guide New to MCP? Start with the mcpskill.org guide →

Configuration

{ "mcpServers": { "postgres": { "command": "mcp-postgres", "args": ["--database-url", "postgres://user:pass@localhost:5432/mydb", "--stdio", "--enable-all"] } } }