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-<category>flags (or--enable-all). A server started with no enable flags advertises an empty tool list and rejects everytools/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-<category> 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"]
}
}
}
Why mcp-postgres?
Command-Line Options
Usage: mcp-postgres [OPTIONS]
Options:
-d, --database-url <URL> PostgreSQL connection string
-H, --host <HOST> TCP server host [127.0.0.1]
-p, --port <PORT> TCP server port [3000]
--http-port <PORT> HTTP/2 server port [3001]
--min-connections <N> Min pool connections [5]
--max-connections <N> Max pool connections [20]
--log-level <LEVEL> Log level [info]
--enable-metrics Prometheus /metrics endpoint
--metrics-port <PORT> Metrics port [9090]
--stdio Stdio mode (Claude Desktop)
--access-mode <MODE> unrestricted, restricted [unrestricted]
--tls-cert <PATH> PEM cert chain to serve HTTP over TLS (HTTPS)
--tls-key <PATH> 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.
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.
# 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-<category> 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) │
└──────────────────┘
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::ArrayQueuewithCachePaddedatomics. 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.
License
Apache-2.0