Postgres MCP Server

Postgres MCP Server

An AI database assistant that connects AI clients to a PostgreSQL database for schema exploration, safe querying, and LLM-powered SQL generation and reasoning.

Category
Visit Server

README

<div align="center">

๐Ÿ˜ Postgres MCP Server

An AI Database Assistant, built on the Model Context Protocol

Connects an AI client to a real PostgreSQL database โ€” schema exploration, safe querying, and LLM-powered reasoning, all through MCP tools.

Python PostgreSQL SQLAlchemy Groq Docker Tests

Docker Hub ยท Architecture ยท Installation ยท Example Tool Calls

</div>


What is this?

A production-grade Model Context Protocol (MCP) server that connects an AI client (like Claude) to a real PostgreSQL database, combining direct schema/data access with LLM-powered reasoning (via Groq) for SQL generation, query explanation, optimization, and business insight generation.

Built on a fictional company database ("Orbitals Inc.") โ€” a software consultancy with employees, departments, clients, projects, orders, invoices, support tickets, and meetings โ€” to exercise realistic relational queries and multi-hop relationships.

What makes this an "AI Database Assistant," not just a SQL executor

Capability Tool
Schema exploration list_tables, describe_table, list_columns, search_schema
Safe, validated querying execute_select (SELECT-only, injection-hardened, row-limited)
Relationship discovery find_related_tables (BFS over the FK graph, direct + indirect)
AI-assisted SQL generate_sql, explain_query, optimize_query
Business reasoning summarize_database, business_insights (generates SQL, executes it, interprets results in plain language)

The database is the source of truth for all facts; the LLM is used for reasoning, translation, and interpretation โ€” never as a substitute for real query execution.

Architecture

MCP Layer (tools/)        โ†’ thin, declares tools only
Service Layer (services/) โ†’ business logic, orchestration
Repository Layer (repositories/) โ†’ raw SQL / SQLAlchemy queries
Database Layer (db/)      โ†’ async engine, connection pooling
LLM Client Layer (llm/)   โ†’ Groq abstraction, provider-agnostic

Each layer only knows about the one below it โ€” MCP tools never touch the database directly, and the LLM provider is swappable behind an interface (llm/base.py) without touching services.

Folder Structure

postgres-mcp-server/
โ”œโ”€โ”€ src/postgres_mcp/
โ”‚   โ”œโ”€โ”€ config.py, server.py, logging_config.py, exceptions.py
โ”‚   โ”œโ”€โ”€ db/               # async engine, session management
โ”‚   โ”œโ”€โ”€ models/            # SQLAlchemy models (11 tables)
โ”‚   โ”œโ”€โ”€ repositories/       # raw SQL against Postgres
โ”‚   โ”œโ”€โ”€ services/           # business logic
โ”‚   โ”œโ”€โ”€ llm/                # Groq provider (swappable interface)
โ”‚   โ”œโ”€โ”€ tools/               # MCP tool registration
โ”‚   โ””โ”€โ”€ utils/                # SQL injection defenses (sql_guard.py)
โ”œโ”€โ”€ scripts/               # check_connection, check_llm, seed_database
โ”œโ”€โ”€ alembic/                # schema migrations
โ”œโ”€โ”€ tests/
โ”‚   โ”œโ”€โ”€ unit/                # sql_guard, schema_service, insight_service
โ”‚   โ””โ”€โ”€ integration/          # real Neon queries
โ”œโ”€โ”€ Dockerfile, docker-compose.yml
โ””โ”€โ”€ alembic.ini

Database Schema

11 tables modeling a software consultancy: departments, employees (self-referencing manager hierarchy), clients, projects, project_assignments (many-to-many), products, orders, invoices, support_tickets, meetings, meeting_attendees (many-to-many). Full relational integrity via foreign keys, check constraints (e.g., positive order quantities, valid status enums), and indexes on frequently-filtered columns.

Installation

Prerequisites

  • Python 3.12+
  • A Neon PostgreSQL database (free tier works)
  • A Groq API key (free tier works)
  • Docker (optional, for containerized runs)

Setup

git clone <your-repo-url>
cd postgres-mcp-server
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env
# fill in .env with your real Neon connection string and Groq API key

Environment Variables

Variable Description
DATABASE_URL Neon connection string, async form: postgresql+asyncpg://user:pass@host/db?ssl=require
GROQ_API_KEY Your Groq API key
GROQ_MODEL Model name (default: llama-3.3-70b-versatile)
LOG_LEVEL Logging verbosity (default: INFO)
ENVIRONMENT development or production

Neon Setup

  1. Create a free account and project at neon.tech
  2. Copy the connection string from your project dashboard
  3. Convert it to async form: change postgresql:// to postgresql+asyncpg://, and sslmode=require to ssl=require, dropping any channel_binding param

Database Setup

alembic upgrade head              # creates all 11 tables
python scripts/seed_database.py   # populates realistic fictional data

Running Locally

python -m postgres_mcp.server

This starts the MCP server over stdio transport. To test it interactively:

npx @modelcontextprotocol/inspector@latest python -m postgres_mcp.server

Running with Docker

docker build -t postgres-mcp-server:latest .
docker run -i --env-file .env postgres-mcp-server:latest

Or via Docker Compose:

docker compose up --build

Pre-built image available on Docker Hub:

docker pull amankhan1009/postgres-mcp-server:latest

Testing

pytest -m "not integration" -v   # unit + mocked tests (fast, no DB needed)
pytest -m integration -v          # integration tests (hits real Neon)
pytest -v                          # everything

22 tests passing: 20 unit/mocked (including full sql_guard injection-defense coverage) + 2 integration tests against real seeded data.

Example Tool Calls

list_tables()

["clients", "departments", "employees", "invoices", "meeting_attendees",
 "meetings", "orders", "products", "project_assignments", "projects", "support_tickets"]

business_insights("which department has the highest average employee salary?")

The department with the highest average employee salary is Engineering, with an average salary of $101,125.

find_related_tables("employees", max_depth=2)

{
  "table_name": "employees",
  "related_tables": {
    "departments": 1, "project_assignments": 1, "meeting_attendees": 1, "support_tickets": 1,
    "projects": 2, "clients": 2, "meetings": 2
  }
}

Security

  • All user/LLM-supplied SQL passes through sql_guard.py: single-statement enforcement, forbidden keyword/function blocking, and a hard row limit
  • Every query runs inside a READ ONLY Postgres transaction as a final safety net
  • Table names from tool inputs are validated against a live whitelist (list_tables()) before being used in any query, since identifiers can't be parameterized like values
  • Secrets are never baked into the Docker image โ€” passed only at runtime via --env-file
  • Container runs as a non-root user

Future Improvements

  • Optional, separately-hardened write capability (structured insert_row-style tools with strict table/column whitelisting, audit logging, and confirmation steps) โ€” deliberately out of scope for this version, which is read-only by design
  • Support for a second LLM provider (OpenAI/Anthropic) via the existing LLMProvider interface
  • Query result caching for repeated describe_table/list_tables calls
  • Rate limiting on execute_select and LLM-powered tools

<div align="center">

Built as a portfolio project to demonstrate production-grade backend architecture, PostgreSQL fluency, and safe AI-database integration via MCP.

</div>

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured