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.
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.
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
- Create a free account and project at neon.tech
- Copy the connection string from your project dashboard
- Convert it to async form: change
postgresql://topostgresql+asyncpg://, andsslmode=requiretossl=require, dropping anychannel_bindingparam
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 ONLYPostgres 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
LLMProviderinterface - Query result caching for repeated
describe_table/list_tablescalls - Rate limiting on
execute_selectand 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
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
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.
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.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
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.
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.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
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.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.