Skip to main content
Glama
swoiow

Database MCP

by swoiow

DB-MCP Gateway

A multi-database MCP gateway with table-level access control.

Manage MySQL and PostgreSQL connections through a web admin UI, create scoped MCP endpoints, and assign users via token-based ACL.

Architecture

┌─────────────────────────────────────────────────────────┐
│                    DB-MCP Gateway                       │
│                                                         │
│  Connection ─── credentials (admin, all tables)         │
│       │                                                 │
│       ├── Endpoint ─── MCP exposure + table scope       │
│       │     e.g. /mysql/orders-api (tables: orders,     │
│       │           order_items)                          │
│       │                                                 │
│       └── Endpoint ─── MCP exposure (all tables)        │
│             e.g. /mysql/full-access                     │
│                                                         │
│  ACL: User ──► Endpoint                                 │
│  (token-based, one user can access multiple endpoints)  │
│                                                         │
│  Admin UI: /admin                                       │
│  User discovery: /api/endpoints?token=xxx               │
└─────────────────────────────────────────────────────────┘

Three-layer model:

  • Connection — database credentials. Admin-level, no restrictions.

  • Endpoint — MCP exposure layer. References one connection. Optionally restricts which tables are visible via allowed_tables whitelist. Empty whitelist = all tables.

  • ACL — binds a user to an endpoint. Users authenticate by token.

One connection can back multiple endpoints with different table scopes.

Related MCP server: MCP Universal DB Client

Permission model (gateway-owned)

The gateway holds the admin DB credentials and executes every query itself. Permissions are enforced at two levels, both in the gateway:

  • L1 — endpoint access: every request to an MCP endpoint (/{db_type}/{alias}/sse|/messages|/mcp) must carry a user token, either as Authorization: Bearer <token> (preferred) or ?token=. The gateway checks the token → endpoint ACL; no grant → 403.

  • L2 — table scope: per tool call, referenced tables are extracted from the SQL AST (sqlglot) and checked against the endpoint's allowed_tables; execute_sql additionally rejects anything that is not a single pure SELECT (blocks data-modifying CTEs, SELECT INTO, INTO OUTFILE, stacked queries).

Features

  • Multi-database: unlimited MySQL and PostgreSQL connections.

  • Table-level scoping: each endpoint can whitelist specific tables. get_all_schemas / get_tables filter results; get_table_schema blocks unauthorized tables; execute_sql validates table references.

  • Web admin UI: light/dark theme, pagination, search, batch import, bulk ACL assignment. Accessible at /admin.

  • Token-based user auth: each user gets a hex token. Users query /api/endpoints?token=xxx to discover their available MCP servers.

  • Dynamic mounting: endpoints are mounted/unmounted on config change without restart.

  • Standalone servers: server_mysql.py and server_pgsql.py can run independently with .env config (SDK 1.27+, v1 API).

  • Optional TTL cache: per-call use_cache/ttl parameters (gateway and standalone).

  • Two transports: SSE (/sse, /messages) and Streamable HTTP (/mcp) mounted per endpoint.

  • Audit log: every MCP tool call appended as JSONL (audit.log).

  • Usage metering: per user / endpoint / tool counters (GET /admin/api/metering, persisted to metering.json).

  • Runtime guards: query timeout, server-side max_rows cap, per-(user, endpoint) rate limiting (all env-configurable).

  • AST read-only guard: sqlglot-based, blocks data-modifying CTEs, SELECT INTO, INTO OUTFILE, stacked queries.

Project Structure

gateway.py              # FastAPI gateway entrypoint
gateway_config.py       # Models + pickle persistence
gateway_api.py          # Admin + user API routes
gateway_mcp_factory.py  # Dynamic per-endpoint MCP server creation

server_mysql.py         # Standalone MySQL MCP server (SDK 1.27+)
server_pgsql.py         # Standalone PostgreSQL MCP server (SDK 1.27+)

core/
  base.py               # Abstract driver interface
  cache.py              # In-process TTL cache
  sqlguard.py           # AST read-only guard + table extraction (sqlglot)
  engines.py            # Process-wide async engine cache
  ctx.py                # Per-request context (L1 identity for tools)
  audit.py              # JSONL query audit log
  metering.py           # Usage counters (persisted JSON)
  ratelimit.py          # Sliding-window rate limiter

tests/                  # pytest: guard, scope, persistence, auth, metering

drivers/
  mysql_driver.py       # MySQL driver (SQLAlchemy + aiomysql)
  pgsql_driver.py       # PostgreSQL driver (SQLAlchemy + asyncpg)

prompts/
  mysql_prompts.py      # MySQL built-in prompts (bilingual)
  pgsql_prompts.py      # PostgreSQL built-in prompts (bilingual)

static/
  admin.html            # Admin management UI

gateway_data.json       # Persisted config (JSON; legacy .pkl auto-migrated)
requirements.txt
Dockerfile
.env.sample

Quick Start

Gateway mode

pip install -r requirements.txt
uvicorn gateway:app --host 0.0.0.0 --port 8000

Open http://localhost:8000/admin to configure connections, endpoints, users, and ACL.

Standalone MySQL

uvicorn server_mysql:app --host 0.0.0.0 --port 8001

Standalone PostgreSQL

uvicorn server_pgsql:app --host 0.0.0.0 --port 8002

Standalone servers read connection info from .env (see .env.sample).

Docker

docker build -t db-mcp:latest .

# Gateway (default)
docker run --rm -p 8000:8000 db-mcp:latest

# MySQL only
docker run --rm -p 8001:8001 -e TARGET=mysql db-mcp:latest

# PostgreSQL only
docker run --rm -p 8002:8002 -e TARGET=pgsql db-mcp:latest

Admin UI

Visit /admin. The UI has four tabs:

  1. Connections — add/edit/delete database connections. Batch import via JSON array. Search and filter by type.

  2. Endpoints — create MCP endpoints backed by a connection. Set allowed_tables to restrict table access (one per line, supports table, db.table, schema.table). Leave empty for all tables.

  3. Users — create users, view/regenerate tokens.

  4. ACL — assign endpoints to users. Bulk assign supported.

First startup creates a default admin user automatically. Check the Users tab for the token.

Securing the admin API

Set ADMIN_TOKEN before starting the gateway:

export ADMIN_TOKEN="a-long-random-string"
uvicorn gateway:app --host 0.0.0.0 --port 8000

