Skip to main content

PostgreSQL MCP Server

Python MCP License: MIT PyPI

A Model Context Protocol (MCP) server for PostgreSQL databases. Query, explore, and analyze your PostgreSQL databases directly from any MCP-compatible AI client.

Features

  • Execute SQL — Run any SQL query with automatic result formatting
  • Natural Language Queries — Ask questions in plain English or Turkish
  • Schema Exploration — List tables, describe columns, view statistics
  • Execution Plans — EXPLAIN / EXPLAIN ANALYZE with buffer stats
  • Query History — Review past queries scoped to your database and workspace
  • Read-Only Mode — Optional write protection via READ_ONLY=true
  • Zero Install — Works with uvx, no virtual environment needed
  • Structured Output — Results come back as typed JSON (columns, rows, row_count, duration_ms), not an ASCII table you have to parse back
  • Write Confirmation — Any INSERT/UPDATE/DELETE/DROP is confirmed with the user before it runs, with an extra warning for the irreversible ones
  • Prompts — analyze_table and optimize_query as ready-made investigation flows

Quick Start

Claude Code

claude mcp add postgres \
  -e DB_HOST=localhost \
  -e DB_PORT=5432 \
  -e DB_NAME=mydb \
  -e DB_USER=postgres \
  -e DB_PASSWORD=secret \
  -- uvx mapeg-postgres-mcp

Claude Desktop

Add to your config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "postgres": {
      "command": "uvx",
      "args": ["mapeg-postgres-mcp"],
      "env": {
        "DB_HOST": "localhost",
        "DB_PORT": "5432",
        "DB_NAME": "mydb",
        "DB_USER": "postgres",
        "DB_PASSWORD": "secret"
      }
    }
  }
}

Cursor

Add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "postgres": {
      "command": "uvx",
      "args": ["mapeg-postgres-mcp"],
      "env": {
        "DB_HOST": "localhost",
        "DB_PORT": "5432",
        "DB_NAME": "mydb",
        "DB_USER": "postgres",
        "DB_PASSWORD": "secret"
      }
    }
  }
}

Windsurf

Add to Windsurf MCP config:

{
  "mcpServers": {
    "postgres": {
      "command": "uvx",
      "args": ["mapeg-postgres-mcp"],
      "env": {
        "DB_HOST": "localhost",
        "DB_PORT": "5432",
        "DB_NAME": "mydb",
        "DB_USER": "postgres",
        "DB_PASSWORD": "secret"
      }
    }
  }
}

VS Code

Add to your VS Code settings (JSON):

"mcp": {
  "servers": {
    "postgres": {
      "type": "stdio",
      "command": "uvx",
      "args": ["mapeg-postgres-mcp"],
      "env": {
        "DB_HOST": "localhost",
        "DB_PORT": "5432",
        "DB_NAME": "mydb",
        "DB_USER": "postgres",
        "DB_PASSWORD": "secret"
      }
    }
  }
}

Gemini CLI

Add to ~/.gemini/settings.json:

{
  "mcpServers": {
    "postgres": {
      "command": "uvx",
      "args": ["mapeg-postgres-mcp"],
      "env": {
        "DB_HOST": "localhost",
        "DB_PORT": "5432",
        "DB_NAME": "mydb",
        "DB_USER": "postgres",
        "DB_PASSWORD": "secret"
      }
    }
  }
}

GitHub Copilot

Add to ~/.copilot/mcp-config.json:

{
  "mcpServers": {
    "postgres": {
      "command": "uvx",
      "args": ["mapeg-postgres-mcp"],
      "env": {
        "DB_HOST": "localhost",
        "DB_PORT": "5432",
        "DB_NAME": "mydb",
        "DB_USER": "postgres",
        "DB_PASSWORD": "secret"
      }
    }
  }
}

OpenAI Codex

Add to ~/.codex/config.toml:

[mcp_servers.postgres]
command = "uvx"
args = ["mapeg-postgres-mcp"]

[mcp_servers.postgres.env]
DB_HOST = "localhost"
DB_PORT = "5432"
DB_NAME = "mydb"
DB_USER = "postgres"
DB_PASSWORD = "secret"

Install from Source

cd mapeg-postgres-mcp
pip install -e .

Configuration

Environment Variable Required Default Description
DB_HOST No localhost PostgreSQL host
DB_PORT No 5432 PostgreSQL port
DB_NAME Yes — Database name
DB_USER No postgres Database user
DB_PASSWORD Yes — Database password
READ_ONLY No false Block write operations (INSERT, UPDATE, DELETE, DROP, etc.)

