mcp-postgres
mcp-postgres
A comprehensive PostgreSQL MCP (Model Context Protocol) server providing 27 tools for database management and administration.
Features
Connection Management — connect, disconnect, pool health monitoring
Query Execution — parameterized queries, EXPLAIN ANALYZE, prepared statements
Schema Introspection — tables, indexes, constraints, views, functions, enums, extensions
CRUD Operations — type-safe insert, update, delete, upsert with injection protection
Server Management — version, settings, config reload, uptime
Database Sizing — database and table sizes with index/toast breakdown
Installation
npm install @itunified.io/mcp-postgresOr run directly:
npx @itunified.io/mcp-postgresConfiguration
Set one of the following environment variables:
# Option 1: Connection string (preferred)
export POSTGRES_CONNECTION_STRING="postgresql://myuser:mypassword@your-database.example.com:5432/mydb"
# Option 2: Individual variables
export PGHOST="your-database.example.com"
export PGPORT="5432"
export PGUSER="myuser"
export PGPASSWORD="mypassword"
export PGDATABASE="mydb"
export PGSSLMODE="require" # optionalMulti-Database Configuration
Create a config file at ~/.config/mcp-postgres/databases.yaml:
databases:
production:
host: db.example.com
port: 5432
user: admin
password: ${DB_PROD_PASSWORD}
database: myapp
ssl: true
staging:
host: staging-db.example.com
port: 5432
user: admin
password: ${DB_STAGING_PASSWORD}
database: myapp
default: productionEnvironment variables in ${VAR_NAME} syntax are automatically expanded.
Config file discovery order:
POSTGRES_CONFIG_FILEenv var (explicit path)~/.config/mcp-postgres/databases.yamlordatabases.jsonPOSTGRES_CONNECTION_STRINGenv var (single database)Individual
PG*env vars (single database)
Override the config path with POSTGRES_CONFIG_FILE env var:
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["@itunified.io/mcp-postgres"],
"env": {
"POSTGRES_CONFIG_FILE": "/path/to/databases.yaml"
}
}
}
}Use pg_list_connections to see all configured databases, pg_switch_database to change the active one.
HashiCorp Vault Integration (Optional)
mcp-postgres supports opportunistic secret loading from HashiCorp Vault via AppRole authentication. When configured, it fetches PostgreSQL credentials from a KV v2 path — so you never need to put database passwords in environment variables or config files.
How it works:
On startup, the server checks for
NAS_VAULT_ADDR,NAS_VAULT_ROLE_ID, andNAS_VAULT_SECRET_IDin the environmentIf all three are set, it logs in via AppRole and reads the configured KV v2 path
It populates
POSTGRES_CONNECTION_STRINGandPG*env vars from the Vault secret — but only for vars not already setIf Vault is not configured or unreachable, the server silently falls back to env vars
Precedence: Explicit env vars → Vault → config file fallback → (error if nothing set)
Variable | Required | Description |
| Yes* | Vault server address (e.g., |
| Yes* | AppRole role ID for this server |
| Yes* | AppRole secret ID for this server |
| No | KV v2 mount path (default: |
* Only required if using Vault. Without these, the server uses env vars / config files directly.
Vault KV v2 secret structure:
# Path: kv/your/postgres/secret
{
"connection_string": "postgresql://myuser:mypassword@your-database.example.com:5432/mydb",
"host": "your-database.example.com",
"port": "5432",
"user": "myuser",
"password": "mypassword",
"database": "mydb"
}Key mapping: connection_string → POSTGRES_CONNECTION_STRING, host → PGHOST, port → PGPORT, user → PGUSER, password → PGPASSWORD, database → PGDATABASE
Tip: You can store either
connection_string(for single-database setups) or individual fields (host/port/user/password/database), or both. The loader maps whatever keys are present.
Vault setup steps:
Write PG credentials to a KV v2 path:
vault kv put kv/your/postgres/secret \ connection_string="postgresql://myuser:mypassword@your-database.example.com:5432/mydb" \ host="your-database.example.com" \ port="5432" \ user="myuser" \ password="mypassword" \ database="mydb"Create a read-only policy:
path "kv/data/your/postgres/secret" { capabilities = ["read"] }Create an AppRole and get credentials:
vault write auth/approle/role/mcp-postgres \ token_policies="mcp-postgres" token_ttl=1h vault read auth/approle/role/mcp-postgres/role-id vault write -f auth/approle/role/mcp-postgres/secret-idConfigure the server with Vault env vars (no PG creds needed):
{ "mcpServers": { "postgres": { "command": "npx", "args": ["@itunified.io/mcp-postgres"], "env": { "NAS_VAULT_ADDR": "https://vault.example.com:8200", "NAS_VAULT_ROLE_ID": "your-role-id", "NAS_VAULT_SECRET_ID": "your-secret-id" } } } }
Note: Config file options (
POSTGRES_CONFIG_FILE,databases.yaml) andPGSSLMODEare not loaded from Vault — set them via env vars if needed.
Claude Desktop / MCP Settings
Add to your settings.json:
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["@itunified.io/mcp-postgres"],
"env": {
"POSTGRES_CONNECTION_STRING": "postgresql://myuser:mypassword@your-database.example.com:5432/mydb"
}
}
}
}Tools
Connection (5 tools)
Tool | Description |
| Connect to a database (default or named) |
| Disconnect from a database or all |
| Pool health for active or named database |
| List all configured databases and status |
| Switch the active database context |
Query (3 tools)
Tool | Description |
| Execute parameterized SELECT/DML query |
| Run EXPLAIN ANALYZE on a query |
| Manage named prepared statements (PREPARE/EXECUTE/DEALLOCATE) |
Schema Introspection (9 tools)
Tool | Description |
| List all schemas |
| List tables (with optional schema filter) |
| Describe table columns, types, defaults, constraints |
| List indexes for a table |
| List constraints (PK, FK, unique, check) |
| List views with definitions |
| List functions/procedures with signatures |
| List enum types and values |
| List installed extensions |
CRUD (4 tools)
Tool | Description |
| Insert row(s) with parameterized values |
| Update rows (requires |
| Delete rows (requires |
| Insert or update on conflict (requires |
Server (4 tools)
Tool | Description |
| PostgreSQL version |
| Show/search server configuration |
| Reload configuration (requires |
| Server uptime and start time |
HA Monitoring (4 tools)
Tool | Description |
| Streaming replication state and lag |
| List replication slots |
| WAL generation rate and archive status |
| Primary vs standby detection |
Database Management (2 tools)
Tool | Description |
| Size of all databases |
| Table sizes with index/toast breakdown |
Enterprise Edition
For advanced PostgreSQL operations, mcp-postgres-enterprise extends this server with:
DBA Monitoring — VACUUM, ANALYZE, REINDEX, pg_stat_activity, table/index stats, locks, cache hit ratio, bloat detection
CloudNativePG (CNPG) — K8s cluster management, failover, switchover, backup orchestration
HA Operations — Replication slot management, PgBouncer pool control
Backup / PITR — pg_dump/pg_restore orchestration, point-in-time recovery
RBAC — Role management, privilege grants, row-level security policies
Audit — Query log analysis, connection audit, permission mapping
Compliance — SSL enforcement, connection limit checks
Available as a private GitHub package. Contact itunified.io for access.
Security
Query Safety Model
CRUD tools (
pg_insert,pg_update,pg_delete,pg_upsert): All use parameterized queries ($1,$2, ...) — safe from SQL injection. Destructive operations requireconfirm: true.pg_query: Unrestricted raw SQL runner by design — intended for power users who need full SQL flexibility. No injection protection is applied because the tool's purpose is to execute arbitrary SQL.pg_query_explain: Defaults to safeplanmode (EXPLAIN only, no execution).mode=analyzealways requiresconfirm: truebecause EXPLAIN ANALYZE executes the statement.pg_query_prepared: Deprecated. Prepared statements are session-local in PostgreSQL and unreliable with connection pools. Statement names are validated as SQL identifiers. Use parameterizedpg_queryinstead.
Destructive Operations
These tools require confirm: true to execute:
pg_update,pg_delete,pg_upsert— data modificationpg_reload_config— server configurationpg_query_explain(analyze mode) — statement execution
Credentials
Connection credentials are read from environment variables or JSON/YAML config — never logged or stored
All identifiers (table, column, schema names) are validated against a strict regex pattern
License
This project is dual-licensed:
AGPL-3.0 — Free for open-source and non-commercial use
Commercial License — For proprietary and commercial use
See COMMERCIAL_LICENSE.md for details.
Contributing
Contributions are welcome! Please open an issue first to discuss proposed changes.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/itunified-io/mcp-postgres'
If you have feedback or need assistance with the MCP directory API, please join our Discord server