Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 47,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here

Works with

Claude CodeClaude DesktopCursorVS CodeClineCodex CLIOpenClaw+ any MCP client

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

A production-grade PostgreSQL Model Context Protocol (MCP) server.

README.md

MCPg

A production-grade Model Context Protocol server for PostgreSQL. Lets AI agents safely inspect, query, operate, and tune a Postgres database — 254 tools spanning catalog introspection, query intelligence, natural-language SQL, structural diffs, hybrid search, graph queries, data movement, live ops, and more.

![PyPI version](https://pypi.org/project/mcpg/) ![Python versions](https://pypi.org/project/mcpg/) ![License: MIT](https://github.com/devopam/MCPg/blob/main/LICENSE) ![CI](https://github.com/devopam/MCPg/actions/workflows/ci.yml) ![Stars](https://github.com/devopam/MCPg) ![smithery badge](https://smithery.ai/servers/devopam/mcpg) ![MCPg MCP server](https://glama.ai/mcp/servers/devopam/MCPg)

Try it live: point an MCP client — or the MCP Inspector — at the hosted, read-only demo endpoint https://devopam-mcpg-demo.hf.space/mcp. It serves read tools against throwaway demo data; for real use, run MCPg next to your own database (see Quick start).

📍 Listed On

---

| Aspect | MCPg | |---------------------|-----------------------------------| | Safety | Read-only default + AST validation | | Transport | stdio + HTTP/SSE | | Install | pip install mcpg | | Postgres Versions | 14–19 | | Key Differentiator | Production observability + multi-tenancy |

Why MCPg

  • Safe by default. Read-only access mode. Every user-supplied SQL

statement parses through a validated AST allowlist before execution. Identifier interpolation flows through a strict [A-Za-z_][A-Za-z0-9_]* regex — a design constraint that means user input never reaches the database through string concatenation. Capabilities like DDL, shell, and LISTEN/NOTIFY are off until you opt in. Every tool publishes MCP ToolAnnotations (readOnlyHint, openWorldHint) derived from those same gates, so clients can auto-approve reads and gate writes without guessing.

  • One server, broad surface. Application data access (queries, search,

cursors, NL→SQL) and DBA-grade operations (health checks, index tuning, EXPLAIN analysis, locks, vacuum, dumps, replicas, migrations) in a single MCP server. Agents don't have to switch tools to switch tasks.

  • PostgreSQL-native everything. No ORM, no abstraction tax — uses

psycopg3 directly, speaks every pg_* system view, integrates with TimescaleDB, pgvector, PostGIS, Apache AGE, and pg_stat_statements where they're available, and degrades gracefully when they aren't.

  • Production-shaped, not demo-shaped. Connection pooling, per-request

SET ROLE multi-tenancy, read-replica routing with degraded-host detection, server-side cursors with dedicated connections, rate-limiting, audit trail with regex redaction, PG TLS enforcement on startup, OIDC JWT bearer auth, per-session statement / lock timeouts.

  • Observability built in. Prometheus /metrics endpoint on the

HTTP transport surfaces mcpg_tool_calls_total{tool,status} + mcpg_tool_duration_seconds. Every tool call records a structured audit event with credential-redacted arguments.

  • Test-driven, multi-version. 2,500+ unit tests plus an integration

suite that runs against a real PostgreSQL container in CI — matrix covers PG 14, 15, 16, 17, 18 on every push, plus PG 19 (beta) as an experimental (non-blocking) entry tracked under issue #120.

---

Install

From PyPI (recommended)

pip install mcpg
# or, in an isolated venv exposed globally:
uv tool install mcpg

Verify:

mcpg --version

Docker

Pull the pre-built image from the GitHub Container Registry (published on every tagged release — :latest tracks the newest, or pin a version like :0.6.5):

docker pull ghcr.io/devopam/mcpg:latest
docker run --rm --name mcpg -p 8000:8000 \
    -e MCPG_DATABASE_URL=postgresql://user:pass@host:5432/db \
    -e MCPG_ACCESS_MODE=read-only \
    ghcr.io/devopam/mcpg:latest

On Windows PowerShell replace the trailing \ with a backtick ` `` (or put the command on one line); the installation guide has ready-to-copy Linux/macOS, PowerShell, and Command Prompt blocks.

Or build it yourself from source:

docker build -t mcpg https://github.com/devopam/MCPg.git

Multi-stage image: runtime stage drops the build toolchain, runs as uid=10001 / gid=10001 with nologin shell, application files root-owned and read-only to the runtime user.

From source (developers)

git clone https://github.com/devopam/MCPg && cd MCPg
uv sync

uv sync creates a venv with all runtime + dev dependencies and exposes the mcpg console script.

More detail in the Installation Guide.

---

Quick start

One-click installs: ![Add to Cursor](https://cursor.com/install-mcp?name=mcpg&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyJtY3BnIl0sImVudiI6eyJNQ1BHX0RBVEFCQVNFX1VSTCI6InBvc3RncmVzcWw6Ly91c2VyOnBhc3NAbG9jYWxob3N0OjU0MzIvbXlkYiJ9fQ%3D%3D) ![Install in VS Code](https://vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522mcpg%2522%252C%2522command%2522%253A%2522uvx%2522%252C%2522args%2522%253A%255B%2522mcpg%2522%255D%252C%2522env%2522%253A%257B%2522MCPG_DATABASE_URL%2522%253A%2522%2524%257Binput%253Adatabase_url%257D%2522%257D%252C%2522inputs%2522%253A%255B%257B%2522type%2522%253A%2522promptString%2522%252C%2522id%2522%253A%2522database_url%2522%252C%2522description%2522%253A%2522PostgreSQL%2520connection%2520URL%2520%2528postgresql%253A%252F%252Fuser%253Apass%2540host%253A5432%252Fdb%2529%2522%252C%2522password%2522%253Atrue%257D%255D%257D) ![Claude Desktop](https://github.com/devopam/MCPg/releases/latest) — setup for Windsurf, JetBrains, Zed, Cline, Antigravity, Qwen Code, Perplexity, ChatGPT, Copilot Studio, Continue, and HTTP clients in the integrations guide.

One-click install in Claude Desktop (.mcpb)

Download mcpg-<version>.mcpb from the latest release and double-click it (or drag it into Claude Desktop's Settings → Extensions). You'll be prompted for your PostgreSQL connection URL — stored in the OS keychain — and an access mode (defaults to read-only). That's the whole install: the bundle is ~2 kB and the host resolves the pinned mcpg release from PyPI for your platform.

Or wire it up manually (stdio transport)

Drop this into your claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json; Windows: %APPDATA%\Claude\claude_desktop_config.json):

{
  "mcpServers": {
    "mcpg": {
      "command": "uvx",
      "args": ["mcpg"],
      "env": {
        "MCPG_DATABASE_URL": "postgresql://user:pass@localhost:5432/mydb"
      }
    }
  }
}

Restart Claude Desktop. The MCPg toolset is now available to the model. You can ask Claude things like:

"What schemas exist in this database? For each one, summarise the three biggest tables."

"Why is this query slow? SELECT FROM orders WHERE customer_id = 42 ORDER BY created_at DESC"*

No interesting data yet? Seed the demo dataset

MCPG_DATABASE_URL=postgresql://... mcpg --demo

One command seeds a small, curated e-commerce dataset (3,000 orders, 900 product reviews, deliberately planted flaws) into an mcpg_demo schema — engineered so the index advisor, query-plan analysis, full-text search, PII audit, and graph projection all have something real to find on your first try. See the guided tour for a captured walkthrough, and remove it any time with mcpg --demo-drop.

Run as an HTTP server (for IDE integrations, web apps, etc.)

MCPG_DATABASE_URL=postgresql://user:pass@localhost:5432/mydb \
MCPG_TRANSPORT=streamable-http \
MCPG_HTTP_PORT=8000 \
mcpg

Then point any MCP-aware client at http://localhost:8000/mcp (or /sse for the SSE transport). Set MCPG_HTTP_AUTH_TOKEN=... for a static bearer, or MCPG_AUTH_MODE=oidc for full JWT validation against an OIDC issuer.

---

Configuration

MCPg is configured entirely through environment variables — no config file, no flags (the CLI's --version / --demo / --demo-drop are one-shot commands, not configuration). The only required one is MCPG_DATABASE_URL; everything else has a safe default.

Common scenarios

| Scenario | Set | |---|---| | Local exploration, read-only | MCPG_DATABASE_URL | | Read-write app data access | MCPG_ACCESS_MODE=restricted | | DBA toolkit (DDL, vacuum, etc.) | MCPG_ACCESS_MODE=unrestricted + MCPG_ALLOW_DDL=true | | HTTP transport with bearer auth | MCPG_TRANSPORT=streamable-http + MCPG_HTTP_AUTH_TOKEN=… | | Multi-tenant SaaS | MCPG_DEFAULT_ROLE=tenant_a + MCPG_ALLOWED_ROLES=tenant_a,tenant_b,… | | Read-replica fan-out | MCPG_REPLICA_URLS=postgresql://…?sslmode=require,postgresql://…?sslmode=require | | NL→SQL — single provider | Set any one vendor key (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, XAI_API_KEY, GROQ_API_KEY, HF_TOKEN, … — 22 built-in providers). MCPg auto-picks the default. | | NL→SQL — multiple providers, caller picks | Set all vendor keys you want active. Each call to translate_nl_to_sql can pass provider="…" (any configured built-in or custom). |

Full reference

Core

| Variable | Default | Description | |---|---|---| | MCPG_DATABASE_URL | required | Primary PostgreSQL DSN. Supports URI (postgresql://…) and keyword (host=… user=…) forms. Remote hosts require sslmode=require (or stronger). | | MCPG_ACCESS_MODE | read-only | read-only \| restricted (allows write tools) \| unrestricted (also unlocks DBA tools when paired with the gate vars). | | MCPG_TRANSPORT | stdio | stdio (default, for Claude Desktop) \| streamable-http \| sse. | | MCPG_LOG_LEVEL | INFO | DEBUG \| INFO \| WARNING \| ERROR \| CRITICAL. | | MCPG_HTTP_HOST | 127.0.0.1 | Bind address for HTTP transports. Set to 0.0.0.0 inside containers. | | MCPG_HTTP_PORT | 8000 | Listen port for HTTP transports (1–65535). |

Capability gates (opt-in for higher-blast-radius tools)

| Variable | Default | Description | |---|---|---| | MCPG_ALLOW_DDL | false | Expose DDL tools (run_ddl, create_graph, drop_graph, hypertable tools, migration tools). Requires MCPG_ACCESS_MODE=unrestricted. | | MCPG_ALLOW_SHELL | false | Expose subprocess-backed tools (dump_database, restore_database, run_pg_binary). Required PG client binaries must be on PATH. | | MCPG_ALLOW_LISTEN | false | Expose LISTEN/NOTIFY tools (subscribe_channel, poll_notifications, unsubscribe_channel, list_notification_subscriptions). |

Authentication (HTTP transports only)

| Variable | Default | Description | |---|---|---| | MCPG_AUTH_MODE | static | static (compare bearer to MCPG_HTTP_AUTH_TOKEN) \| oidc (full JWT validation). | | MCPG_HTTP_AUTH_TOKEN | — | Required bearer token when MCPG_AUTH_MODE=static. Constant-time compare. | | MCPG_OIDC_ISSUER | — | OIDC issuer URL (required when MCPG_AUTH_MODE=oidc). | | MCPG_OIDC_AUDIENCE | — | Expected aud claim (required when MCPG_AUTH_MODE=oidc). | | MCPG_OIDC_JWKS_URL | discovered | Override JWKS endpoint (auto-discovered from issuer's .well-known otherwise). | | MCPG_OIDC_ROLE_CLAIM | — | JWT claim whose value becomes the per-request PG role (SET LOCAL ROLE). Composes with the tenancy driver. |

HTTP hardening (HTTP transports only)

| Variable | Default | Description | |---|---|---| | MCPG_HTTP_MAX_BODY_BYTES | 1048576 | (1 MiB) Request bodies above this get a 413. Counts streamed bytes, so a missing/lying Content-Length can't bypass it. | | MCPG_HTTP_ALLOWED_ORIGINS | — | Comma-separated CORS allowlist. Unset = no CORS middleware (no cross-origin headers emitted). | | MCPG_HTTP_HSTS_MAX_AGE | 31536000 | Strict-Transport-Security max-age. 0 disables the HSTS header. Security headers (CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy) are always added unless the app already set them. | | MCPG_HTTP_REQUEST_TIMEOUT_SECONDS | 0 | Per-request wall-clock cap (504 on expiry). 0 = disabled. Leave off if you rely on long-lived SSE / streamable-http streams — a hard cap also severs those. |

Multi-tenancy (SET ROLE)

| Variable | Default | Description | |---|---|---| | MCPG_DEFAULT_ROLE | — | Static PG role applied to every query. Identifier-validated. | | MCPG_ALLOWED_ROLES | — | Comma-separated allowlist. When set, the X-MCPG-Role header / OIDC role claim must be in this list. |

Read replicas

| Variable | Default | Description | |---|---|---| | MCPG_REPLICA_URLS | — | Comma-separated replica DSNs. force_readonly queries round-robin across healthy replicas; primary fallback on failure; 30 s degraded-replica retry window. |

Multiple databases (read-only secondaries)

| Variable | Default | Description | |---|---|---| | MCPG_SECONDARY_DATABASE_URLS | — | Comma- or newline-separated name=dsn entries naming additional read-only databases this one server can serve (e.g. analytics=postgresql://…?sslmode=require,reporting=postgresql://…?sslmode=require). Read-capable tools accept an optional database argument selecting a secondary by name; omit it for the primary. Secondaries are read-only — PostgreSQL-enforced (every query runs in a READ ONLY transaction), so writes / DDL / shell / migrate always target the primary. Names must be simple identifiers ([a-z0-9_]+), unique, and not primary (the reserved id of MCPG_DATABASE_URL). Same TLS rules as the primary DSN. Call list_databases to discover the configured ids and their reachability. |

Pool / timeouts / TLS

| Variable | Default | Description | |---|---|---| | MCPG_POOL_MIN_SIZE | 1 | Minimum pool connections. | | MCPG_POOL_MAX_SIZE | 5 | Maximum pool connections. Must be ≥ MCPG_POOL_MIN_SIZE. | | MCPG_STATEMENT_TIMEOUT_MS | 30000 | Per-session statement_timeout set on connection checkout. Runaway queries self-terminate. | | MCPG_LOCK_TIMEOUT_MS | 5000 | Per-session lock_timeout. Hanging lock waits self-terminate. | | MCPG_ENABLE_ANALYTICAL_QUERIES | true | Expose run_analytical_query (long-running reads on an isolated pool). Set false to withdraw the tool. | | MCPG_ANALYTICAL_TIMEOUT_MS | 120000 | Default per-call budget for run_analytical_query (2 min). | | MCPG_ANALYTICAL_MAX_TIMEOUT_MS | 600000 | Hard ceiling for run_analytical_query; a per-call timeout_ms is clamped to this (10 min). Must be ≥ MCPG_ANALYTICAL_TIMEOUT_MS. | | MCPG_ANALYTICAL_MAX_CONCURRENCY | 2 | Size of the isolated analytical pool — max simultaneous run_analytical_query calls. | | MCPG_ALLOW_INSECURE_TLS | false | Bypass the startup TLS check that refuses remote DSNs without sslmode=require (or stronger). Loopback hosts are always exempt. | | MCPG_SHUTDOWN_DRAIN_SECONDS | 30 | On SIGTERM, wait up to this long for in-flight tool calls to finish before closing the pool and cursors. |

Subprocess tools (MCPG_ALLOW_SHELL=true only)

| Variable | Default | Description | |---|---|---| | MCPG_SHELL_TIMEOUT_SEC | 60 | Max wall-clock for pg_dump / pg_restore / psql invocations. | | MCPG_SHELL_MAX_OUTPUT_BYTES | 67108864 | (64 MiB) Cap on captured stdout per subprocess call. | | MCPG_SUBPROCESS_BIN_ALLOWLIST | — | Comma-separated absolute dirs the resolved pg_dump / pg_restore / psql must live under. Empty = trust PATH. Defeats a PATH-shim of these binaries. | | MCPG_SUBPROCESS_CPU_SECONDS | — | Per-child RLIMIT_CPU (seconds). POSIX only; unset = inherit. | | MCPG_SUBPROCESS_MEMORY_MB | — | Per-child RLIMIT_AS (MiB). POSIX only; unset = inherit. |

LISTEN/NOTIFY (MCPG_ALLOW_LISTEN=true only)

| Variable | Default | Description | |---|---|---| | MCPG_LISTEN_QUEUE_MAX | 1000 | Per-channel buffer; oldest notifications dropped on overflow. |

Audit

| Variable | Default | Description | |---|---|---| | MCPG_AUDIT_PERSIST | false | When true, every run_write / run_ddl call persists to a mcpg_audit.events table (auto-created idempotently). | | MCPG_AUDIT_REDACT_KEYS | — | Comma-separated regex fragments added to the secret-name pattern (defaults already cover password, passwd, secret, token, api[_-]?key, bearer, authorization, database_url, dsn, conninfo). | | MCPG_AUDIT_INTEGRITY | false | When true, each persisted event is signed with an HMAC chained over the previous event; the verify_audit_chain tool walks the chain and reports the first break. Requires MCPG_AUDIT_HMAC_KEY. | | MCPG_AUDIT_HMAC_KEY | — | Secret key for the audit HMAC chain. Required when MCPG_AUDIT_INTEGRITY=true. Never appears in repr/logs. |

Secrets backend

By default every secret is read straight from the environment. Set MCPG_SECRETS_BACKEND=file to instead load API keys / bearer token / HMAC key from a mounted file — a name in the file wins; anything absent falls back to the env var, so partial files work.

| Variable | Default | Description | |---|---|---| | MCPG_SECRETS_BACKEND | env | env (read every secret from the environment) \| file (overlay a secrets file on top of the environment). | | MCPG_SECRETS_FILE_PATH | — | Required when MCPG_SECRETS_BACKEND=file. Path to a flat name → value map: JSON always, or YAML (.yaml/.yml) when PyYAML is installed. Covers ANTHROPIC_API_KEY / OPENAI_API_KEY / GEMINI_API_KEY / GOOGLE_API_KEY / MCPG_NL2SQL_API_KEY, MCPG_HTTP_AUTH_TOKEN, and MCPG_AUDIT_HMAC_KEY. |

Rate limiting

| Variable | Default | Description | |---|---|---| | MCPG_RATE_LIMIT_ENABLED | false | Enable token-bucket per-tool rate limiting. | | MCPG_RATE_LIMIT_MAX_REQUESTS | 60 | Global cap per window across all tools. | | MCPG_RATE_LIMIT_WINDOW_SECONDS | 60 | Window length for the global quota. | | MCPG_RATE_LIMIT_HEAVY_MAX | 5 | Cap for heavy tools (run_write, run_ddl, dump_database, etc.). | | MCPG_RATE_LIMIT_HEAVY_WINDOW | 60 | Window length for the heavy-tool quota. |

Caching & Feature flags

| Variable | Default | Description | |---|---|---| | MCPG_CACHE_ENABLED | true | Enable or disable the adaptive cache layer. | | MCPG_CACHE_TTL_SECONDS | 300 | Default cache Time-To-Live in seconds. | | MCPG_CACHE_MAXSIZE | 1024 | Maximum LRU capacity bound for the memory cache. | | MCPG_REDIS_URL | — | Optional Redis backend connection string for external, multi-node caching. | | MCPG_ENABLE_HEAVY_DIAGNOSTICS | true | Toggle computationally heavy diagnostic, diagram, and advisor tools. |

Natural-language SQL

MCPg auto-discovers every configured provider from the environment at startup — set as many vendor keys as you have and each becomes callable. Nineteen providers ship built in. Three are first-party (Anthropic, OpenAI, Gemini); the other sixteen speak the OpenAI-compatible API with vendor-preset endpoints: DeepSeek, Qwen, OpenRouter, Perplexity, xAI (Grok), Groq, Mistral, Together, Fireworks, DeepInfra, Cerebras, Nebius, Hugging Face, GitHub Models, SambaNova, and Moonshot (Kimi). Every built-in is plug-and-play — set the vendor's conventional API-key env var and it's auto-discovered — and *any other OpenAI-compatible vendor or local model server (Ollama, vLLM, LM Studio) is still pluggable through configuration alone* via MCPG_NL2SQL_CUSTOM_PROVIDERS. The whole built-in list is one declarative registry in nl2sql.py, so adding a vendor or refreshing a retired default model is a one-line data change.

When MCPG_NL2SQL_PROVIDER is unset, MCPg auto-picks the default in registry order — anthropic → openai → gemini stay first so existing deployments are unaffected. translate_nl_to_sql accepts an optional provider="…" argument to route per call; get_server_info reports which are configured.

| Variable | Default | Description | |---|---|---| | <VENDOR>_API_KEY | — | Setting a vendor's conventional key enables that provider. Standard slugs: ANTHROPIC_API_KEY, OPENAI_API_KEY, DEEPSEEK_API_KEY, OPENROUTER_API_KEY, PERPLEXITY_API_KEY, XAI_API_KEY, GROQ_API_KEY, MISTRAL_API_KEY, TOGETHER_API_KEY, FIREWORKS_API_KEY, CEREBRAS_API_KEY, NEBIUS_API_KEY, SAMBANOVA_API_KEY, MOONSHOT_API_KEY. | | (keys that deviate) | — | A few vendors don't follow <VENDOR>_API_KEY: GeminiGEMINI_API_KEY or GOOGLE_API_KEY; QwenDASHSCOPE_API_KEY or QWEN_API_KEY; Hugging FaceHF_TOKEN; GitHub ModelsGITHUB_TOKEN; DeepInfraDEEPINFRA_TOKEN. | | MCPG_NL2SQL_PROVIDER | auto-picked | Any built-in slug (listed above) or a custom name. Pins the default provider used when the tool is called without provider=. Unset + any vendor key present → MCPg auto-picks in registry order. | | MCPG_NL2SQL_API_KEY | — | Explicit key for the configured MCPG_NL2SQL_PROVIDER. Overrides the vendor-conventional env var for that provider only. Requires MCPG_NL2SQL_PROVIDER to be set. | | MCPG_NL2SQL_MODEL | provider default | Override the default model (e.g. claude-sonnet-4-6, gpt-4o-mini, grok-3-mini). Applies only to the default provider. | | MCPG_NL2SQL_BASE_URL | — | Endpoint override for the default provider (private gateways / regional endpoints). | | MCPG_NL2SQL_CUSTOM_PROVIDERS | — | Bring your own provider — no code change. Comma/newline-separated name=base_url\|model entries declaring extra OpenAI-compatible providers beyond the built-ins (local Ollama / vLLM / LM Studio, or any niche vendor). Key from <NAME>_API_KEY by convention, or append \|KEY_ENV_VAR for ones that deviate; keyless allowed for loopback endpoints. Each name becomes callable via provider=. | | MCPG_NL2SQL_MAX_TOKENS | 2048 | Cap on generated tokens (hard limit: 16384). |

---

Usage examples

The MCP tools are invoked by the agent (Claude, Cursor, Continue, …) in response to your natural-language instructions. A handful of illustrative round-trips:

Inspect the schema

You: What tables live in the public schema, and which ones are the biggest by row count?

Agent (using list_tables + summarize_table × N): Six tables: customers (1.2M rows), orders (4.7M), line_items (18.3M), products (340), addresses (1.4M), audit_log (45.8M — the largest, accumulates without retention).

Diagnose a slow query

You: Why does SELECT * FROM orders o JOIN line_items l ON o.id = l.order_id WHERE o.created_at > now() - interval '7 days' take 8 seconds?

Agent (using why_is_this_slow + recommend_indexes): EXPLAIN ANALYZE shows a sequential scan over orders (4.7M rows) filtered by created_at. There's no index on orders.created_at. Recommended: CREATE INDEX CONCURRENTLY orders_created_at_idx ON orders (created_at DESC); Expected improvement: ~95% reduction (index scan touches ~33K rows instead of full table). Run validate_migration on it before applying to confirm there's no locking surprise.

Translate plain English to SQL

You: Find customers who placed an order this month but never in the previous three months — show me their email and current lifetime spend.

Agent (using translate_nl_to_sql): ``sql SELECT c.email, SUM(l.price * l.quantity) AS lifetime_spend FROM customers c JOIN orders o ON o.customer_id = c.id JOIN line_items l ON l.order_id = o.id WHERE EXISTS ( SELECT 1 FROM orders o2 WHERE o2.customer_id = c.id AND o2.created_at >= date_trunc('month', now())) AND NOT EXISTS ( SELECT 1 FROM orders o3 WHERE o3.customer_id = c.id AND o3.created_at >= date_trunc('month', now()) - interval '3 months' AND o3.created_at < date_trunc('month', now())) GROUP BY c.email; ``

Picture the schema

You: Draw me an ER diagram of the public schema.

Agent (using generate_schema_diagram): Returns a Mermaid diagram you can paste straight into GitHub / Notion / Obsidian.

Audit the database

You: How healthy is this database right now?

Agent (using audit_database): Returns a graded report: Memory & I/O score 92 (GOOD), Transaction & Connection 78 (WARNING: rollback rate 0.4%, look at app logs), Concurrency & Locks 60 (CRITICAL: 14 backends waiting), Cleanliness & Bloat 88 (GOOD), Slow queries 70 (WARNING: top query template runs 5000×, mean 90 ms — see optimize_query).

Run a guarded write

You: Soft-delete every order older than 5 years.

Agent (using run_write with MCPG_AUDIT_PERSIST=true): Validates the statement through the safe-SQL kernel, runs it inside a transaction, returns affected row count, persists the call (sql + arguments — with secrets regex-redacted — + status) to mcpg_audit.events for after-the-fact review.

For dozens more recipes — multi-tenant routing, RLS testing, NL→SQL, hybrid vector + FTS search, Apache AGE Cypher, TimescaleDB, ORM schema exports, server-side cursors — see docs/cookbook.md.

---

What's in the box

Compact category list. For the full, current tool reference see docs/tools.md; for a guided walkthrough see docs/tour.md.

  • Catalog introspection — schemas, tables, columns, indexes,

constraints, views, functions, triggers, sequences, partitions, policies, roles, grants, enums, domains, composite types, FDWs, publications, subscriptions, extensions, generated columns.

  • Query intelligencerun_select, run_select_parallel,

explain_query, analyze_query_plan, why_is_this_slow, recommend_indexes, analyze_workload, check_database_health, detect_n_plus_one, audit_database.

  • Searchfuzzy_search (trigram), full_text_search,

vector_search, hybrid_search (pgvector + FTS via RRF), geo_search (PostGIS k-NN).

  • Natural language → SQLtranslate_nl_to_sql (22 built-in

providers — Anthropic, OpenAI, Gemini, xAI, Groq, Mistral, Hugging Face, … — plus any custom OpenAI-compatible endpoint; output passes through the same safe-SQL kernel as hand-written queries).

  • Visualisationgenerate_schema_diagram (ER),

generate_fk_cascade_graph (blast-radius of ON DELETE CASCADE), generate_graph_diagram (Apache AGE property graphs).

  • Structural diff & migrationscompare_schemas,

validate_migration, staged prepare_migration / complete_migration / cancel_migration workflow.

  • Apache AGE graph + Cypherlist_graphs, describe_graph,

run_cypher, create_graph, drop_graph, generate_graph_diagram.

  • Composite + advisor toolssummarize_table,

find_unused_objects, find_sensitive_columns (PII heuristic), lint_naming_conventions, test_rls_for_role, list_locks, find_blocking_chains, read_pg_stat_io (PG16+), generate_test_data.

  • Live ops & maintenancelist_active_queries,

verify_connection_encryption (TLS status of the live link), run_maintenance (VACUUM/ANALYZE), prune_audit_events (audit retention), cancel_query, terminate_backend, run_write, run_ddl, enable_extension.

  • Data movementexport_query / export_table (CSV/JSON),

dump_database / restore_database, import_csv / import_json (COPY FROM STDIN), copy_table_between_databases.

  • Server-side cursorsopen_cursor, fetch_cursor,

close_cursor, list_cursors for pageable reads over millions of rows.

  • TimescaleDBlist_hypertables, list_chunks,

create_hypertable, add_compression_policy, add_retention_policy.

  • ORM schema exporters — Prisma, Drizzle, SQLAlchemy, sqlc,

Diesel, jOOQ, Ent, Ecto.

  • Event streamssubscribe_channel, poll_notifications,

unsubscribe_channel, list_notification_subscriptions bridging PostgreSQL LISTEN/NOTIFY into the MCP poll model.

  • Observability — Prometheus /metrics endpoint +

get_metrics_exposition tool for stdio; structured audit trail with regex-based credential redaction.

---

Documentation

---

Security

coordinated-disclosure window; reports to devopam@gmail.com.

  • Defence-in-depth: capability gates, SafeSQL kernel, identifier

allowlist, audit redaction, PG TLS enforcement at startup, rate-limiting, OIDC JWT validation, per-session timeouts.

the living roadmap of shipped (✅) and queued (⬜) hardening items.

Privacy Policy

MCPg is self-hosted: your database contents never leave your infrastructure, and there is no telemetry or phone-home of any kind. The one documented exception is the opt-in translate_nl_to_sql tool, which sends your question plus schema context (names, not row data) to the LLM provider you configure. Full policy — data collection, usage, storage, third-party sharing, retention, and contact — is in PRIVACY.md.

---

Release notes & changelog

See CHANGELOG.md for the full version history, docs/release-process.md for how releases are cut, and the GitHub Releases page for downloadable artifacts.

---

Contributing

Pull requests welcome — see CONTRIBUTING.md for the dev-loop setup, test conventions, and the per-PR review checklist.

---

License

MIT — see LICENSE. The SQL-safety kernel (src/mcpg/sql/) is first-party, re-authored from the MIT-licensed crystaldba/postgres-mcp; see NOTICE for the lineage.

Wrapped extensions — licenses you should know about

MCPg's source is MIT, but the PostgreSQL extensions it wraps each carry their own license. The wrappers themselves are at arm's length (SQL-level calls, no static or dynamic linking into MCPg's Python process), so MCPg-the-project is not a derivative work of any of them. Operators deploying a service built on MCPg + a given extension take on whatever obligations that extension's license imposes — same as installing the extension directly. The matrix below names the license per wrapped extension so you can make an informed choice.

| Extension | License | Notes for operators | |---|---|---| | pgvector | PostgreSQL License (BSD-style) | Permissive; no special obligations. | | pg_partman | PostgreSQL License | Permissive. | | pg_cron | PostgreSQL License | Permissive. | | pg_turboquant | MIT | Permissive. | | pg_buffercache / pg_walinspect / pgstattuple | PostgreSQL contrib | Permissive. | | TimescaleDB | Apache 2.0 (community) + Timescale License (TSL, source-available) for some features | Mixed — see Timescale's docs for which features are TSL-gated. | | Apache AGE | Apache 2.0 | Permissive. | | pg_search (ParadeDB) | AGPL-3.0 | Operators running a network service that lets users interact with pg_search are subject to AGPL's network clause — typically the obligation to offer the source of pg_search (and any modifications) to those users. MCPg's wrappers don't extend that obligation to MCPg itself; you take on the obligation when you deploy and "convey" the extension over a network. If your service redistribution model is incompatible with AGPL's network clause, pick a different BM25 implementation (the BM25 plan lists alternatives). |

This matrix is a starting point — for the binding answer on your specific deployment, consult the extension's upstream LICENSE file and (if it matters legally) your own counsel.

Disclaimer. Best efforts have been made to bring MCPg to production grade, but it remains an actively developed project and may contain issues. See the License terms for indemnity details.

<!-- mcp-name: io.github.devopam/mcpg -->

See related servers & alternatives →

Related MCP servers

Browse all →

Related guides

Hand-picked reading to help you choose and use Databases servers.