MCP server for PostgreSQL: local, Docker, RDS, Neon, Supabase, or behind an SSH bastion.
Connect Runs on your machine
claude mcp add mcp-postgres-server -e DATABASE_URL=<DATABASE_URL> -e PG_HOST=<PG_HOST> -e PG_PORT=<PG_PORT> -e PG_USER=<PG_USER> -e PG_PASSWORD=<PG_PASSWORD> -e PG_DATABASE=<PG_DATABASE> -e PG_ALLOW_WRITE=<PG_ALLOW_WRITE> -e PG_SSLMODE=<PG_SSLMODE> -e PG_SSL_CA=<PG_SSL_CA> -e PG_ENABLE_RUNTIME_CONNECT=<PG_ENABLE_RUNTIME_CONNECT> -e PG_MAX_RESULT_BYTES=<PG_MAX_RESULT_BYTES> -e PG_STATEMENT_TIMEOUT=<PG_STATEMENT_TIMEOUT> -e PG_CONNECT_TIMEOUT=<PG_CONNECT_TIMEOUT> -e PG_SSH_HOST=<PG_SSH_HOST> -e PG_SSH_PORT=<PG_SSH_PORT> -e PG_SSH_USER=<PG_SSH_USER> -e PG_SSH_PRIVATE_KEY=<PG_SSH_PRIVATE_KEY> -e PG_SSH_PASSPHRASE=<PG_SSH_PASSPHRASE> -e PG_SSH_AGENT=<PG_SSH_AGENT> -e PG_SSH_PASSWORD=<PG_SSH_PASSWORD> -e PG_SSH_FINGERPRINT=<PG_SSH_FINGERPRINT> -e PG_SSH_KEEPALIVE_INTERVAL=<PG_SSH_KEEPALIVE_INTERVAL> -- npx -y [email protected]
{
"mcpServers": {
"mcp-postgres-server": {
"command": "npx",
"args": [
"-y",
"[email protected]"
],
"env": {
"DATABASE_URL": "<DATABASE_URL>",
"PG_HOST": "<PG_HOST>",
"PG_PORT": "<PG_PORT>",
"PG_USER": "<PG_USER>",
"PG_PASSWORD": "<PG_PASSWORD>",
"PG_DATABASE": "<PG_DATABASE>",
"PG_ALLOW_WRITE": "<PG_ALLOW_WRITE>",
"PG_SSLMODE": "<PG_SSLMODE>",
"PG_SSL_CA": "<PG_SSL_CA>",
"PG_ENABLE_RUNTIME_CONNECT": "<PG_ENABLE_RUNTIME_CONNECT>",
"PG_MAX_RESULT_BYTES": "<PG_MAX_RESULT_BYTES>",
"PG_STATEMENT_TIMEOUT": "<PG_STATEMENT_TIMEOUT>",
"PG_CONNECT_TIMEOUT": "<PG_CONNECT_TIMEOUT>",
"PG_SSH_HOST": "<PG_SSH_HOST>",
"PG_SSH_PORT": "<PG_SSH_PORT>",
"PG_SSH_USER": "<PG_SSH_USER>",
"PG_SSH_PRIVATE_KEY": "<PG_SSH_PRIVATE_KEY>",
"PG_SSH_PASSPHRASE": "<PG_SSH_PASSPHRASE>",
"PG_SSH_AGENT": "<PG_SSH_AGENT>",
"PG_SSH_PASSWORD": "<PG_SSH_PASSWORD>",
"PG_SSH_FINGERPRINT": "<PG_SSH_FINGERPRINT>",
"PG_SSH_KEEPALIVE_INTERVAL": "<PG_SSH_KEEPALIVE_INTERVAL>"
}
}
}
}
{
"mcpServers": {
"mcp-postgres-server": {
"command": "npx",
"args": [
"-y",
"[email protected]"
],
"env": {
"DATABASE_URL": "<DATABASE_URL>",
"PG_HOST": "<PG_HOST>",
"PG_PORT": "<PG_PORT>",
"PG_USER": "<PG_USER>",
"PG_PASSWORD": "<PG_PASSWORD>",
"PG_DATABASE": "<PG_DATABASE>",
"PG_ALLOW_WRITE": "<PG_ALLOW_WRITE>",
"PG_SSLMODE": "<PG_SSLMODE>",
"PG_SSL_CA": "<PG_SSL_CA>",
"PG_ENABLE_RUNTIME_CONNECT": "<PG_ENABLE_RUNTIME_CONNECT>",
"PG_MAX_RESULT_BYTES": "<PG_MAX_RESULT_BYTES>",
"PG_STATEMENT_TIMEOUT": "<PG_STATEMENT_TIMEOUT>",
"PG_CONNECT_TIMEOUT": "<PG_CONNECT_TIMEOUT>",
"PG_SSH_HOST": "<PG_SSH_HOST>",
"PG_SSH_PORT": "<PG_SSH_PORT>",
"PG_SSH_USER": "<PG_SSH_USER>",
"PG_SSH_PRIVATE_KEY": "<PG_SSH_PRIVATE_KEY>",
"PG_SSH_PASSPHRASE": "<PG_SSH_PASSPHRASE>",
"PG_SSH_AGENT": "<PG_SSH_AGENT>",
"PG_SSH_PASSWORD": "<PG_SSH_PASSWORD>",
"PG_SSH_FINGERPRINT": "<PG_SSH_FINGERPRINT>",
"PG_SSH_KEEPALIVE_INTERVAL": "<PG_SSH_KEEPALIVE_INTERVAL>"
}
}
}
}
{
"servers": {
"mcp-postgres-server": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"[email protected]"
],
"env": {
"DATABASE_URL": "<DATABASE_URL>",
"PG_HOST": "<PG_HOST>",
"PG_PORT": "<PG_PORT>",
"PG_USER": "<PG_USER>",
"PG_PASSWORD": "<PG_PASSWORD>",
"PG_DATABASE": "<PG_DATABASE>",
"PG_ALLOW_WRITE": "<PG_ALLOW_WRITE>",
"PG_SSLMODE": "<PG_SSLMODE>",
"PG_SSL_CA": "<PG_SSL_CA>",
"PG_ENABLE_RUNTIME_CONNECT": "<PG_ENABLE_RUNTIME_CONNECT>",
"PG_MAX_RESULT_BYTES": "<PG_MAX_RESULT_BYTES>",
"PG_STATEMENT_TIMEOUT": "<PG_STATEMENT_TIMEOUT>",
"PG_CONNECT_TIMEOUT": "<PG_CONNECT_TIMEOUT>",
"PG_SSH_HOST": "<PG_SSH_HOST>",
"PG_SSH_PORT": "<PG_SSH_PORT>",
"PG_SSH_USER": "<PG_SSH_USER>",
"PG_SSH_PRIVATE_KEY": "<PG_SSH_PRIVATE_KEY>",
"PG_SSH_PASSPHRASE": "<PG_SSH_PASSPHRASE>",
"PG_SSH_AGENT": "<PG_SSH_AGENT>",
"PG_SSH_PASSWORD": "<PG_SSH_PASSWORD>",
"PG_SSH_FINGERPRINT": "<PG_SSH_FINGERPRINT>",
"PG_SSH_KEEPALIVE_INTERVAL": "<PG_SSH_KEEPALIVE_INTERVAL>"
}
}
}
}
Replace the values in angle brackets with your own. Keys stay on your machine; we never see them.
Tools
This server runs locally, so its tools are listed by your MCP client once it starts.
Environment variables
| Name | Description |
|---|---|
DATABASE_URLOptional, secret | Full connection string (preferred). Supports sslmode in the URL. |
PG_HOSTOptional | Database host (fallback when DATABASE_URL is not set). |
PG_PORTOptional | Database port. |
PG_USEROptional | Database user. |
PG_PASSWORDOptional, secret | Database password. |
PG_DATABASEOptional | Database name. |
PG_ALLOW_WRITEOptional | When true, execute performs writes and reads are sent directly. Off (default) is read-only: execute refuses writes and each read runs in a READ ONLY transaction. |
PG_SSLMODEOptional | TLS mode. require/allow/prefer encrypt without verifying the certificate; verify-ca/verify-full verify it (supply a CA via PG_SSL_CA). Unlike libpq, allow/prefer do not fall back to plaintext, so a server without TLS needs disable. |
PG_SSL_CAOptional | Path to a CA certificate file. Setting it by itself implies verify-full. |
PG_ENABLE_RUNTIME_CONNECTOptional | Register the connect_db tool (runtime credential switching). |
PG_MAX_RESULT_BYTESOptional | Byte budget for a query result sent to the model. Whole rows are kept while they fit; over the budget returnedRows < rowCount and truncated is true. |
PG_STATEMENT_TIMEOUTOptional | Statement timeout in milliseconds, applied to every session. |
PG_CONNECT_TIMEOUTOptional | Timeout in milliseconds for a single connect attempt (raise it for slow links or SSH tunnels). |
PG_SSH_HOSTOptional | SSH bastion host. Setting it enables tunneling: the server reaches the database only through an SSH tunnel to this host. Needs the ssh2 optional dependency. |
PG_SSH_PORTOptional | SSH bastion port. |
PG_SSH_USEROptional | SSH username. |
PG_SSH_PRIVATE_KEYOptional | Path to a private key file. If unset, auth falls back like ssh: a running agent (SSH_AUTH_SOCK), then a default key (~/.ssh/id_ed25519, id_rsa, id_ecdsa). |
PG_SSH_PASSPHRASEOptional, secret | Passphrase for the private key, if encrypted. |
PG_SSH_AGENTOptional | true to use the ambient agent (SSH_AUTH_SOCK), or an explicit socket path / Windows named pipe. |
PG_SSH_PASSWORDOptional, secret | SSH login password. Opt-in; a key or agent takes precedence. Prefer keys, a bastion often disables password auth. |
PG_SSH_FINGERPRINTOptional | Pinned host-key fingerprint (SHA256:...). Host-key verification is mandatory and set only this way: without it the tunnel refuses to connect. Get it with ssh-keygen -lF host. |
PG_SSH_KEEPALIVE_INTERVALOptional | SSH keepalive interval in ms; the tunnel drops after 3 unanswered keepalives, and the next call reconnects. |
Details
| Package | [email protected] (NPM, stdio) |
| First published | 14 Sep 2026 |
| Last updated | 14 Sep 2026 |
| Registry name | io.github.antonorlov/mcp-postgres-server |
More databases servers See all
Listing data from the official MCP registry. Status and tools from NestDaddy's daily check. Browse all MCP servers.
