mcp-database
MCP server for multiple databases (PostgreSQL, MySQL, MariaDB, SQLite, MongoDB, Redis) with tools for schema inspection, querying, performance diagnostics, and safe write operations, featuring access modes, PII masking, and audit logging.
README
mcp-database
MCP database server for PostgreSQL, MySQL, MariaDB, SQLite, MongoDB, and Redis. One connection per instance, per-connection access modes, and a full performance-diagnosis toolkit for dev, SRE, and DBA workflows.
Contents
- Supported databases
- Features
- Tools
- Quick start
- Configuration
- Architecture
- Querying
- Docker
- Connecting to each engine
- Development
- References
- License
Supported databases
One connection per instance; the engine is inferred from the URI scheme (override with ENGINE_TYPE).
| Database | URI scheme | ENGINE_TYPE |
Driver | Highlights |
|---|---|---|---|---|
| PostgreSQL | postgresql://, postgres:// |
postgres |
psycopg 3 | pgvector KNN, native full-text search, HypoPG hypothetical indexes, transactional DDL dry-run, planner column stats |
| MySQL | mysql:// |
mysql |
aiomysql | FULLTEXT search, planner column stats + histograms, performance_schema diagnostics |
| MariaDB | mariadb:// |
mariadb |
aiomysql | Follows the MySQL surface with the engine differences absorbed (max_statement_time, SHOW SLAVE HOSTS) |
| SQLite | sqlite:///relative.db, sqlite:////absolute.db |
sqlite |
aiosqlite | File databases with structurally read-only reads (mode=ro), FTS5 text search, EXPLAIN QUERY PLAN |
| MongoDB | mongodb://, mongodb+srv:// |
mongodb |
PyMongo (async) | Atlas $search / $vectorSearch, aggregation reads, replica-set / shard topology |
| Redis | redis://, rediss:// |
redis |
redis-py (async) | Allowlisted command envelope (FLUSH*/EVAL/KEYS never allowed), SCAN-based inspection, SLOWLOG/INFO/ACL diagnostics |
Engine support per tool (some features are engine-specific — e.g. HypoPG is PostgreSQL-only) is in docs/tools.md. CI verifies every tool against real PostgreSQL 16/17, MySQL 8.0/8.4, MariaDB 10.11/11.4, SQLite, MongoDB 7/8, and Redis 7/8 (plus pgvector and Atlas-local images) on every push.
Features
- 39 tools, risk-encoded names.
db_schema_*/db_read_*/db_perf_*never write (safe to always-allow);db_write_*/db_admin_*need approval. - Vector + full-text search. pgvector KNN and FTS (PostgreSQL), FULLTEXT (MySQL), Atlas
$search/$vectorSearch(MongoDB), plus index inspection and quality diagnostics. - Cluster tooling. Replication-lag and topology triage (
db_perf_cluster) with audited actions: promote, start/stop replica, step down, freeze. - Access modes per connection.
read_write,read_only,monitor(perf analysis with no data access, for production with PII). - Fail-closed read validation. sqlglot rejects writes, DDL, multi-statement and dangerous functions; MongoDB is limited to a read-only op allowlist.
- Fine-grained write control.
write_opslimits which operations run;database_modessets a different mode per database. - Write safety belts.
dry_run(execute, roll back, report impact) andexpected_max_rows(auto-abort oversized writes). - PII masking.
redact_fieldsmasks values with***;["*"]shows type placeholders only, never values. - Audit log. Every write, admin and export call is logged as JSONL (mode 600); literals become
?, so PII never touches disk. - Result limits. 500 rows / 1 MiB per response with source-side
LIMITinjection;db_read_exportstreams big results to JSON/CSV.
Tools
Full reference with parameters and per-database support indicators: docs/tools.md.
| Class | Tools | Safe to always-allow |
|---|---|---|
db_schema_ |
connections, databases, objects, describe, ddl, search, relationships, users, grants, search_indexes | ✅ |
db_read_ |
query, sample, export, vector_search, text_search | ✅ |
db_perf_ |
explain, column_stats, diagnose, top_queries, active_ops, blocking, index_stats, table_stats, health, replication, settings, logs, vector_stats, cluster | ✅ |
db_write_ |
query (with dry_run / expected_max_rows), search_index |
case by case |
db_admin_ |
kill, analyze, maintain, cluster | case by case |
Access-mode matrix:
| Class | read_write |
read_only |
monitor |
|---|---|---|---|
db_schema_ |
✅ | ✅ | ✅ (no data sampling) |
db_read_ |
✅ | ✅ | ❌ |
db_perf_ |
✅ | ✅ | ✅ |
db_write_ / db_admin_ |
✅ | ❌ | ❌ |
Quick start
Requirements: Docker (runs both the playground databases and the published server image). uv is only needed for local development.
# 1. Clone (for the playground compose file and seed data)
git clone https://github.com/DiegoBulhoes/mcp-database.git && cd mcp-database
# 2. Start and seed the playground databases (PostgreSQL + MySQL + MongoDB)
make up && make mongo-rs && make seed
# 3. Register with Claude Code — runs the published image, one connection per server entry.
# All configuration lives in --env; the docker -e flags are a fixed forwarding template.
claude mcp add db-postgres \
--env URI="postgresql://dev:dev@localhost:5432/app" \
--env ENGINE_TYPE=postgres \
--env MODE=read_write \
-- docker run -i --rm --network host -e URI -e ENGINE_TYPE -e MODE -e NAME \
ghcr.io/diegobulhoes/mcp-database:latest
--network hostlets the container reachlocalhostdatabases (Linux). On macOS/Windows Docker Desktop, drop it and usehost.docker.internalin the URI instead.
Then ask Claude things like "why is pg_app slow?" and it will chain db_perf_active_ops → db_perf_blocking → db_perf_top_queries → db_perf_explain without a single permission prompt (see below).
Querying
You don't call the tools yourself; your AI assistant does, picking the connection by name (it discovers what exists via db_schema_connections). You just ask in natural language:
| You ask | The assistant calls |
|---|---|
| "how many orders over 100 in pg_app?" | db_read_query(conn="pg_app", query="SELECT count(*) FROM orders WHERE total > 100") |
| "top pages by clicks in mongo_app" | db_read_query(conn="mongo_app", query={"collection": "events", "operation": "aggregate", "pipeline": [{"$group": {"_id": "$page", "n": {"$sum": 1}}}]}) |
| "why is pg_app slow?" | db_perf_active_ops → db_perf_blocking → db_perf_top_queries → db_perf_explain (the SRE runbook, no prompts) |
| "upgrade user 42 to the pro plan" | db_write_query(conn="pg_app", query="UPDATE users SET plan = 'pro' WHERE id = 42", expected_max_rows=1) (this one asks for your approval) |
The query argument depends on the connection type:
- PostgreSQL / MySQL: a SQL string.
db_read_queryaccepts only SELECT/UNION/VALUES (parser-validated, fail-closed); everything else goes throughdb_write_query. - MongoDB: a JSON object
{"collection", "operation", ...}. Reads:find,aggregate,countDocuments,distinct,listIndexes; writes (viadb_write_query):insertMany,updateMany,deleteMany,createIndex.
Example query values:
SELECT id, total FROM orders WHERE total > 100 ORDER BY total DESC LIMIT 20
{"collection": "events", "operation": "aggregate",
"pipeline": [{"$group": {"_id": "$page", "n": {"$sum": 1}}}, {"$sort": {"n": -1}}]}
Write safety belts on db_write_query:
- Unbounded-mutation guard: an
UPDATE/DELETEwith noWHERE(or a MongoDBupdateMany/deleteManywith an empty filter) is rejected outright unless the caller declares intent — either adry_runor anexpected_max_rows. This stops a careless model from wiping a whole table without saying so. (DROP/TRUNCATEare explicit by nature and stay allowed.) dry_run: trueexecutes inside a transaction and rolls back, reporting how many rows would be affected.expected_max_rows: Naborts with rollback if the write would affect more than N rows (catches a missing WHERE before it hurts).
References
Projects and resources that shaped this server's design:
- Model Context Protocol: protocol specification and the Python SDK (FastMCP) this server is built on.
- anthropics/skills (Anthropic): two skills from this repo are bundled in
.claude/skills/: mcp-builder, whose best practices this server was audited against (tool naming with thedb_service prefix, parameter descriptions, annotations, actionable errors, and the agent evaluations format), and algorithmic-art for generative-art sessions. - postgres-mcp (Crystal DBA): inspiration for access modes, safe SQL execution, and the performance/health tool set.
- mongodb-mcp-server (MongoDB): inspiration for the export tool, byte-based response limits, and server log access.
- mcp-server-mysql (Ben Borla): inspiration for per-operation write permissions (
write_ops) and per-database modes (database_modes).
License
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.