Skip to main content
Glama
lastfore

PostgreSQL MCP Server

by lastfore

PostgreSQL MCP Server

A production-grade Model Context Protocol (MCP) server that enables users to interact with PostgreSQL databases using natural language. Built on FastMCP, this server converts natural language questions into safe SQL queries, executes them, and validates the results. Some reference documents:

Features

  • Natural Language to SQL: Uses GPT-5.2-mini to convert plain English questions into optimized PostgreSQL queries

  • Security First: Read-only enforcement, blocking of dangerous functions, SQL injection protection, and query timeout control

  • Result Validation: AI-based result validation with confidence scoring

  • Intelligent Schema: Automatic schema caching with TTL-based refresh mechanism

  • Production Ready: Connection pool management, circuit breakers, rate limiting, and comprehensive metrics collection

  • MCP Compatible: Supports Claude Desktop and any MCP-compatible client

Related MCP server: PostgreSQL MCP Server

Quick Start

Prerequisites

  • Python 3.14+

  • PostgreSQL 12+

  • OpenAI API Key (for GPT-5.2-mini)

  • UV package manager (recommended) or pip

Installation

# 克隆仓库
git clone <repository-url>
cd pg-mcp

# 安装依赖
uv sync

# 复制环境配置模板
cp .env.example .env

# 编辑 .env 并配置参数
vi .env

Using pip

# 克隆仓库
git clone <repository-url>
cd pg-mcp

# 创建虚拟环境
python -m venv .venv
source .venv/bin/activate  # Windows 系统: .venv\Scripts\activate

# 安装依赖
pip install -e .

# 复制环境配置模板
cp .env.example .env

# 编辑 .env 并配置参数
vi .env

Configuration

Edit the .env file to configure your settings:

# 数据库配置
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_NAME=your_database
DATABASE_USER=your_user
DATABASE_PASSWORD=your_password

# OpenAI 配置
OPENAI_API_KEY=sk-your-api-key-here
OPENAI_MODEL=gpt-5.2-mini

# 安全设置(可选,显示默认值)
SECURITY_ALLOW_WRITE_OPERATIONS=false
SECURITY_MAX_ROWS=10000
SECURITY_MAX_EXECUTION_TIME=30

For full configuration options, please refer to .env.example.

Running the Server

Standalone Mode

# 使用 UV
uv run python main.py

# 或使用 pip
python main.py

Integration with Claude Desktop

Add the following configuration to your Claude Desktop MCP settings file:

macOS/Linux: ~/Library/Application Support/Claude/claude_desktop_config.json

Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "postgres": {
      "command": "uv",
      "args": [
        "--directory",
        "/absolute/path/to/pg-mcp",
        "run",
        "python",
        "main.py"
      ],
      "env": {
        "DATABASE_HOST": "localhost",
        "DATABASE_NAME": "your_database",
        "DATABASE_USER": "your_user",
        "DATABASE_PASSWORD": "your_password",
        "OPENAI_API_KEY": "sk-your-api-key-here"
      }
    }
  }
}

For detailed configuration instructions, please refer to Claude Desktop Configuration.

Usage

Example Queries

After connecting via Claude Desktop or another MCP client, you can ask natural language questions:

Simple Query

How many tables are in the database?
→ SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public'

Show me all users
→ SELECT * FROM users LIMIT 10000

What are the column names in the products table?
→ SELECT column_name, data_type FROM information_schema.columns
  WHERE table_name = 'products'

Analytical Query

What are the top 10 products by sales?
→ SELECT product_name, SUM(quantity * price) as total_sales
  FROM orders
  GROUP BY product_name
  ORDER BY total_sales DESC
  LIMIT 10

How many users registered in the last 30 days?
→ SELECT COUNT(*) FROM users
  WHERE created_at > CURRENT_DATE - INTERVAL '30 days'

SQL-Only Mode

You can also request just the SQL without execution:

Generate SQL to find duplicate emails
Return Type: sql
→ Returns: SELECT email, COUNT(*) FROM users GROUP BY email HAVING COUNT(*) > 1

Return Types

The server supports two return types:

  • result (default): Executes the query and returns the results

  • sql: Generates and validates the SQL, but does not execute it

Response Format

Successful Query Response

