Skip to main content
Glama
aminyx

mcp-devdb

by aminyx

mcp-devdb

CI

Sicherer, schreibgeschützter MCP-Server für lokale Entwicklungsdatenbanken. Coding-Agenten müssen ständig auf deine Entwicklungsdatenbank zugreifen — Schema, Beispieldaten, Abfragepläne, Tabellengrößen — aber ein naiver Datenbank-Connector gewährt ihnen vollen Schreibzugriff. mcp-devdb ist die abgesicherte Alternative: ein Model Context Protocol-Server, der Introspection-Tools hinter einer gehärteten schreibgeschützten SQL-Absicherung, Spaltenmaskierung, Ergebnislimits und einem Pro-Sitzung-Abfragebudget bereitstellt.

Backends in v1: PostgreSQL (via postgres) und SQLite (via better-sqlite3). Das Adapter-Interface ist engine-neutral, sodass MySQL später hinzugefügt werden kann.

Schnellstart

  1. Erstelle mcp-devdb.json neben dem Ort, an dem der Server läuft (siehe mcp-devdb.example.json):

{
  "databases": {
    "app": { "url": "postgres://dev:dev@localhost:5432/app_development" },
    "cache": { "url": "sqlite:./data/cache.db" }
  }
}
  1. Führe es aus:

npx mcp-devdb --config ./mcp-devdb.json

Der Server spricht MCP über stdio; richte deinen MCP-Client auf diesen Befehl aus. Verbindungsstrings leben nur in der Konfigurationsdatei oder in Umgebungsvariablen ("url": "env:MY_DB_URL" oder der MCP_DEVDB_URL-Fallback ohne Konfigurationsdatei) — das Modell kann niemals einen bereitstellen.

Claude Code

claude mcp add devdb -- npx mcp-devdb --config /absolute/path/to/mcp-devdb.json

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "devdb": {
      "command": "npx",
      "args": ["mcp-devdb", "--config", "/absolute/path/to/mcp-devdb.json"]
    }
  }
}

Related MCP server: MCP PostgreSQL

Tools

Tool

Eingabe

Rückgabe

list_tables

database?

Schemas, Tabellen, Zeilenschätzungen und Größen auf der Platte

describe_table

database?, table

Spalten, Typen, Nullability, Defaults, PK, FKs, Indizes

sample_rows

database?, table, limit? (max 50)

Erste N Zeilen; Zellen > 200 Zeichen gekürzt; sensible Spalten als *** maskiert

run_query

database?, sql

Abgesicherte schreibgeschützte Abfrage; Zeilenlimit (200) + Bytelimit (256 KiB); verbraucht Abfragebudget

explain_query

database?, sql

Ausführungsplan — PostgreSQL EXPLAIN (FORMAT JSON), SQLite EXPLAIN QUERY PLAN; verbraucht Abfragebudget

db_overview

database?

Datenbankname, Größe, Tabellenanzahl, größte Tabellen, Erweiterungen (PG)

database ist optional, wenn genau eine Datenbank konfiguriert ist; bei mehreren musst du die gewünschte angeben.

Konfiguration

mcp-devdb.json im Arbeitsverzeichnis oder ein beliebiger Pfad via --config:

{
  "databases": {
    "app": {
      "url": "postgres://dev:dev@localhost:5432/app_development",
      "allowTables": ["users", "orders", "public.events_*"],
      "denyTables": ["audit_log"]
    },
    "billing": { "url": "env:BILLING_DEV_DATABASE_URL" }
  },
  "maskPatterns": ["password", "secret", "token", "key", "hash", "ssn", "card"],
  "queryBudget": 100,
  "rowLimit": 200,
  "byteLimit": 262144,
  "statementTimeoutMs": 5000
}
  • allowTables / denyTables — case-insensitive Namen mit *-Wildcards; Regeln mit einem Punkt matchen schema.table. Deny gewinnt; eine nicht-leere Allowlist ist exklusiv.

  • maskPatterns — case-insensitive Regexes, die gegen Spaltennamen gematcht werden.

  • CLI-Flags: --config <path>, --no-mask (Spaltenmaskierung deaktivieren), --help, --version.

Sicherheitsmodell (Zusammenfassung)

