Database MCP server for MySQL, MariaDB, PostgreSQL & SQLite
Model Context Protocol (MCP) Server: ai.haymon/database
The ai.haymon/database MCP server provides database access for SQL engines including MySQL, MariaDB, PostgreSQL, and SQLite. It is distributed as a single-binary MCP server and is intended to connect an AI assistant to these databases. The project is licensed under MIT and includes CI, releases, and documentation at dbmcp.haymon.ai.
π οΈ Key Features
Single-binary MCP server
Supports MySQL and MariaDB
Supports PostgreSQL
Supports SQLite
Described as a βDatabase MCPβ for SQL databases
Lists accessible databases, paginated via cursor / nextCursor. See Cursor Pagination for iteration details. Not available for SQLite.
listTables
Lists tables in a database, paginated via cursor / nextCursor. See Cursor Pagination for iteration details.
Parameters: database (defaults to the active database; SQLite has no database parameter), cursor, search, detailed.
search is an optional case-insensitive LIKE/ILIKE pattern with % (any sequence) and _ (single character) as wildcards β pass users% to match names beginning with users, or %order% for substring matching. A bare word with no wildcards matches only an exact table name.
detailed (default false) switches the response shape:
Brief (default) β tables is a sorted JSON array of bare table-name strings.
Detailed (detailed: true) β tables is a JSON object keyed by table name; each value carries the table's schema, kind, owner, comment, columns[], constraints[], indexes[], and triggers[]. One call returns both the table list and the per-table metadata.
listViews
Lists views in a database, paginated via cursor / nextCursor. Available on MySQL/MariaDB, PostgreSQL (public schema), and SQLite. Parameters: database (defaults to the active database; SQLite has no database parameter), cursor, search, detailed. SQLite returns the brief shape only β search and detailed are not accepted there.
search is an optional case-insensitive LIKE/ILIKE pattern with % (any sequence) and _ (single character) as wildcards. The search value must remain identical across paginated calls for cursor continuity.
detailed (default false) switches the response shape:
Brief (default) β views is a sorted JSON array of bare view-name strings. View names are unique per schema, so no duplicates appear.
Detailed (detailed: true) β views is a JSON object keyed by bare view name; each value carries the per-backend metadata payload. PostgreSQL exposes schema, owner, description, definition. MySQL/MariaDB exposes schema, definer, security, checkOption, updatable, characterSetClient, collationConnection, definition. See the listViews reference for source columns, enumerated value sets, and intentional omissions per backend.
Lists user-defined triggers on tables, paginated via cursor / nextCursor. Internal constraint and foreign-key triggers are excluded. Available on MySQL/MariaDB, PostgreSQL (public schema), and SQLite. Parameters: database (defaults to the active database; SQLite has no database parameter), cursor, search, detailed.
search is an optional case-insensitive LIKE/ILIKE pattern with % (any sequence) and _ (single character) as wildcards. The search value must remain identical across paginated calls for cursor continuity.
detailed (default false) switches the response shape:
Brief (default) β triggers is a sorted JSON array of bare trigger-name strings.
Detailed (detailed: true) β triggers is a JSON object keyed by trigger name; each value carries the per-backend metadata payload (timing, events, definition, and backend-specific extras like PostgreSQL status/functionName or MySQL/MariaDB session-context fields). See the listTriggers reference for the full per-backend field list.
Lists user-defined SQL functions, paginated via cursor / nextCursor. PostgreSQL excludes aggregates, window functions, and procedures; MySQL/MariaDB excludes loadable UDFs (mysql.func). Available on MySQL/MariaDB and PostgreSQL (public schema). Not available for SQLite. Parameters: database (defaults to the active database), cursor, search, detailed.
search is an optional case-insensitive LIKE/ILIKE pattern with % (any sequence) and _ (single character) as wildcards. The search value must remain identical across paginated calls for cursor continuity.
detailed (default false) switches the response shape:
Brief (default) β functions is a sorted JSON array of bare function-name strings. PostgreSQL overloads appear once per overload (duplicate name strings are expected).
Detailed (detailed: true) β functions is a JSON object keyed by function signature; each value carries the per-backend metadata payload (language, arguments, return type, definition, and backend-specific extras such as PostgreSQL volatility/strict/parallelSafety or MySQL/MariaDB session-context fields). PostgreSQL keys are name(arguments) (overloads disambiguate); MySQL/MariaDB keys are bare names (no overloading). See the listFunctions reference for the full per-backend field list.
Lists user-defined stored procedures, paginated via cursor / nextCursor. Available on MySQL/MariaDB and PostgreSQL (public schema, PostgreSQL 11+). Not available for SQLite. Parameters: database (defaults to the active database), cursor, search, detailed.
search is an optional case-insensitive LIKE/ILIKE pattern with % (any sequence) and _ (single character) as wildcards. The search value must remain identical across paginated calls for cursor continuity.
detailed (default false) switches the response shape:
Brief (default) β procedures is a sorted JSON array of bare procedure-name strings. PostgreSQL overloads appear once per overload (duplicate name strings are expected).
Detailed (detailed: true) β procedures is a JSON object keyed by procedure signature; each value carries the per-backend metadata payload (language, arguments, security, definition, and backend-specific extras such as PostgreSQL owner or MySQL/MariaDB deterministic/sqlDataAccess/session-context fields). PostgreSQL keys are name(arguments) (overloads disambiguate; zero-arg procedures key as name()); MySQL/MariaDB keys are bare names (no overloading). See the listProcedures reference for the full per-backend field list.
Lists materialized views in the public schema, paginated via cursor / nextCursor. PostgreSQL only β not available for MySQL/MariaDB or SQLite. Parameters: database (defaults to the active database), cursor, search, detailed.
search is an optional case-insensitive ILIKE pattern with % (any sequence) and _ (single character) as wildcards. SQL meta-characters (', ;, --) are bound as parameter values and never interpolated. The search value must remain identical across paginated calls for cursor continuity.
detailed (default false) switches the response shape:
Brief (default) β materializedViews is a sorted JSON array of bare matview-name strings. Matview names are unique per schema, so no duplicates appear.
Detailed (detailed: true) β materializedViews is a JSON object keyed by bare matview name; each value carries schema, owner, description (or null when no COMMENT ON MATERIALIZED VIEW), definition (the SELECT body verbatim from pg_matviews.definition), populated (false for matviews created WITH NO DATA and never refreshed), and indexed (true when at least one index exists; REFRESH MATERIALIZED VIEW CONCURRENTLY additionally requires a unique index). Detailed mode deliberately omits column metadata, tablespace, storage parameters, and unique-index detection β recoverable via definition, listTables(detailed=true), or readQuery against pg_indexes. See the listMaterializedViews reference for source columns and operational semantics.
Executes a read-only SQL query (SELECT, SHOW, DESCRIBE, USE, EXPLAIN). Always enforces SQL validation as defence-in-depth. Parameters: query, database, cursor. SELECT results paginate via cursor / nextCursor; SHOW, DESCRIBE, USE, and EXPLAIN return a single page and ignore cursor. See Cursor Pagination for iteration details.
writeQuery
Executes a write SQL query (INSERT, UPDATE, DELETE, CREATE, ALTER, DROP). Only available when read-only mode is disabled. Parameters: query, database.
createDatabase
Creates a database if it doesn't exist. Only available when read-only mode is disabled. Not available for SQLite. Parameters: database.
dropDatabase
Drops an existing database. Refuses to drop the currently connected database. Only available when read-only mode is disabled. Not available for SQLite. Parameters: database.
dropTable
Drops a table from a database. If the table has foreign key dependents, the database error is surfaced to the user. On PostgreSQL, a cascade parameter is available to force the drop with CASCADE. Only available when read-only mode is disabled. Parameters: database, table, cascade (PostgreSQL only).
explainQuery
Returns the execution plan for a SQL query. Supports an optional analyze parameter for actual execution statistics (PostgreSQL and MySQL/MariaDB). In read-only mode, EXPLAIN ANALYZE is only allowed for read-only statements since it actually executes the query. SQLite uses EXPLAIN QUERY PLAN (no ANALYZE support). Always available regardless of read-only mode. Parameters: query, database, analyze (PostgreSQL/MySQL only).
Security π
Read-only mode (default) β write tools hidden from AI assistant; readQuery enforces AST-based SQL validation
Single-statement enforcement β multi-statement injection blocked at parse level
Dangerous function blocking β LOAD_FILE(), INTO OUTFILE, INTO DUMPFILE detected in the AST
Identifier validation β database/table names validated against control characters and empty strings
Origin + Host allowlists β server-side rejection (403) plus CORS preflight; configurable for HTTP transport
SSL/TLS β configured via individual DB_SSL_* variables
PII redaction(opt-in, off by default) β when enabled, query tool output passes through a regex-based redactor that rewrites detected PII spans across 46 built-in entity types spanning seven categories: personal (email), financial (cards, IBAN, UK bank accounts, sort and US ABA routing codes, CVV), government IDs (SSN, ITIN, EIN, UK/US passports, NHS, NINO, SIN, VAT), contact (phone), network (IP, URL, MAC), digital identity (API keys, JWTs, PEM private keys, password hashes), and crypto wallets. Toggle: --pii / PII_ENABLE. Operator: --pii-operator / PII_OPERATOR β one of replace (default, entity-aware placeholders like <EMAIL_ADDRESS>), mask (length-preserving *), redact (drop), hash (SHA-256 hex). Optional subset via --pii-categories / PII_CATEGORIES (comma-separated, e.g. financial,government); unset enables all built-ins. Scope: query tool output payloads only. See PII configuration for the full surface.
ML/NER redaction(opt-in at runtime, off by default) β adds PERSON, LOCATION, ORGANIZATION, NATIONALITY_RELIGION_POLITICS, and FACILITY detection that regex cannot catch, enabled via the --pii-ner / PII_NER_ENABLE toggle plus a user-supplied model directory. Which entities are produced depends on the model's labels (CoNLL models give person/location/organization; OntoNotes-class models add NRP and facility). Inference uses ONNX Runtime (model directory holds config.json, tokenizer.json, model.onnx; recommended: the MIT-licensed dslim/bert-base-NER exported to ONNX, int8-quantized for speed). Fail-closed: a model that cannot load aborts startup and an inference error fails the request β never a silent fallback. Respects --pii-categories. English for v1.
Credential redaction β database password is never shown in logs or debug output
Testing π§ͺ
bash
# Unit tests
cargo test --workspace --lib --bins
# Integration tests (requires Docker)
./tests/run.sh
# Filter by engine
./tests/run.sh --filter mariadb
./tests/run.sh --filter mysql
./tests/run.sh --filter postgres
./tests/run.sh --filter sqlite
# With MCP Inspector
npx @modelcontextprotocol/inspector ./target/release/dbmcp stdio
# HTTP mode testing
curl -X POST http://localhost:9001/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"0.1"}}}'
Project Structure ποΈ
This is a Cargo workspace with the following crates:
Crate
Path
Description
dbmcp
. (root)
Main binary β CLI, transports, database backends
dbmcp-sql
crates/backend/
Shared error types, validation, and identifier utilities
dbmcp-config
crates/config/
Configuration structs and CLI argument mapping
dbmcp-server
crates/server/
Shared MCP tool implementations and server info
dbmcp-mysql
crates/mysql/
MySQL/MariaDB backend handler and operations
dbmcp-postgres
crates/postgres/
PostgreSQL backend handler and operations
dbmcp-sqlite
crates/sqlite/
SQLite backend handler and operations
sqlx-json
crates/sqlx-json/
Type-safe row-to-JSON conversion for sqlx (RowExt trait)