{
  "success": true,
  "generated_sql": "SELECT COUNT(*) FROM users",
  "data": {
    "columns": ["count"],
    "rows": [[1523]],
    "row_count": 1,
    "execution_time": 0.023
  },
  "confidence": 95,
  "tokens_used": 234
}

SQL-Only Response

{
  "success": true,
  "generated_sql": "SELECT * FROM users WHERE created_at > CURRENT_DATE - INTERVAL '30 days'",
  "confidence": 90,
  "tokens_used": 156
}

Error Response

{
  "success": false,
  "error": {
    "code": "SECURITY_VIOLATION",
    "message": "Query contains blocked operation: DELETE",
    "details": {
      "blocked_operation": "DELETE"
    }
  }
}

Architecture

Core Components

┌─────────────────────────────────────────────────────────────┐
│                      MCP Server (FastMCP)                   │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                    Query Orchestrator                       │
│  - Coordinates all components                               │
│  - Manages retry logic                                      │
│  - Handles error recovery                                   │
└─────────────────────────────────────────────────────────────┘
           │                  │                  │
           ▼                  ▼                  ▼
    ┌───────────┐     ┌────────────┐     ┌──────────────┐
    │   SQL     │     │    SQL     │     │     SQL      │
    │ Generator │────▶│ Validator  │────▶│  Executor    │
    │ (LLM)     │     │ (Security) │     │ (Database)   │
    └───────────┘     └────────────┘     └──────────────┘
           │                                      │
           ▼                                      ▼
    ┌───────────┐                          ┌──────────────┐
    │  Schema   │                          │   Result     │
    │  Cache    │                          │  Validator   │
    └───────────┘                          │  (LLM)       │
                                           └──────────────┘

Security Features

  1. Read-only Enforcement: Only SELECT queries are allowed by default

  2. Blocking Dangerous Functions: Blacklist includes dangerous PostgreSQL functions (pg_sleep, file I/O, etc.)

  3. SQL Parsing: Uses sqlglot for accurate SQL structure validation

  4. Injection Protection: Parameterized queries and input sanitization

  5. Resource Limits:

    • Row limit (default: 10,000)

    • Query timeout (default: 30 seconds)

    • Connection pool management

  6. Transaction Isolation: All queries run in a read-only transaction

Resilience Features

  • Circuit Breaker: Prevents cascading LLM API failures

  • Rate Limiting: Prevents API quota exhaustion

  • Retry Logic: Automatic retries for transient failures using exponential backoff

  • Connection Pooling: Efficient database connection reuse

  • Schema Caching: TTL-based caching to reduce database metadata queries

Configuration Reference

Database Settings

Variable

Description

Default

DATABASE_HOST

PostgreSQL Host

localhost

DATABASE_PORT

PostgreSQL Port

5432

DATABASE_NAME

Database Name

Required

DATABASE_USER

Database User

Required

DATABASE_PASSWORD

Database Password

Required

DATABASE_MIN_POOL_SIZE

Min pool connections

5

DATABASE_MAX_POOL_SIZE

Max pool connections

20

DATABASE_COMMAND_TIMEOUT

Query timeout (seconds)

30

OpenAI Settings

Variable

Description

Default

OPENAI_API_KEY

OpenAI API Key

Required

OPENAI_MODEL

Model to use

gpt-5.2-mini

OPENAI_MAX_TOKENS

Max tokens per request

32000

OPENAI_TEMPERATURE

Model temperature

0.0

OPENAI_TIMEOUT

API timeout (seconds)

30

Security Settings

Variable

Description

Default

SECURITY_ALLOW_WRITE_OPERATIONS

Allow INSERT/UPDATE/DELETE

false

SECURITY_BLOCKED_FUNCTIONS

Comma-separated blacklist

Refer .env.example

SECURITY_MAX_ROWS

Max rows per query

10000

SECURITY_MAX_EXECUTION_TIME

Query timeout (seconds)

30

Cache Settings

Variable

Description

Default

CACHE_ENABLED

Enable Schema caching

true

CACHE_SCHEMA_TTL

Schema cache TTL (sec)

3600

CACHE_MAX_SIZE

Max cached schemas

100

Resilience Settings

Variable

Description

Default

RESILIENCE_MAX_RETRIES

Max retries

3

RESILIENCE_RETRY_DELAY

Initial retry delay (s)

1.0

RESILIENCE_BACKOFF_FACTOR

Exponential backoff

2.0

RESILIENCE_CIRCUIT_BREAKER_THRESHOLD

Failures before trip

5

RESILIENCE_CIRCUIT_BREAKER_TIMEOUT

Circuit breaker timeout

60

Observability Settings

Variable

Description

Default

OBSERVABILITY_METRICS_ENABLED

Enable Prometheus metrics

true

OBSERVABILITY_METRICS_PORT

Metrics HTTP port

9090

OBSERVABILITY_LOG_LEVEL

Log level

INFO

OBSERVABILITY_LOG_FORMAT

Log format (json/text)

json

Development

Setting up Development Environment

# 安装开发依赖
uv sync --all-extras

# 安装 pre-commit 钩子(可选)
pre-commit install

Running Tests

# 运行所有测试
uv run pytest

# 运行并生成覆盖率报告
uv run pytest --cov=src --cov-report=html

# 运行特定测试类别
uv run pytest tests/unit/          # 仅单元测试
uv run pytest tests/integration/   # 集成测试
uv run pytest tests/e2e/           # 端到端测试
uv run pytest -m integration       # 标记为集成的测试

Code Quality

# 类型检查
uv run mypy src

# Lint 和格式化
uv run ruff check --fix .
uv run ruff format .

# 运行所有质量检查
uv run pytest --cov=src --cov-fail-under=80
uv run mypy src
uv run ruff check .

Project Structure

pg-mcp/
├── src/pg_mcp/
│   ├── cache/              # Schema 缓存
│   ├── config/             # 配置管理
│   ├── db/                 # 数据库连接池
│   ├── models/             # 数据模型
│   ├── observability/      # 日志、指标、追踪
│   ├── prompts/            # LLM Prompt 模板
│   ├── resilience/         # 熔断器、限流器
│   ├── services/           # 核心业务逻辑
│   │   ├── orchestrator.py      # 查询协调
│   │   ├── sql_generator.py     # 基于 LLM 的 SQL 生成
│   │   ├── sql_validator.py     # 安全验证
│   │   ├── sql_executor.py      # 查询执行
│   │   └── result_validator.py  # 结果验证
│   └── server.py           # FastMCP 服务器
├── tests/
│   ├── unit/               # 单元测试
│   ├── integration/        # 集成测试
│   └── e2e/                # 端到端测试
├── fixtures/               # 测试数据库 fixture
├── .env.example            # 环境模板
├── pyproject.toml          # 项目配置
└── main.py                 # 入口点

Docker Deployment

Building the Image

docker build -t pg-mcp:latest .

Running the Container

docker run -d \
  --name pg-mcp \
  -e DATABASE_HOST=your-db-host \
  -e DATABASE_NAME=your-db \
  -e DATABASE_USER=your-user \
  -e DATABASE_PASSWORD=your-password \
  -e OPENAI_API_KEY=sk-your-key \
  -p 9090:9090 \
  pg-mcp:latest

Docker Compose

# 启动所有服务(PostgreSQL + pg-mcp)
docker-compose up -d

# 查看日志
docker-compose logs -f pg-mcp

# 停止服务
docker-compose down

Refer to docker-compose.yml for detailed configuration.

Monitoring

Metrics

The server exposes Prometheus metrics on port 9090 (configurable):

curl http://localhost:9090/metrics

Available Metrics:

  • pg_mcp_queries_total - Total queries processed

  • pg_mcp_query_duration_seconds - Query execution time histogram

  • pg_mcp_sql_generation_duration_seconds - SQL generation time

  • pg_mcp_sql_validation_failures_total - Number of validation failures

  • pg_mcp_database_errors_total - Number of database errors

  • pg_mcp_llm_tokens_used_total - Total LLM tokens used

Logs

Structured JSON logs (or text format) are output to stdout:

{
  "timestamp": "2025-12-20T10:30:00.123Z",
  "level": "INFO",
  "message": "Query executed successfully",
  "database": "mydb",
  "execution_time": 0.023,
  "row_count": 42
}

Troubleshooting

Common Issues

Connection Refused

Error: Connection to database failed

Solution: Verify that PostgreSQL is running and credentials are correct:

psql -h $DATABASE_HOST -U $DATABASE_USER -d $DATABASE_NAME

OpenAI API Error

Error: OpenAI API request failed

