by Souhar-dya
Provides a RESTful API that converts natural language queries into SQL statements and executes them against PostgreSQL or MySQL databases, returning structured results.
Mcp Db Server exposes relational databases (PostgreSQL, MySQL, SQLite) through a FastAPI‑based HTTP interface. It translates plain English questions into safe, read‑only SQL queries using HuggingFace transformer models, then returns the query results as JSON suitable for AI agents.
Docker Compose (recommended)
git clone https://github.com/Souhar-dya/mcp-db-server.git
cd mcp-db-server
export MCP_API_KEY="$(openssl rand -hex 32)"
docker-compose up --build
The service will be reachable at http://localhost:8000.
Local development
pip install -r requirements.txt
export DATABASE_URL="postgresql+asyncpg://user:pass@localhost:5432/dbname"
export MCP_API_KEY="$(openssl rand -hex 32)"
python -m app.server
Calling the API (all database routes require the X‑API‑Key header)
curl -H "X-API-Key: $MCP_API_KEY" http://localhost:8000/mcp/list_tables
curl -X POST http://localhost:8000/mcp/query \
-H "X-API-Key: $MCP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"nl_query": "top 5 customers by total order amount"}'
X‑API‑Key authentication for all data endpoints127.0.0.1, CORS disabled unless configuredsouhardyak/mcp-db-server:1.4.0 / latest)/health) for container orchestration/docsQ: Which databases are supported? A: PostgreSQL, MySQL/MariaDB (via async drivers) and SQLite (for quick local testing).
Q: Can I run INSERT/UPDATE statements? A: No. The server enforces read‑only SELECT operations for safety.
Q: How is SQL injection prevented? A: The NL‑to‑SQL model output is validated, table names are checked against the actual schema, and only SELECT statements are allowed. Results are also capped.
Q: Do I need to expose the API key publicly?
A: No. Set MCP_API_KEY as an environment variable and pass it in the X‑API‑Key header for every protected request.
Q: How do I enable CORS for a web front‑end?
A: Populate the CORS_ALLOW_ORIGINS environment variable with a comma‑separated list of allowed origins.
Q: What port does the server listen on?
A: Default 8000 on 127.0.0.1; customize via HOST and PORT environment variables.
An MCP (Model Context Protocol) server that exposes relational databases (PostgreSQL/MySQL) to AI agents with natural language query support. Transform natural language questions into SQL queries and get structured results.
X-API-Key authentication for all database HTTP endpoints; /health remains public for health checks.127.0.0.1.sslmode=require compatibility for asyncpg connections.souhardyak/mcp-db-server:1.4.0souhardyak/mcp-db-server:latest| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Health check and service status |
/mcp/list_tables |
GET | List all available tables with column counts |
/mcp/describe/{table_name} |
GET | Get detailed schema for a specific table |
/mcp/query |
POST | Execute natural language queries |
/mcp/tables/{table_name}/sample |
GET | Get sample data from a table |
Clone and start the services:
git clone https://github.com/Souhar-dya/mcp-db-server.git
cd mcp-db-server
export MCP_API_KEY="$(openssl rand -hex 32)"
docker-compose up --build
Test the endpoints:
# Health check
curl http://localhost:8000/health
# List tables (requires the configured API key)
curl -H "X-API-Key: $MCP_API_KEY" http://localhost:8000/mcp/list_tables
# Describe a table
curl -H "X-API-Key: $MCP_API_KEY" http://localhost:8000/mcp/describe/customers
# Natural language query
curl -X POST "http://localhost:8000/mcp/query" \
-H "X-API-Key: $MCP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"nl_query": "show top 5 customers by total orders"}'
Prerequisites:
Install dependencies:
pip install -r requirements.txt
Set environment variables:
export DATABASE_URL="postgresql+asyncpg://user:password@localhost:5432/dbname"
export MCP_API_KEY="$(openssl rand -hex 32)"
# or for MySQL:
# export DATABASE_URL="mysql+pymysql://user:password@localhost:3306/dbname"
Run the server:
python -m app.server
The project includes a sample database with realistic e-commerce data:
The server can understand various types of natural language queries:
# Get all customers
curl -X POST "http://localhost:8000/mcp/query" \
-H "Content-Type: application/json" \
-d '{"nl_query": "show all customers"}'
# Count orders by status
curl -X POST "http://localhost:8000/mcp/query" \
-H "Content-Type: application/json" \
-d '{"nl_query": "count orders by status"}'
# Top customers by order value
curl -X POST "http://localhost:8000/mcp/query" \
-H "Content-Type: application/json" \
-d '{"nl_query": "top 5 customers by total order amount"}'
# Recent orders
curl -X POST "http://localhost:8000/mcp/query" \
-H "Content-Type: application/json" \
-d '{"nl_query": "show recent orders from last week"}'
| Variable | Description | Default |
|---|---|---|
DATABASE_URL |
Full database connection URL | postgresql+asyncpg://postgres:postgres@localhost:5432/postgres |
DB_HOST |
Database host | localhost |
DB_PORT |
Database port | 5432 |
DB_USER |
Database username | postgres |
DB_PASSWORD |
Database password | postgres |
DB_NAME |
Database name | postgres |
HOST |
Server host | 127.0.0.1 |
PORT |
Server port | 8000 |
MCP_API_KEY |
Required API key for database HTTP routes | Not set (API disabled) |
CORS_ALLOW_ORIGINS |
Comma-separated allowed browser origins | Empty (disabled) |
# PostgreSQL
DATABASE_URL=postgresql+asyncpg://user:pass@localhost:5432/mydb
# MySQL
DATABASE_URL=mysql+pymysql://user:pass@localhost:3306/mydb
# PostgreSQL with SSL
DATABASE_URL=postgresql+asyncpg://user:pass@localhost:5432/mydb?sslmode=require
### Database Connection Examples
```bash
# PostgreSQL (local or cloud)
DATABASE_URL=postgresql+asyncpg://user:password@host:5432/dbname
# MySQL (local or cloud)
DATABASE_URL=mysql+aiomysql://user:password@host:3306/dbname
# PostgreSQL with SSL (cloud, e.g. Neon, Supabase, Aiven)
DATABASE_URL=postgresql+asyncpg://user:password@host:5432/dbname?sslmode=require
# MySQL with SSL (cloud, e.g. Aiven, PlanetScale)
DATABASE_URL=mysql+aiomysql://user:password@host:3306/dbname?ssl-mode=REQUIRED
Note:
- For MySQL cloud providers, the
ssl-modeparameter in the URL is ignored by the driver, but SSL is always enabled in the MCP server for cloud connections.- For PostgreSQL, use
sslmode=requirefor cloud DBs. For MySQL, just use the standard URL; SSL is handled automatically.- If you see errors about
ssl-modeorsslmode, check your URL and ensure you are using the correct driver prefix (mysql+aiomysqlorpostgresql+asyncpg).
# Neon (PostgreSQL)
DATABASE_URL=postgresql+asyncpg://username:password@ep-xxxxxx-pooler.us-east-2.aws.neon.tech/dbname
# Aiven (MySQL)
DATABASE_URL=mysql+aiomysql://avnadmin:yourpassword@mysql-xxxxxx-username-xxxx.aivencloud.com:11079/defaultdb?ssl-mode=REQUIRED
docker run -d \
-p 8000:8000 \
-e DATABASE_URL="<your_cloud_database_url>" \
-e MCP_API_KEY="<your_random_api_key>" \
souhardyak/mcp-db-server:latest
connect() got an unexpected keyword argument 'ssl-mode', ignore it: SSL is still enabled.mysql+aiomysql in the URL for async support.
### PostgreSQL SSL connection note
For PostgreSQL cloud providers, use an asyncpg URL and `sslmode=require`:
```bash
DATABASE_URL=postgresql+asyncpg://user:password@host:5432/dbname?sslmode=require
The server normalizes sslmode=require to the ssl option expected by asyncpg. A temporary PostgreSQL verification was completed successfully against a compatible cloud database using CREATE, INSERT, SELECT, UPDATE, DELETE, and DROP; no test data was retained. Never commit or share a connection URL containing a real password.
MCP_API_KEY is a secret that you generate and provide to the server. It protects all database HTTP endpoints through the X-API-Key request header. The /health endpoint remains public for container health checks.
Generate a strong key on Linux or macOS:
export MCP_API_KEY="$(openssl rand -hex 32)"
Generate one in Windows PowerShell:
$bytes = New-Object byte[] 32
[Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes)
$env:MCP_API_KEY = ([BitConverter]::ToString($bytes) -replace "-", "").ToLower()
Start the Docker image with the key:
docker run -d \
-p 8000:8000 \
-e DATABASE_URL="<your_database_url>" \
-e MCP_API_KEY="$MCP_API_KEY" \
souhardyak/mcp-db-server:latest
Call a protected endpoint with the same key:
curl -H "X-API-Key: $MCP_API_KEY" http://localhost:8000/mcp/list_tables
Keep the key in a password manager or deployment secret store. Do not commit it to Git, put it in a public image, or include it in logs.
X-API-Key; /health remains public for health checks127.0.0.1 unless explicitly configured otherwisemcp-db-server/
├── app/
│ ├── __init__.py # Package initialization
│ ├── server.py # FastAPI application and endpoints
│ ├── db.py # Database connection and operations
│ └── nl_to_sql.py # Natural language to SQL conversion
├── .github/workflows/
│ └── docker-publish.yml # CI/CD pipeline
├── docker-compose.yml # Docker Compose configuration
├── Dockerfile # Container definition
├── init_db.sql # Sample database schema and data
├── requirements.txt # Python dependencies
└── README.md # This file
This server is designed to work seamlessly with MCP-compatible AI agents:
/docsVS Code MCP gallery uses MCP Registry metadata. This repository now includes
server.json for registry publication.
docker build -t souhardyak/mcp-db-server:1.3.1 .
docker push souhardyak/mcp-db-server:1.3.1
server.json is configured for an OCI package and stdio transport:
name: io.github.Souhar-dya/mcp-db-serverregistryType: ociidentifier: docker.io/souhardyak/mcp-db-server:1.3.1The Dockerfile includes registry ownership annotation:
io.modelcontextprotocol.server.name=io.github.Souhar-dya/mcp-db-serverInstall publisher and publish metadata:
mcp-publisher login github
mcp-publisher publish
After publishing, users can discover/install it from MCP-compatible clients, including VS Code MCP experiences that read from the registry.
{
"servers": {
"mcp-db-server": {
"type": "stdio",
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e",
"DATABASE_URL=sqlite+aiosqlite:////data/default.db",
"souhardyak/mcp-db-server:1.3.1"
]
}
}
}
Use the dedicated Docker smoke test in tests/docker:
python tests/docker/smoke_test.py
This verifies Docker daemon access, image build, container startup, and health status.
# Pull the latest image
docker pull souhardyak/mcp-db-server:latest
# Run with your database
docker run -d \
-p 8000:8000 \
-e DATABASE_URL="your_database_url_here" \
souhardyak/mcp-db-server:latest
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcp-db-server
spec:
replicas: 3
selector:
matchLabels:
app: mcp-db-server
template:
metadata:
labels:
app: mcp-db-server
spec:
containers:
- name: mcp-db-server
image: souhardyak/mcp-db-server:latest
ports:
- containerPort: 8000
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-secret
key: url
---
apiVersion: v1
kind: Service
metadata:
name: mcp-db-server-service
spec:
selector:
app: mcp-db-server
ports:
- port: 80
targetPort: 8000
type: LoadBalancer
# Start test database
docker-compose up postgres -d
# Wait for database to be ready
sleep 10
# Run tests
python -m pytest tests/ -v
# Test health endpoint
curl http://localhost:8000/health
# Test table listing
curl http://localhost:8000/mcp/list_tables
# Test natural language query
curl -X POST "http://localhost:8000/mcp/query" \
-H "Content-Type: application/json" \
-d '{"nl_query": "show me all customers from California"}'
git checkout -b feature/amazing-feature)git commit -m 'Add some amazing feature')git push origin feature/amazing-feature)This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
from db import DatabaseManager to failmcp_server.py now uses robust path resolution that works both locally and in Docker containersCould not locate column in row for column 'column_name' error with MySQL databasesdescribe_table method to use index-based row access for better SQLAlchemy compatibilitystr can't be used in 'await' expression error in MCP server⭐ If this project helped you, please consider giving it a star!
Please log in to share your review and rating for this MCP.
Explore related MCPs that share similar capabilities and solve comparable challenges
by googleapis
An MCP server that streamlines database tool development by handling connection pooling, authentication, observability, and secure access, allowing agents to interact with databases via natural language.
by TabularisDB
Provides a cross‑platform desktop workspace for managing, exploring, and querying a wide range of relational and NoSQL databases, with built‑in AI assistance, visual query building, and an extensible plugin system.
by bytebase
Provides a universal gateway that lets MCP‑compatible clients explore and query MySQL, PostgreSQL, SQL Server, MariaDB, and SQLite databases through a single standardized interface.
by designcomputer
Enables secure interaction with MySQL databases via the Model Context Protocol, allowing AI applications to list tables, read contents, and execute queries safely.
by benborla
Provides read‑only access to MySQL databases for large language models, allowing schema inspection and safe execution of SQL queries.
by neo4j-contrib
Enables natural‑language interaction with Neo4j databases, allowing large language models to query, modify, and manage graph data through multiple transport modes.
by mongodb-js
Provides a Model Context Protocol server that enables interaction with MongoDB databases and MongoDB Atlas clusters through a unified API.
by ClickHouse
Enables AI assistants to run read‑only ClickHouse queries, list databases and tables, and execute embedded chDB queries through an MCP interface.
by neondatabase
Interact with Neon Postgres databases using natural language commands through the Model Context Protocol, enabling conversational database creation, migration, and query execution.