Das vollständige Bedrohungsmodell findest du in SECURITY.md. Kurz zusammengefasst:

  • Schreibschutz-Guard: Jede run_query/explain_query-Anweisung wird tokenisiert (Anführungszeichen, E'...'-Escapes, Kommentare, Dollar-quotierte Strings) und muss mit SELECT / WITH / EXPLAIN / SHOW / VALUES beginnen; Multi-Statement-Eingaben und Schreib-/DDL-Schlüsselwörter an beliebiger Stelle auf oberster Ebene werden abgelehnt — ein CTE gefolgt von INSERT wird abgefangen, SELECT 'DROP TABLE x' ist kein Fehlalarm.

  • Absicherung auf Engine-Ebene: SQLite-Dateien werden schreibgeschützt geöffnet; PostgreSQL-Sitzungen laufen mit default_transaction_read_only=on, expliziten BEGIN READ ONLY-Transaktionen und Statement-Timeouts.

  • Spaltenmaskierung standardmäßig aktiviert (--no-mask zum Deaktivieren), Ergebnislimits und ein Pro-Sitzung-Abfragebudget (Standard 100; bei Erschöpfung wirst du aufgefordert, den Server neu zu starten).

  • Zugangsdaten erreichen niemals das Modell: Verbindungsstrings stammen ausschließlich aus lokaler Konfiguration/Umgebung und werden aus jeder Fehlermeldung entfernt.

Smoke-Test

scripts/verify-stdio.mjs erstellt eine temporäre SQLite-Datenbank, startet node dist/cli.js und führt einen echten MCP-Handshake über stdio mit rohem JSON-RPC durch. Tatsächliche Ausgabe:

$ node scripts/verify-stdio.mjs
initialize -> mcp-devdb 0.1.0 (protocol 2025-06-18)
tools/list -> db_overview, describe_table, explain_query, list_tables, run_query, sample_rows
tools/call list_tables ->
{
  "database": "demo",
  "dialect": "sqlite",
  "tableCount": 2,
  "tables": [
    {
      "schema": null,
      "name": "orders",
      "type": "table",
      "rowEstimate": 3,
      "sizeBytes": 4096,
      "sizePretty": "4.0 KiB"
    },
    {
      "schema": null,
      "name": "users",
      "type": "table",
      "rowEstimate": 2,
      "sizeBytes": 4096,
      "sizePretty": "4.0 KiB"
    }
  ]
}
tools/call run_query "DROP TABLE users" -> isError=true
  Query rejected by read-only guard: Only read-only statements are allowed; the statement must start with one of: SELECT, WITH, EXPLAIN, SHOW, VALUES
SMOKE TEST PASSED

Einschränkungen

  • Noch kein MySQL. Das DbAdapter-Interface in src/adapters/types.ts ist der Erweiterungspunkt.

  • Nur Entwicklungsdatenbanken. Der Guard blockiert Schreiboperationen auf SQL-Ebene, aber ein SELECT kann dennoch schlecht gekennzeichnete Funktionen oder Erweiterungsfunktionen mit Seiteneffekten aufrufen (z. B. dblink, das eine eigene nicht-schreibgeschützte Verbindung öffnet). Für Entwicklungsdatenbanken akzeptabel; niemals für Produktion verwenden. Siehe SECURITY.md.

  • Der Guard ist konservativ: Unquotierte Spalten, die wie verbotene Schlüsselwörter benannt sind (z. B. eine Spalte namens update), werden abgelehnt — quote sie ("update"), um fortzufahren.

  • SELECT ... FOR UPDATE wird abgelehnt (es setzt Zeilensperren).

  • SQLite-Zeilenanzahlen verwenden COUNT(*); bei sehr großen Dateien kann list_tables langsam sein.

Entwicklung

npm install
npm run lint && npm run typecheck && npm test && npm run build
node scripts/verify-stdio.mjs

Lizenz

MIT — Copyright (c) 2026 Aminyx

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    A lightweight Postgres MCP server for safe database exploration and query analysis, read-only by default, with multi-database support.
    4
    21 PyPI
    4
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A read-only MCP server for PostgreSQL that enables safe database introspection and querying via natural language.
    493 npm
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Read-only MCP server for SQL databases (SQLite/PostgreSQL) that enables listing tables, describing schemas, and executing SELECT queries with safety guardrails.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides a read-only PostgreSQL MCP server with schema introspection. Enforces least-privilege database roles to prevent any writes, even from malicious SQL.
    MIT