Solution:

  1. Check if the API key is valid and has credits

  2. Verify network connectivity

  3. If requests time out, check the OPENAI_TIMEOUT setting

Query Timeout

Error: Query execution timeout exceeded

Solution:

  1. Increase SECURITY_MAX_EXECUTION_TIME

  2. Optimize the database (add indexes, VACUUM)

  3. Simplify the query or add filter conditions

Schema Cache Issues

Error: Schema not found in cache

Solution:

  1. Restart the server to reload the schema

  2. Verify the database user has schema read permissions

  3. Check if CACHE_ENABLED is set to true

Debug Mode

Enable debug logging:

export OBSERVABILITY_LOG_LEVEL=DEBUG
uv run python main.py

Claude Desktop Configuration

macOS/Linux Configuration

Edit ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "postgres": {
      "command": "uv",
      "args": [
        "--directory",
        "/Users/yourname/projects/pg-mcp",
        "run",
        "python",
        "main.py"
      ],
      "env": {
        "DATABASE_HOST": "localhost",
        "DATABASE_PORT": "5432",
        "DATABASE_NAME": "mydb",
        "DATABASE_USER": "postgres",
        "DATABASE_PASSWORD": "your-password",
        "OPENAI_API_KEY": "sk-your-api-key-here",
        "OPENAI_MODEL": "gpt-5.2-mini",
        "SECURITY_MAX_ROWS": "10000",
        "CACHE_ENABLED": "true",
        "OBSERVABILITY_LOG_LEVEL": "INFO"
      }
    }
  }
}

Windows Configuration

Edit %APPDATA%\Claude\claude_desktop_config.json:

{
  "mcpServers": {
    "postgres": {
      "command": "uv",
      "args": [
        "--directory",
        "C:\\Users\\YourName\\projects\\pg-mcp",
        "run",
        "python",
        "main.py"
      ],
      "env": {
        "DATABASE_HOST": "localhost",
        "DATABASE_NAME": "mydb",
        "DATABASE_USER": "postgres",
        "DATABASE_PASSWORD": "your-password",
        "OPENAI_API_KEY": "sk-your-api-key-here"
      }
    }
  }
}

Using Python Virtualenv

If not using UV, configure Python directly:

{
  "mcpServers": {
    "postgres": {
      "command": "/absolute/path/to/pg-mcp/.venv/bin/python",
      "args": ["main.py"],
      "cwd": "/absolute/path/to/pg-mcp",
      "env": {
        "DATABASE_HOST": "localhost",
        ...
      }
    }
  }
}

Restarting Claude Desktop

After editing the configuration:

  1. Quit Claude Desktop completely

  2. Restart Claude Desktop

  3. The PostgreSQL MCP server will be available

Security Considerations

Production Deployment

  1. Use a Read-Only Database User: Create a dedicated PostgreSQL user with only SELECT permissions:

CREATE USER pg_mcp_readonly WITH PASSWORD 'secure-password';
GRANT CONNECT ON DATABASE your_database TO pg_mcp_readonly;
GRANT USAGE ON SCHEMA public TO pg_mcp_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO pg_mcp_readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO pg_mcp_readonly;
  1. Protect API Keys: Use environment variables or a secret management system; never commit to version control

  2. Network Isolation: Run the server in an isolated network, restricting database access by IP

  3. Monitor Usage: Enable metrics and set up alerts for anomalous patterns

  4. Rate Limiting: Configure appropriate rate limiting parameters to prevent abuse

  5. Log Sanitization: Sensitive data is automatically filtered from logs

License

[Your License Information]

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Support

For questions and issues:

  • GitHub Issues: [repository-url]/issues

  • Documentation: Check the specs/w5/ directory for detailed design documents

Acknowledgments

Install Server
F
license - not found
B
quality
D
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Tools

Related MCP Servers

  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    Enables secure read-only interactions with PostgreSQL databases through natural language. Provides database inspection, table listing, and SQL query execution with built-in security validation.
  • A
    license
    A
    quality
    A
    maintenance
    Enables read-only interaction with PostgreSQL databases through natural language queries, supporting dynamic connections and secure query validation.
    3
    195
    2
    MIT

View all related MCP servers

Related MCP Connectors

View all MCP Connectors

Latest Blog Posts

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/lastfore/pg-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server