postgres-mcp-js
by shubham4038
README.md
# anydb-mcp
> **One MCP server. Any database. PostgreSQL, MySQL, and MongoDB — all at once.**
> Give Claude, Cursor, Windsurf, or any MCP-compatible AI safe, structured access to all your databases without ever exposing credentials.
---
## What is this?
**anydb-mcp** is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that connects AI assistants to your databases. Connect up to **3 databases simultaneously** — mix and match PostgreSQL, MySQL, and MongoDB. The AI can inspect schemas, diagnose performance problems, detect missing indexes, analyze locks, find slow queries across all databases in one call, and run safe read-only queries — all through a single, unified interface.
Works with: **Claude Desktop**, **Claude Code**, **Cursor**, **Windsurf**, **Zed**, and any MCP-compatible client.
---
## Features
- **PostgreSQL + MySQL + MongoDB** — connect any combination, up to 3 at once
- **Auto-detects DB type** from the URL prefix (`postgresql://`, `mysql://`, `mongodb://`)
- **Up to 3 databases simultaneously** — primary, secondary, tertiary — switchable per tool call
- **14 built-in tools** — schema inspection, health checks, index analysis, lock detection, bloat, slow queries
- **`list_slow_queries` fans out across all DBs** — one call, combined report from every connected database
- **Credential isolation** — passwords never appear in tool calls or AI responses; AI only sees aliases like `"primary"`
- **Restricted mode** — read-only transactions enforced at the database level (PostgreSQL/MySQL), 30s timeout
- **Index miss detection** — sequential scan hotspots, FK columns without indexes, unused index stats
- **Lock analysis** — blocking chains (PostgreSQL/MySQL), current operations (MongoDB)
- **Table bloat** — dead-tuple analysis with VACUUM recommendations (PostgreSQL)
- **hypopg support** — simulate hypothetical indexes before creating them (PostgreSQL)
- **Zero config** — credentials go in the MCP client `env` block, no `.env` file needed
---
## Quick start
### npx (no install needed)
```bash
npx anydb-mcp
```
### Global install
```bash
npm install -g anydb-mcp
anydb-mcp
```
### Local clone
```bash
git clone https://github.com/shubham4038/anydb-mcp.git
cd anydb-mcp
npm install && npm run build
node dist/index.js
```
---
## Connect to your AI
Credentials go in the `env` block — no `.env` file needed on the user's side.
### Claude Desktop
File: `~/Library/Application Support/Claude/claude_desktop_config.json`
```json
{
"mcpServers": {
"anydb": {
"command": "npx",
"args": ["anydb-mcp"],
"env": {
"DB_PRIMARY_URL": "postgresql://user:pass@localhost:5432/mydb",
"ACCESS_MODE": "restricted"
}
}
}
}
```
### Claude Code
File: `~/.claude/settings.json`
```json
{
"mcpServers": {
"anydb": {
"command": "npx",
"args": ["anydb-mcp"],
"env": {
"DB_PRIMARY_URL": "postgresql://user:pass@localhost:5432/mydb",
"ACCESS_MODE": "restricted"
}
}
}
}
```
### Cursor
**Settings → MCP → Add new MCP server:**
```json
{
"command": "npx",
"args": ["anydb-mcp"],
"env": {
"DB_PRIMARY_URL": "mysql://user:pass@localhost:3306/mydb",
"ACCESS_MODE": "restricted"
}
}
```
### Windsurf
File: `~/.codeium/windsurf/mcp_config.json`
```json
{
"mcpServers": {
"anydb": {
"command": "npx",
"args": ["anydb-mcp"],
"env": {
"DB_PRIMARY_URL": "mongodb://user:pass@localhost:27017/mydb"
}
}
}
}
```
---
## Connecting multiple databases
Mix any combination of PostgreSQL, MySQL, and MongoDB. The AI uses the alias to target the right database — it never sees connection strings.
```json
{
"env": {
"DB_PRIMARY_URL": "postgresql://user:pass@pg-host:5432/production",
"DB_PRIMARY_NAME": "production",
"DB_SECONDARY_URL": "mysql://user:pass@mysql-host:3306/legacy",
"DB_SECONDARY_NAME": "legacy",
"DB_TERTIARY_URL": "mongodb://user:pass@mongo-host:27017/analytics",
"DB_TERTIARY_NAME": "analytics",
"ACCESS_MODE": "restricted"
}
}
```
**DB type is auto-detected from the URL prefix:**
| URL prefix | Database |
|------------|----------|
| `postgresql://` or `postgres://` | PostgreSQL |
| `mysql://` or `mysql2://` | MySQL |
| `mongodb://` or `mongodb+srv://` | MongoDB |
**Example multi-DB AI prompts:**
- *"List slow queries across all my databases"*
- *"Compare index health between production and legacy"*
- *"Show me what's currently locking on production"*
- *"Is the analytics MongoDB missing any indexes?"*
---
## Tools
Every tool accepts an optional `database` parameter (defaults to the primary database). Call `list_databases` first to see what's configured.
### Schema inspection
| Tool | PostgreSQL | MySQL | MongoDB |
|------|:---:|:---:|:---:|
| `list_databases` | schemas | schemas | databases |
| `list_schemas` | ✅ | ✅ | ✅ |
| `list_objects` | tables/views | tables/views | collections |
| `get_object_details` | columns + indexes | columns + indexes | indexes + sample doc |
### SQL & query execution
| Tool | Description |
|------|-------------|
| `execute_sql` | PostgreSQL/MySQL: SQL string. MongoDB: JSON `{"db":"mydb","collection":"users","filter":{...}}`. Read-only in restricted mode |
| `explain_query` | EXPLAIN plan. PostgreSQL supports `hypothetical_indexes` via hypopg. MongoDB uses `executionStats` |
| `get_top_queries` | PostgreSQL: `pg_stat_statements`. MySQL: `performance_schema`. MongoDB: `system.profile` |
| `list_slow_queries` | **All databases at once** — historical + currently running slow queries, combined report |
### Index analysis
| Tool | PostgreSQL | MySQL | MongoDB |
|------|:---:|:---:|:---:|
| `analyze_workload_indexes` | ✅ full | ✅ via perf_schema | ✅ via $indexStats |
| `analyze_query_indexes` | ✅ EXPLAIN | ✅ EXPLAIN | ✅ explain() |
| `detect_index_misses` | ✅ seq scans + FK | ✅ perf_schema | ✅ $indexStats |
### Health checks
Pass `health_type: "all"` or any specific check:
| Check | PostgreSQL | MySQL | MongoDB |
|-------|:---:|:---:|:---:|
| `index` | unused/invalid/duplicate | unused via perf_schema | unused via $indexStats |
| `connection` | state breakdown | processlist | connections from serverStatus |
| `vacuum` | dead tuples + wraparound | ❌ N/A | ❌ N/A |
| `sequence` | sequences > 75% used | ❌ N/A | ❌ N/A |
| `replication` | replica lag + slots | ❌ N/A | ✅ replSetGetStatus |
| `buffer` | shared buffer hit ratio | InnoDB buffer pool | ❌ N/A |
| `constraint` | invalid constraints | ❌ N/A | ❌ N/A |
### Advanced diagnostics
| Tool | PostgreSQL | MySQL | MongoDB |
|------|:---:|:---:|:---:|
| `analyze_locks` | blocking chains + idle-in-tx | InnoDB trx + data_lock_waits | currentOp |
| `analyze_table_bloat` | ✅ dead tuples + VACUUM | not applicable | not applicable |
---
## Security model
| Protection | How it works |
|------------|-------------|
| **Credentials never reach the AI** | DB URLs read from env at startup only — never in tool args or results |
| **Alias-only identity** | AI sees `"production"` / `"legacy"`, never a hostname or password |
| **DB-level read-only** | PostgreSQL/MySQL: every query runs inside `BEGIN; SET TRANSACTION READ ONLY; ... ROLLBACK` |
| **Statement validation** | PostgreSQL/MySQL: first SQL keyword checked before query reaches the DB |
| **Query timeout** | 30-second `statement_timeout` on all queries |
| **Completely isolated adapters** | PostgreSQL, MySQL, MongoDB code never imports from each other — enforced by TypeScript |
---
## Optional extensions
### PostgreSQL
```sql
CREATE EXTENSION IF NOT EXISTS pg_stat_statements; -- enables get_top_queries
CREATE EXTENSION IF NOT EXISTS hypopg; -- enables hypothetical index simulation
```
Add to `postgresql.conf`:
```
shared_preload_libraries = 'pg_stat_statements'
```
### MySQL
`performance_schema` should be enabled by default in MySQL 5.6+. Verify:
```sql
SHOW VARIABLES LIKE 'performance_schema';
```
### MongoDB
Enable the profiler for slow query tracking:
```javascript
db.setProfilingLevel(1, { slowms: 100 })
```
---
## Docker
```bash
docker build -t anydb-mcp .
docker run --rm -i \
-e DB_PRIMARY_URL="postgresql://user:pass@host:5432/mydb" \
-e DB_SECONDARY_URL="mysql://user:pass@host:3306/mydb" \
-e ACCESS_MODE=restricted \
anydb-mcp
```
---
## Local development
```bash
git clone https://github.com/shubham4038/anydb-mcp.git
cd anydb-mcp
npm install
npm run dev # runs with tsx, no build step needed
npm run typecheck # type check only
npm run build # production build
```
---
## Architecture
Each database adapter is **100% self-contained**. PostgreSQL code never imports MySQL code, MySQL never imports MongoDB code. They only share a common TypeScript interface.
```
src/
adapters/
types.ts ← shared interface only (no logic)
postgres/ ← all PostgreSQL code, isolated
mysql/ ← all MySQL code, isolated
mongodb/ ← all MongoDB code, isolated
db/
registry.ts ← only place that knows all 3 adapters exist
server.ts ← MCP tools, calls adapter.method() without knowing which DB
```
---
## GitHub topics
Add these in **Settings → Topics** for discoverability:
`mcp` `model-context-protocol` `postgresql` `mysql` `mongodb` `database` `multi-database` `ai` `claude` `cursor` `llm` `developer-tools` `typescript` `nodejs`
---
## License
MIT — free to use, modify, and distribute.
TDQS
A3.7/5.0
Scored across 13 tools
Disambiguation4/5
Most tools have clear and distinct purposes, though the index analysis tools (analyze_query_indexes, analyze_workload_indexes, detect_index_misses) overlap somewhat in focus, potentially causing some confusion for an agent.
Naming Consistency5/5
All tools use a consistent underscore-separated verb_noun pattern (e.g., analyze_locks, list_databases), making the tool set predictable and easy to navigate.
Tool Count5/5
With 13 tools, the set is well-scoped for a database analysis server, covering essential operations without being overwhelming or insufficient.
Completeness5/5
The tool set comprehensively covers read-only database analysis: health, locks, bloat, indexes, query explanation, and object listing. There are no obvious gaps for its stated purpose.
Maintenance
ActivityStale
ResponsivenessNo issues