Tools

execute_sql — Run SQL queries

Execute any SQL query on the connected PostgreSQL database.

Parameter Type Required Description
sql string Yes SQL query to execute
limit integer No Row limit added to a SELECT that has no LIMIT (default: 100)

Returns sql (as actually run), columns, rows, row_count, limit_applied and duration_ms. Non-JSON column types are converted: numeric becomes a string so that a value wider than an IEEE-754 float is not silently rounded, timestamps become ISO-8601 strings, and bytes become a size marker.

Writes are confirmed first. A statement starting with INSERT, UPDATE, DELETE, DROP, ALTER, CREATE, TRUNCATE, MERGE, GRANT or REVOKE puts a question in front of the user before anything runs; DROP, TRUNCATE and DELETE are flagged as irreversible in that question. If the user declines, nothing is executed. With READ_ONLY=true writes are refused without asking.

natural_language_query — Query in plain language

Answers a fixed set of questions without writing SQL: list tables, list users, list schemas, show database info. Supports Turkish and English phrasing.

Parameter Type Required Description
query string Yes Natural language query

Examples: "show all tables", "tabloları listele", "show database info"

This is keyword matching, not a text-to-SQL model. Anything outside those four questions returns a tool error naming what it does understand — write the SQL yourself and use execute_sql.

describe_table — Table structure details

Get column definitions, row count, and table size.

Parameter Type Required Description
table_name string Yes Table name (schema.table or table)
smart_query — AI-powered query assistant

Returns the public schema's tables and columns as context for answering a question. It does not write or run SQL: read the returned schema, then use execute_sql.

Parameter Type Required Description
question string Yes Question about your data
explain_query — Execution plan analysis

Show the EXPLAIN plan for a SQL query.

Parameter Type Required Description
sql string Yes SQL query to explain
analyze boolean No Run EXPLAIN ANALYZE (default: false)
format string No Output format: text, json, yaml (default: text)
buffers boolean No Include buffer usage (requires analyze=true)

analyze=true actually runs the query, so it is refused on a statement that writes.

get_query_history — Review past queries

Retrieve recent query history scoped to this database and workspace.

Parameter Type Required Description
limit integer No Number of entries (default: 20)
status string No Filter: success or error
tool_name string No Filter by tool name

Resources

URI Description
postgresql://tables List all user tables
postgresql://schema Detailed schema with columns
postgresql://stats Database version and statistics
postgresql://table/{schema}/{table} One table's columns, row count and size

Prompts

Name Description
analyze_table Inspect a table's shape, sample its data, and report data-quality issues
optimize_query Read the plan, find the expensive step, propose and re-check a fix

Requirements

Python 3.10+ and MCP SDK 2.x (mcp>=2.2,<3). The server speaks the 2026-07-28 protocol revision and still serves older MCP clients from the same process. All psycopg2 calls run on a worker thread, so a slow query no longer blocks the server.

License

MIT

Metadata

Release files for mapeg-postgres-mcp 2.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mapeg-postgres-mcp 2.0.0
File Size Uploaded Provenance
mapeg_postgres_mcp-2.0.0.tar.gz 23.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for mapeg-postgres-mcp 2.0.0
File Interpreter ABI Platform
mapeg_postgres_mcp-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 42.9 kB

Release files / mapeg_postgres_mcp-2.0.0.tar.gz

Download URL mapeg_postgres_mcp-2.0.0.tar.gz
Size 23.2 kB
Tags Source
SHA-256 checksum
How to use checksums
3d33c49180a9ffbe317c7972feb132b1af4b163058bc5cd8271583e0d06927fc
BLAKE2b-256 checksum
How to use checksums
66a51ed06b46fc5563b1b066d02d8265a353fddf8465b88aeaf2e7c45c40c3dd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.11

Release files / mapeg_postgres_mcp-2.0.0-py3-none-any.whl

Download URL mapeg_postgres_mcp-2.0.0-py3-none-any.whl
Size 19.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8950ac25fff95a97c7d763b26f1e9f63fc637e768d12ff17ca994b8bcb3d674f
BLAKE2b-256 checksum
How to use checksums
10add2aa9899d2f8a47af07bfb88fc217307e1522b9fb0d73c14c5974c891214
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.11

Security for mapeg-postgres-mcp 2.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

2.0.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page