# PostgreSQL MCP server

> Lets an AI client run read-only SQL queries and inspect schemas, tables, and columns in a PostgreSQL database, with optional write access.

- Repository: https://github.com/antonorlov/mcp-postgres-server
- Page: https://hostedmcp.org/servers/antonorlov/mcp-postgres-server
- Transport: stdio
- Stars: 25
- License: MIT
- Latest version: 0.3.1

## Install

### Claude Code

```sh
claude mcp add --env DATABASE_URL=<YOUR_DATABASE_URL> --env PG_PASSWORD=<YOUR_PG_PASSWORD> --env PG_SSH_PASSPHRASE=<YOUR_PG_SSH_PASSPHRASE> --env PG_SSH_PASSWORD=<YOUR_PG_SSH_PASSWORD> mcp-postgres-server -- npx -y mcp-postgres-server
```

### Cursor (`~/.cursor/mcp.json`)

```json
{
  "mcpServers": {
    "mcp-postgres-server": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-postgres-server"
      ],
      "env": {
        "DATABASE_URL": "<YOUR_DATABASE_URL>",
        "PG_PASSWORD": "<YOUR_PG_PASSWORD>",
        "PG_SSH_PASSPHRASE": "<YOUR_PG_SSH_PASSPHRASE>",
        "PG_SSH_PASSWORD": "<YOUR_PG_SSH_PASSWORD>"
      }
    }
  }
}
```

### VS Code (`.vscode/mcp.json`)

```json
{
  "servers": {
    "mcp-postgres-server": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "mcp-postgres-server"
      ],
      "env": {
        "DATABASE_URL": "<YOUR_DATABASE_URL>",
        "PG_PASSWORD": "<YOUR_PG_PASSWORD>",
        "PG_SSH_PASSPHRASE": "<YOUR_PG_SSH_PASSPHRASE>",
        "PG_SSH_PASSWORD": "<YOUR_PG_SSH_PASSWORD>"
      }
    }
  }
}
```

### Claude Desktop (`claude_desktop_config.json`)

```json
{
  "mcpServers": {
    "mcp-postgres-server": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-postgres-server"
      ],
      "env": {
        "DATABASE_URL": "<YOUR_DATABASE_URL>",
        "PG_PASSWORD": "<YOUR_PG_PASSWORD>",
        "PG_SSH_PASSPHRASE": "<YOUR_PG_SSH_PASSPHRASE>",
        "PG_SSH_PASSWORD": "<YOUR_PG_SSH_PASSWORD>"
      }
    }
  }
}
```

### Codex (`~/.codex/config.toml`)

```toml
[mcp_servers.mcp-postgres-server]
command = "npx"
args = ["-y", "mcp-postgres-server"]

[mcp_servers.mcp-postgres-server.env]
DATABASE_URL = "<YOUR_DATABASE_URL>"
PG_PASSWORD = "<YOUR_PG_PASSWORD>"
PG_SSH_PASSPHRASE = "<YOUR_PG_SSH_PASSPHRASE>"
PG_SSH_PASSWORD = "<YOUR_PG_SSH_PASSWORD>"
```

### Gemini CLI (`~/.gemini/settings.json`)

```json
{
  "mcpServers": {
    "mcp-postgres-server": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-postgres-server"
      ],
      "env": {
        "DATABASE_URL": "<YOUR_DATABASE_URL>",
        "PG_PASSWORD": "<YOUR_PG_PASSWORD>",
        "PG_SSH_PASSPHRASE": "<YOUR_PG_SSH_PASSPHRASE>",
        "PG_SSH_PASSWORD": "<YOUR_PG_SSH_PASSWORD>"
      }
    }
  }
}
```

## Environment variables

| Name | Required | Secret | Description |
|---|---|---|---|
| `DATABASE_URL` | no | yes | Full connection string (preferred). Supports sslmode in the URL. |
| `PG_PASSWORD` | no | yes | Database password. |
| `PG_SSH_PASSPHRASE` | no | yes | Passphrase for the private key, if encrypted. |
| `PG_SSH_PASSWORD` | no | yes | SSH login password. Opt-in; a key or agent takes precedence. Prefer keys, a bastion often disables password auth. |
| `DATABASE_URL` | no | no |  |
| `PG_ALLOW_WRITE` | no | no |  |
| `PG_ALLOW_WRITE` | no | no | 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_CONNECT_TIMEOUT` | no | no | Timeout in milliseconds for a single connect attempt (raise it for slow links or SSH tunnels). |
| `PG_DATABASE` | no | no |  |
| `PG_DATABASE` | no | no | Database name. |
| `PG_ENABLE_RUNTIME_CONNECT` | no | no | Register the connect_db tool (runtime credential switching). |
| `PG_HOST` | no | no |  |
| `PG_HOST` | no | no | Database host (fallback when DATABASE_URL is not set). |
| `PG_MAX_RESULT_BYTES` | no | no | 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_PASSWORD` | no | no |  |
| `PG_PORT` | no | no |  |
| `PG_PORT` | no | no | Database port. |
| `PG_SSH_AGENT` | no | no | true to use the ambient agent (SSH_AUTH_SOCK), or an explicit socket path / Windows named pipe. |
| `PG_SSH_FINGERPRINT` | no | no |  |
| `PG_SSH_FINGERPRINT` | no | no | 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_HOST` | no | no |  |
| `PG_SSH_HOST` | no | no | 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_KEEPALIVE_INTERVAL` | no | no | SSH keepalive interval in ms; the tunnel drops after 3 unanswered keepalives, and the next call reconnects. |
| `PG_SSH_PORT` | no | no | SSH bastion port. |
| `PG_SSH_PRIVATE_KEY` | no | no |  |
| `PG_SSH_PRIVATE_KEY` | no | no | 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_USER` | no | no |  |
| `PG_SSH_USER` | no | no | SSH username. |
| `PG_SSLMODE` | no | no | 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_CA` | no | no | Path to a CA certificate file. Setting it by itself implies verify-full. |
| `PG_STATEMENT_TIMEOUT` | no | no | Statement timeout in milliseconds, applied to every session. |
| `PG_USER` | no | no |  |
| `PG_USER` | no | no | Database user. |

## Tools (2)

- `execute`
- `connect_db`

## FAQ

### Is the PostgreSQL MCP server read-only by default?

Yes. Write access is off by default and must be explicitly enabled with PG_ALLOW_WRITE=true; otherwise reads run in a READ ONLY transaction and execute refuses writes.

### How do I connect the server to my PostgreSQL database?

Set a single DATABASE_URL connection string, or the individual PG_HOST, PG_PORT, PG_USER, PG_PASSWORD, and PG_DATABASE variables when DATABASE_URL is not set.

### Which tools does the PostgreSQL MCP server provide?

It provides query, list_schemas, list_tables, describe_table, and execute; connect_db is only registered when PG_ENABLE_RUNTIME_CONNECT=true.

### Can I use it with an Amazon RDS or Neon database?

Yes. Use the provider's connection string with sslmode=require; Supabase also works through its pooler host.

### Does it support SSH tunneling to a database behind a bastion?

Yes. Set PG_SSH_HOST plus auth and host-key settings to reach a database only accessible through a jump host.
