Skip to the content.

MCPg Installation Guide

How to install, configure, and verify MCPg. The complete MCPG_* environment-variable reference lives in the README; this guide focuses on getting a working install and the most common configuration paths.


Prerequisites


Install

pip install mcpg

Or, with uv’s globally-isolated tool install:

uv tool install mcpg

Either path puts an mcpg console script on your PATH and pulls the runtime dependencies (mcp[cli], psycopg[binary], psycopg-pool, pglast, httpx, pyjwt[crypto]).

Verify the install:

mcpg --version
# → mcpg 0.6.10

Option 2 — Docker

Build the image (identical on every OS):

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

Then run it. The only per-OS difference is the line-continuation character — pick the block for your shell:

Linux / macOS (bash/zsh)

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

Windows (PowerShell)

docker run --rm --name mcpg -p 8000:8000 `
    -e MCPG_DATABASE_URL=postgresql://user:pass@host:5432/db `
    -e MCPG_ACCESS_MODE=read-only `
    mcpg

Windows (Command Prompt)

docker run --rm --name mcpg -p 8000:8000 -e MCPG_DATABASE_URL=postgresql://user:pass@host:5432/db -e MCPG_ACCESS_MODE=read-only mcpg

The image is a hardened multi-stage build: the runtime stage drops the build toolchain and runs as uid=10001 / gid=10001 with a nologin shell. Application files are root-owned and read-only to the runtime user.

Option 3 — From source (developers)

git clone https://github.com/devopam/MCPg && cd MCPg
uv sync
uv run mcpg --version

uv sync creates a virtual environment with all runtime + dev dependencies. Pick this path to follow main, run the test suite, or contribute.


Quick start

MCPg is configured entirely through environment variables, and the only per-OS difference in this whole guide is how you set them. The mcpg command itself, pip, uv, and docker are identical on every platform. Set variables like this:

Shell Set a variable
Linux / macOS (bash/zsh) export MCPG_DATABASE_URL=postgresql://…
Windows — PowerShell $env:MCPG_DATABASE_URL = "postgresql://…"
Windows — Command Prompt set MCPG_DATABASE_URL=postgresql://…

Every export … example below uses the Linux/macOS form; translate it to your shell with the table above.

The minimum to get running locally (stdio transport, read-only mode):

Linux / macOS (bash/zsh)

export MCPG_DATABASE_URL=postgresql://postgres:postgres@localhost:5432/mydb
mcpg

Windows (PowerShell)

$env:MCPG_DATABASE_URL = "postgresql://postgres:postgres@localhost:5432/mydb"
mcpg

Windows (Command Prompt)

set MCPG_DATABASE_URL=postgresql://postgres:postgres@localhost:5432/mydb
mcpg

That starts MCPg on the stdio transport in read-only mode, ready to be consumed by an MCP client (Claude Desktop, Cursor, Continue, etc.). See the next section for how to wire it into a specific client.

For HTTP-based clients:

Linux / macOS (bash/zsh)

export MCPG_DATABASE_URL=postgresql://postgres:postgres@localhost:5432/mydb
export MCPG_TRANSPORT=streamable-http
export MCPG_HTTP_PORT=8000
export MCPG_HTTP_AUTH_TOKEN=...    # optional but strongly recommended
mcpg

Windows (PowerShell)

$env:MCPG_DATABASE_URL = "postgresql://postgres:postgres@localhost:5432/mydb"
$env:MCPG_TRANSPORT = "streamable-http"
$env:MCPG_HTTP_PORT = "8000"
$env:MCPG_HTTP_AUTH_TOKEN = "..."    # optional but strongly recommended
mcpg

Windows (Command Prompt)

set MCPG_DATABASE_URL=postgresql://postgres:postgres@localhost:5432/mydb
set MCPG_TRANSPORT=streamable-http
set MCPG_HTTP_PORT=8000
set MCPG_HTTP_AUTH_TOKEN=...
mcpg

Wire it into an MCP client

Download mcpg-<version>.mcpb from the latest GitHub release and open it with Claude Desktop (double-click, or Settings → Extensions → drag it in). The install dialog prompts for:

The bundle is a ~2 kB uv-type MCPB: Claude Desktop resolves the pinned mcpg release from PyPI for your platform at install time, so there is nothing else to install. Additional environment variables (replicas, capability gates, NL→SQL keys) can still be layered on via the manual config below if you need them.

Claude Desktop (stdio, manual config)

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",
        "MCPG_ACCESS_MODE": "read-only"
      }
    }
  }
}

Restart Claude Desktop after editing the file. (If you’ve installed MCPg via pip install mcpg, you can use "command": "mcpg" with no args.)

Cursor, Continue, or any HTTP MCP client

export MCPG_DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
export MCPG_TRANSPORT=streamable-http
export MCPG_HTTP_AUTH_TOKEN=<random_long_token>
mcpg

Configure the client to connect to http://<host>:8000/mcp and send Authorization: Bearer <random_long_token>.

For production HTTP deployments, prefer OIDC over a static token — set MCPG_AUTH_MODE=oidc, MCPG_OIDC_ISSUER, MCPG_OIDC_AUDIENCE, and optionally MCPG_OIDC_ROLE_CLAIM to map JWT claims to PG roles. The OIDC flow validates JWTs against the issuer’s JWKS (asymmetric algorithms only — RS256/ES256 families).


Configuration

MCPg is configured entirely through environment variables. The only required one is MCPG_DATABASE_URL; all others have safe defaults.

The full reference (every MCPG_* variable, grouped by area, with defaults and descriptions) is in the README. The summaries below give you the minimum set per common scenario.

Common scenarios

Scenario Set
Local exploration, read-only MCPG_DATABASE_URL
Read-write app access MCPG_ACCESS_MODE=restricted
DBA toolkit (DDL, vacuum, etc.) MCPG_ACCESS_MODE=unrestricted + MCPG_ALLOW_DDL=true
Dump / restore subprocess tools MCPG_ACCESS_MODE=unrestricted + MCPG_ALLOW_SHELL=true
LISTEN/NOTIFY event streams MCPG_ACCESS_MODE=unrestricted + MCPG_ALLOW_LISTEN=true
HTTP transport with static bearer MCPG_TRANSPORT=streamable-http + MCPG_HTTP_AUTH_TOKEN=…
HTTP transport with OIDC MCPG_TRANSPORT=streamable-http + MCPG_AUTH_MODE=oidc + MCPG_OIDC_ISSUER=… + MCPG_OIDC_AUDIENCE=…
HTTP transport with IP allowlist MCPG_HTTP_IP_ALLOWLIST=10.0.0.0/8,192.168.1.0/24 (applied before auth; matched against the immediate peer — X-Forwarded-For is not honoured, so deployments behind a reverse proxy must enforce the allowlist at the proxy layer)
HTTP transport with TLS MCPG_HTTP_TLS_CERTFILE=/etc/mcpg/cert.pem + MCPG_HTTP_TLS_KEYFILE=/etc/mcpg/key.pem
HTTP transport with mTLS the TLS pair above + MCPG_HTTP_TLS_CA_CERTS=/etc/mcpg/ca.pem + MCPG_HTTP_TLS_CLIENT_CERT_REQUIRED=true
Cloud secrets (Vault) MCPG_SECRETS_BACKEND=vault + MCPG_VAULT_ADDR=… + MCPG_VAULT_TOKEN=… (optional MCPG_VAULT_NAMESPACE=…, MCPG_VAULT_PATH_PREFIX=secret/mcpg)
Cloud secrets (AWS) MCPG_SECRETS_BACKEND=aws + MCPG_AWS_SECRET_ID=arn:aws:secretsmanager:…
Cloud secrets (GCP) MCPG_SECRETS_BACKEND=gcp + MCPG_GCP_SECRET_NAME=projects/<id>/secrets/<name>/versions/latest
OpenTelemetry tracing pip install 'mcpg[otel]' + MCPG_OTEL_ENABLED=true (+ optional MCPG_OTEL_SERVICE_NAME=mcpg-prod) — emits one span per call_tool; argument values are deliberately not attached
Slow-call logging MCPG_SLOW_CALL_THRESHOLD_MS=500 (any tool slower than this logs a structured record); MCPG_LOG_FORMAT=json for structured logging
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
Multiple databases (read-only secondaries) MCPG_SECONDARY_DATABASE_URLS=analytics=postgresql://…?sslmode=require,reporting=postgresql://…?sslmode=require — read-capable tools take an optional database arg; secondaries are read-only (PostgreSQL-enforced). Call list_databases to discover ids.
NL→SQL — single provider Set ANTHROPIC_API_KEY (or OPENAI_API_KEY / GEMINI_API_KEY). MCPg auto-picks the default.
NL→SQL — multi-provider routing Set all the vendor keys you want active; callers pass provider="anthropic"\|"openai"\|"gemini" per call.
Audit persistence MCPG_AUDIT_PERSIST=true
Prometheus metrics (always on for HTTP transports — GET /metrics)

TLS enforcement (important)

By default MCPg refuses to start if MCPG_DATABASE_URL (or any entry in MCPG_REPLICA_URLS / MCPG_SECONDARY_DATABASE_URLS) points at a non-loopback host without TLS enforcement. PostgreSQL’s libpq accepts plaintext fallback under sslmode=disable | allow | prefer (and an unset sslmode defaults to prefer) — which means a misconfigured production DSN can leak credentials over the network without anyone noticing.

To fix at the DSN level (recommended):

postgresql://user:pass@db.example.com:5432/app?sslmode=require

…or verify-ca / verify-full for stricter validation. Loopback hosts (localhost, 127.0.0.1, ::1) are always exempt.

If you genuinely need to run plaintext for a temporary dev / internal use, the explicit opt-out is:

export MCPG_ALLOW_INSECURE_TLS=true

The startup error message names exactly which DSN failed the check (including the replica index if it was one of your MCPG_REPLICA_URLS entries, or the secondary name if it was an MCPG_SECONDARY_DATABASE_URLS entry).

HTTP transport TLS / mTLS

The TLS settings above protect the database connection. The HTTP transport can be terminated by an external proxy (nginx / Envoy) or by MCPg directly — the in-process option drops the proxy dependency for small deployments.

export MCPG_HTTP_TLS_CERTFILE=/etc/mcpg/cert.pem
export MCPG_HTTP_TLS_KEYFILE=/etc/mcpg/key.pem

Both must be set together; configuring only one is rejected at startup so a deployment can’t silently fall back to plaintext.

For mutual TLS (clients must present a cert chaining to a known CA — useful for service-to-service deployments where bearer tokens aren’t enough):

export MCPG_HTTP_TLS_CA_CERTS=/etc/mcpg/ca.pem
export MCPG_HTTP_TLS_CLIENT_CERT_REQUIRED=true

Setting CLIENT_CERT_REQUIRED=true without CA_CERTS is rejected at startup — there’d be nothing to verify against.

Database privileges

Connect MCPg with a least-privilege database role — ideally one granted only the privileges the workload needs.

MCPg’s access-mode enforcement (read-only / restricted / unrestricted) and capability gates (MCPG_ALLOW_DDL / MCPG_ALLOW_SHELL / MCPG_ALLOW_LISTEN) are a second line of defence, not a substitute for correct database-side permissions. A misconfigured unrestricted + MCPG_ALLOW_DDL=true deployment with a superuser DSN is by-design root access; ensure that combination matches operator intent.

Typical setup for a read-only deployment:

CREATE ROLE mcpg_reader LOGIN PASSWORD 'change-me';
GRANT CONNECT ON DATABASE mydb TO mcpg_reader;
GRANT USAGE ON SCHEMA public TO mcpg_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcpg_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT SELECT ON TABLES TO mcpg_reader;

See security.md for the full threat model and security-hardening.md for the shipped and queued hardening features.


Verify the installation

MCPG_DATABASE_URL=postgresql://localhost/mydb mcpg

On stdio (the default), the server waits silently for an MCP client to attach. To exercise a tool round-trip, point a client at it and call get_server_info — see the User Guide.

For HTTP transports, MCPg also exposes:


Troubleshooting


Next steps