When set, every /admin/api/* call must carry Authorization: Bearer <ADMIN_TOKEN> (the bundled admin UI has a token box in the top bar and stores it in localStorage). Without it the server logs a warning and leaves the admin API open (dev only).

Connection passwords are write-only: accepted on create/update, but read APIs always return "password": "***". To change a password, edit the connection and type the new one (blank = keep unchanged).

MCP Endpoints

Each endpoint exposes SSE and Streamable HTTP transports:

SSE:              /{db_type}/{endpoint_alias}/sse
SSE messages:     /{db_type}/{endpoint_alias}/messages
Streamable HTTP:  /{db_type}/{endpoint_alias}/mcp

Also accessible by endpoint ID:
SSE:              /{db_type}/{endpoint_id}/sse

User endpoint discovery

GET /api/endpoints?token=USER_TOKEN

Returns the list of endpoints the user can access, with MCP paths and table scope info. Every MCP request to those paths must then carry the token as Authorization: Bearer <token> (or ?token=).

Table scoping example

Connection prod-mysql points to a MySQL instance with full access. You create three endpoints:

Endpoint Alias

Connection

allowed_tables

Use case

orders-api

prod-mysql

orders, order_items

Order service

users-api

prod-mysql

users, user_profiles

User service

full-access

prod-mysql

(empty = all)

Internal admin

Assign orders-api to user A, users-api to user B, full-access to user C. Each gets their own MCP server URL.

API Reference

Admin API (/admin/api)

Method

Path

Description

GET

/connections

List connections

POST

/connections

Create connection

PATCH

/connections/{id}

Update connection

DELETE

/connections/{id}

Delete connection (+ cascade)

POST

/connections/batch

Batch create

GET

/endpoints

List endpoints

POST

/endpoints

Create endpoint

PATCH

/endpoints/{id}

Update endpoint

DELETE

/endpoints/{id}

Delete endpoint (+ cascade)

GET

/users

List users

POST

/users

Create user

DELETE

/users/{id}

Delete user (+ cascade)

POST

/users/{id}/regen-token

Regenerate token

GET

/acl

List ACL rules

POST

/acl

Create ACL rule

POST

/acl/batch

Batch create ACL

DELETE

/acl/{id}

Delete ACL rule

GET

/metering

Usage counters (users/endpoints/tools)

POST

/admin/reload

Resync MCP mounts

User API (/api)

Method

Path

Description

GET

/endpoints?token=xxx

Discover accessible endpoints

MCP Tools

Each endpoint exposes these tools (names vary by db_type):

Tool

Description

get_all_schemas

List databases/schemas with tables/columns (filtered by scope)

get_tables

List tables (filtered by scope)

get_table_schema

Describe a table (blocked if outside scope)

execute_sql

Execute read-only SELECT (AST-validated, table references checked)

{db_type}_get_builtin_prompt

Get built-in analysis/sql_rules/react prompt

Persistence

Config is stored in gateway_data.json (JSON, atomic writes). A legacy gateway_data.pkl is auto-migrated on first load (backed up as gateway_data.pkl.bak). To reset, delete the JSON file and restart.

Observability

  • Audit: audit.log (JSONL) — one record per MCP tool call: timestamp, user, endpoint, tool, SQL hash + preview, tables, rows, duration, cache hit, error. Set DBMCP_AUDIT_PATH to relocate.

  • Metering: GET /admin/api/metering returns aggregated calls/rows/errors/latency per user, endpoint and tool (persisted to metering.json, DBMCP_METERING_PATH to relocate).

Runtime guards

Env var

Default

Meaning

DBMCP_QUERY_TIMEOUT

30

tool-call timeout, seconds

DBMCP_MAX_ROWS

10000

hard server-side cap for execute_sql max_rows

DBMCP_RATE_LIMIT_PER_MIN

120

tool calls per (user, endpoint) per minute

MCP_ALLOWED_HOSTS

(empty)

comma-separated host:port allow-list for SDK DNS-rebinding protection (public-domain deployments)

Production note (Streamable HTTP): the MCP SDK enables DNS-rebinding protection by default and only allows localhost / 127.0.0.1 / [::1] (with port). If you serve the gateway on a public domain, extend the allow-list via env (mcp 2.x no longer reads FASTMCP_TRANSPORT_SECURITY__* env vars, so the gateway maps it for you): MCP_ALLOWED_HOSTS="db.example.com:*". SSE transport is unaffected.

Tests

pip install -r requirements.lock pytest
pytest tests/ -q

Covers: read-only SQL guard + table extraction, L2 table scope, JSON persistence + pickle migration, admin auth + password masking, metering, rate limiter, engine fingerprint.

Requirements

  • Python 3.12+

  • mcp >= 2 (v2 API with MCPServer; v1's FastMCP was renamed)

  • fastapi, uvicorn, sqlalchemy, aiomysql, asyncpg, python-dotenv, pydantic, sqlglot

  • Pinned lock file: requirements.lock (pip install -r requirements.lock)

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    The Multi DB MCP Server is a high-performance implementation of the Database Model Context Protocol designed to revolutionize how AI agents interact with databases. Currently supporting MySQL and PostgreSQL databases.
    476
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables connecting to and querying multiple database types (PostgreSQL, MySQL, SQLite) through a unified interface. Supports managing multiple concurrent database connections with connection pooling and SQL query execution through MCP tools.
    5
    6 npm
    MIT
  • A
    license
    Not graded
    quality
    Not graded
    maintenance
    A universal database gateway MCP server that enables AI assistants to connect to and query multiple databases (PostgreSQL, MySQL, MariaDB, SQL Server, SQLite) with support for schema exploration, SQL execution, and secure connections via SSH tunnels.
    7 npm
    -
  • F
    license
    Not graded
    quality
    A
    maintenance
    An MCP server that exposes relational databases (PostgreSQL/MySQL) to AI agents with natural language to SQL query support.
    19
    -