PostgreSQL MCP Server
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_tableandoptimize_queryas 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)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mapeg_postgres_mcp-2.0.0.tar.gz | 23.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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.