Skip to main content
Glama
AndiAtom

MariaDB MCP Server

by AndiAtom

MariaDB MCP Server mit streamable HTTP für Open-WebUI

Ein read-only MCP Server, der als Schnittstelle zwischen einer MariaDB Datenbank und Open-WebUI dient. Der Server erlaubt ausschließlich lesende Abfragen und blockiert alle Schreiboperationen wie INSERT, UPDATE, DELETE, CREATE, ALTER, DROP usw.

Hinweis: Der Server verwendet mysql-connector-python, der vollständig mit MariaDB kompatibel ist und keine externen Systembibliotheken benötigt. Der Server ist MCP-kompatibel und implementiert die notwendigen Endpunkte für Open-WebUI. Aktuellste Version verwendet Python 3.12 als Base Image.


:rocket: Schnellstart

Mit Docker (empfohlen)

# Klone das Repository
git clone https://github.com/AndiAtom/mariadb-mcp-strhttp.git
cd mariadb-mcp-strhttp

# Starte mit Docker Compose (enthält MariaDB + MCP Server)
docker-compose up -d

# Der Server ist jetzt unter http://localhost:8000 verfügbar

Ohne Docker

# Installiere Abhängigkeiten
pip install -r requirements.txt

# Starte den Server
python -m src.server

# Oder direkt
python src/server.py

Related MCP server: tusk-mcp

:gear: Konfiguration

Umgebungsvariablen

Der Server wird über Umgebungsvariablen konfiguriert. Die mitgelieferte config.json dient als Referenz für die möglichen Werte und wird nicht automatisch vom Server eingelesen.

Datenbank-Konfiguration

Variable

Beschreibung

Standardwert

Beispiel

DB_HOST

MariaDB Hostname

localhost

192.168.1.100

DB_PORT

MariaDB Port

3306

3306

DB_USER

MariaDB Benutzername

mcpuser

mcp_user

ALLOW_DB_ROOT

DB_USER=root beim Start erlauben (nur lokale Entwicklung)

false

true

DB_PASSWORD

MariaDB Passwort

""

securepassword

DB_DATABASE

Standard-Datenbank

None

mydatabase

DB_TIMEOUT

Timeout für Datenbankabfragen (Sekunden)

30

60

Server-Konfiguration

Variable

Beschreibung

Standardwert

Beispiel

SERVER_HOST

Server Host

0.0.0.0

0.0.0.0

SERVER_PORT

Server Port

8000

8000

LOG_LEVEL

Log-Level

info

debug

API-Token-Authentifizierung

Variable

Beschreibung

Standardwert

Beispiel

API_TOKEN

Einzelner API-Token

None

my-secret-token

API_TOKENS

Mehrere API-Tokens (komma-separiert)

None

token1,token2

API_TOKEN_FILE

Pfad zur Token-Datei

None

/app/tokens.json

DISABLE_API_AUTH

Authentifizierung deaktivieren

false

true

API_HEADER_NAME

Name des Authorization Headers

Authorization

X-API-Key

API_QUERY_PARAM

Name des Query-Parameters

api_key

token

Hinweis: Der Token wird nicht mehr aus dem Request-Body extrahiert. Dies verhindert einen Doppelkonsum des Bodies durch die Auth-Middleware. Verwende stattdessen den Authorization-Header oder den api_key-Query-Parameter.

CORS

Variable

Beschreibung

Standardwert

Beispiel

CORS_ALLOWED_ORIGINS

Erlaubte CORS-Origins (komma-separiert)

"" (keine)

https://openwebui.example.com

Sicherheit: allow_origins=["*"] mit allow_credentials=True ist eine bekannte Fehlkonfiguration. Ohne Konfiguration von CORS_ALLOWED_ORIGINS sind keine Cross-Origin-Requests mit Credentials möglich.

Datenbank-Zugriffskontrolle

Variable

Beschreibung

Standardwert

Beispiel

ALLOWED_DATABASES

Positiv-Liste erlaubter Datenbanken (komma-separiert)

"" (nicht gesetzt)

testdb,analytics

Sicherheit: System-Schemata (mysql, information_schema, performance_schema, sys) sind immer gesperrt. Ohne ALLOWED_DATABASES sind alle nicht-System-Schemata erlaubt; mit gesetzter Variable nur die gelisteten.

API-Dokumentation

Variable

Beschreibung

Standardwert

Beispiel

PUBLIC_DOCS

/docs und /redoc ohne Auth freischalten

false

true

Sicherheit: Die API-Dokumentation ist standardmäßig auth-pflichtig, um kein Informationsleck zu erzeugen. Nur in vertrauenswürdigen internen Umgebungen auf true setzen.

Request-Limitierung & Security-Header

Variable

Beschreibung

Standardwert

Beispiel

MAX_REQUEST_BODY_BYTES

Maximale Request-Body-Größe in Bytes (DoS-Schutz)

1048576 (1 MiB)

2097152

Sicherheit: Der Server setzt zusätzlich Standard-Security-Header auf jede Antwort: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Referrer-Policy: no-referrer, Cache-Control: no-store. Strict-Transport-Security (HSTS) wird nur bei HTTPS-Requests gesetzt. Ein DB_USER=root wird beim Start abgewiesen (außer ALLOW_DB_ROOT=true); Auth aktiviert ohne konfigurierte Tokens führt zu einem Startabbruch (Fail-Closed).

Rate Limiting

Variable

Beschreibung

Standardwert

Beispiel

RATE_LIMITING_ENABLED

Rate Limiting aktivieren

true

false

RATE_LIMIT_REQUESTS_PER_MINUTE

Anfragen pro Minute

100

200

RATE_LIMIT_BURST_REQUESTS

Burst-Anfragen

10

20

RATE_LIMIT_WHITELIST

Whitelisted Pfade

/health,/, etc.

/health,/info

Referenzkonfiguration (config.json)

Die folgende config.json zeigt die Struktur der Konfigurationswerte. Sie wird nicht vom Server automatisch geladen; alle Werte werden stattdessen über die oben genannten Umgebungsvariablen gesetzt.

{
  "server": {
    "host": "0.0.0.0",
    "port": 8000,
    "log_level": "info"
  },
  "database": {
    "host": "localhost",
    "port": 3306,
    "user": "mcpuser",
    "password": "securepassword",
    "database": "mydatabase",
    "timeout": 30
  },
  "security": {
    "read_only": true,
    "block_write_operations": true,
    "validate_queries": true
  },
  "authentication": {
    "enabled": true,
    "type": "api_token",
    "tokens": ["token1", "token2"],
    "token_file": null,
    "header_name": "Authorization",
    "query_param_name": "api_key"
  },
  "rate_limiting": {
    "enabled": true,
    "requests_per_minute": 100,
    "burst_requests": 10,
    "whitelist": ["/health", "/", "/docs", "/openapi.json", "/redoc"]
  }
}

Hinweis: Maßgeblich sind die Umgebungsvariablen aus den Tabellen oben. Diese config.json ist lediglich eine Referenz.


:key: API-Token-Authentifizierung

Der Server unterstützt optionale API-Token-Authentifizierung, um den Zugriff auf die API zu schützen.

Token-Generierung

Das Projekt enthält ein Skript generate_token.py zur Generierung sicherer API-Tokens:

# Einzelnen Token generieren
python generate_token.py

# Mehrere Tokens generieren
python generate_token.py --num 5

# Token mit bestimmter Länge generieren (Standard: 32 Zeichen)
python generate_token.py --length 64

# Token in Datei speichern
python generate_token.py --file tokens.json

# Tokens nur anzeigen (nicht speichern)
python generate_token.py --no-file

Authentifizierung aktivieren

Es gibt mehrere Möglichkeiten, die Authentifizierung zu konfigurieren:

1. Einzelner Token über Umgebungsvariable

# In docker-compose.yml oder beim Starten
API_TOKEN=your-secure-token-here

2. Mehrere Tokens über Umgebungsvariable (komma-separiert)

API_TOKENS=token1,token2,token3

3. Token aus Datei laden

Erstelle eine JSON-Datei tokens.json:

{
  "tokens": [
    "your-secure-token-1",
    "your-secure-token-2"
  ]
}

Oder eine einfache Textdatei (ein Token pro Zeile):

token1
token2
token3

Dann in docker-compose.yml:

environment:
  - API_TOKEN_FILE=/app/tokens.json
volumes:
  - ./tokens.json:/app/tokens.json:ro

Hot-Reload: Eine über API_TOKEN_FILE eingebundene Token-Datei wird bei Änderung (mtime) automatisch beim nächsten Request neu geladen. Token-Rotation ist damit ohne Server-Restart möglich. Die Prüfung erfolgt über stat und ist sehr billig; nur bei tatsächlicher Änderung wird die Datei gelesen.

Fail-Closed-Startup: Ist die Authentifizierung aktiviert (Standard), aber es sind keine Tokens konfiguriert (API_TOKEN/API_TOKENS/API_TOKEN_FILE), bricht der Server den Start mit einem Fehler ab. Das verhindert sowohl einen versehentlich offenen als auch einen "abgeriegelten" (Silent-Death) Server. Für lokale Entwicklung DISABLE_API_AUTH=true setzen.

Konstanter Token-Vergleich: Tokens werden über secrets.compare_digest validiert (konstante Zeit), um Timing-Seitenkanäle bei der Token-Enumeration zu vermeiden.

4. Authentifizierung deaktivieren (nur für lokale Entwicklung)

DISABLE_API_AUTH=true

Token verwenden

Es gibt drei Möglichkeiten, den Token zu übergeben:

1. Authorization Header (empfohlen)

curl -X POST http://localhost:8000/query \
  -H "Authorization: Bearer your-secure-token" \
  -H "Content-Type: application/json" \
  -d '{"query": "SELECT * FROM customers LIMIT 10"}'

2. Query Parameter

curl -X POST http://localhost:8000/query?api_key=your-secure-token \
  -H "Content-Type: application/json" \
  -d '{"query": "SELECT * FROM customers LIMIT 10"}'

Hinweis: Die Token-Übertragung im Request-Body wird aus Sicherheitsgründen nicht mehr unterstützt (Doppelkonsum des Bodies). Verwende Header oder Query-Parameter.

Öffentliche Endpunkte

Die folgenden Endpunkte benötigen keine Authentifizierung:

  • GET / - Server-Informationen

  • GET /health - Health-Check

  • GET /openapi.json - OpenAPI-Spezifikation (für Clients wie Open-WebUI)

Hinweis: /docs und /redoc sind standardmäßig auth-pflichtig und können über PUBLIC_DOCS=true freigeschaltet werden.

Alle anderen Endpunkte erfordern einen gültigen API-Token, wenn die Authentifizierung aktiviert ist.


:desktop_computer: Open-WebUI Integration

MCP Server in Open-WebUI hinzufügen

  1. Öffne Open-WebUI (z.B. http://localhost:8080)

  2. Gehe zu Einstellungen --> MCP Server oder Externe Tool-Server

  3. Klicke auf "Add MCP Server" oder "Neuer Server"

  4. Füge folgende Konfiguration ein:

{
  "name": "MariaDB Read-Only",
  "type": "http",
  "url": "http://localhost:8000",
  "readOnly": true,
  "headers": {
    "Authorization": "Bearer your-api-token-here"
  },
  "capabilities": {
    "query": true,
    "stream": true,
    "validate": true,
    "list_resources": false,
    "read_resource": false
  },
  "timeout": 60
}

:bulb: Hinweis: Open-WebUI erkennt automatisch den MCP-kompatiblen Endpunkt. Die URL kann einfach http://localhost:8000 sein, der Server hat sowohl den Standard- als auch den /mcp-Endpunkt.

Verbindung testen

Frage Open-WebUI:

"Was sind die Tabellen in der Datenbank?"

Erwartete Antwort: Eine Liste aller Tabellen aus deiner MariaDB.


:shield: Sicherheitsfeatures

Read-Only Implementierung

Der Server implementiert mehrere Ebenen von Read-Only-Schutz:

  1. DB-User-Ebene (primär): Verwende einen dedizierten DB-User ohne Schreibrechte (GRANT SELECT ON ...). Dies ist die wichtigste Schutzmaßnahme.

  2. Session-Ebene: SET SESSION read_only=ON wird auf jeder Verbindung des Pools gesetzt (Defense-in-Depth)

  3. Abfrage-Ebene: Jede Abfrage wird vor der Ausführung auf Schreiboperationen geprüft (is_read_only_query)

  4. Identifier-Validierung: Tabellen- und Datenbanknamen werden per Regex (^[A-Za-z0-9_]+$) validiert, bevor sie in SQL eingefügt werden (SQL-Injection-Schutz)

  5. Kommentar-Stripping: Vor der Prüfung werden SQL-Kommentare entfernt. Dabei kommt ein stack-basiertes Verfahren zum Einsatz, das auch verschachtelte/gestaffelte Blockkommentare (/* a /* b */ INSERT ... */) korrekt nach MariaDB-Semantik entfernt. Ein nicht-greedy Regex würde hier das INSERT übersehen.

Hinweis: Die frühere einzelne, global geteilte Verbindung wurde durch einen Connection-Pool ersetzt, der pro Request eine isolierte Verbindung öffnet. Das verhindert Race Conditions durch USE-Wechsel auf geteilten Verbindungen.

Query Timeout Schutz

  • Standard-Timeout: Alle Datenbankabfragen haben einen Standard-Timeout von 30 Sekunden

  • Individueller Timeout: Kann pro Abfrage über den timeout-Parameter angepasst werden

  • Streaming-Limit: Streaming-Abfragen sind auf 10.000 Zeilen begrenzt, um sehr große Resultsets zu verhindern

  • Konfigurierbar: Timeout kann über die Umgebungsvariable DB_TIMEOUT oder in der Konfigurationsdatei angepasst werden

Audit-Logging

Der Server schreibt strukturierte Audit-Ereignisse in den separaten Logger audit (unabhängig vom Anwendungs- und Access-Log, z. B. in eine Datei oder ein SIEM weiterleitbar). Jedes Ereignis ist eine JSON-Zeile mit:

  • event: Art (query.executed, query.denied, query.error)

  • client_ip: direkter Peer (nicht X-Forwarded-For, vertraut nur direkter Verbindung)

  • token_index: Index des Tokens in der konfigurierten Menge (kein Token-Wert!)

  • database, query_preview (max. 80 Zeichen), valid, row_count, status_code, error

Sicherheit: Es werden keine vollständigen Queries und keine Token-Werte protokolliert. Der token_index ermöglicht eine eindeutige Client-Zuordnung ohne Token-Leak. Audit-Ereignisse werden im /query-Endpunkt bei Erlaubnis, Ablehnung und Fehler geschrieben.

Blockierte Befehle

Der Server blockiert alle Schreiboperationen, einschließlich:

DDL (Data Definition Language)

  • CREATE - Tabellen, Datenbanken, Indizes erstellen

  • ALTER - Objekte ändern

  • DROP - Objekte löschen

  • TRUNCATE - Tabellen leeren

  • RENAME - Objekte umbenennen

DML (Data Manipulation Language)

  • INSERT - Daten einfügen

  • UPDATE - Daten aktualisieren

  • DELETE - Daten löschen

  • REPLACE - Daten ersetzen

  • LOAD - Daten laden

  • MERGE - Daten zusammenführen

DCL (Data Control Language)

  • GRANT - Berechtigungen erteilen

  • REVOKE - Berechtigungen entziehen

  • DENY - Berechtigungen verweigern

Transaktionssteuerung

  • COMMIT - Transaktionen bestätigen

  • ROLLBACK - Transaktionen zurücksetzen

  • SAVEPOINT - Speicherpunkte erstellen

  • RELEASE - Speicherpunkte freigeben

Administrative Befehle

  • SHUTDOWN - Server herunterfahren

  • KILL - Verbindungen beenden

  • PURGE - Logs bereinigen

  • RESET - Zurücksetzen

  • FLUSH - Caches leeren

  • SET PASSWORD - Passwort ändern

  • SET GLOBAL - Globale Variablen setzen

  • SET SESSION - Sitzungsvariablen setzen (außer read_only)

Replikation

  • CHANGE MASTER - Master ändern

  • START SLAVE - Slave starten

  • STOP SLAVE - Slave stoppen

MariaDB/MySQL-spezifische Befehle

  • OPTIMIZE TABLE - Tabellen defragmentieren (Schreiboperation)

  • REPAIR TABLE - Tabellen reparieren (Schreiboperation)

  • ANALYZE TABLE - Statistiken aktualisieren (Schreiboperation)

  • CHECK TABLE - Tabellen prüfen (kann Reparaturen auslösen)

  • CHECKSUM TABLE - Prüfsummen berechnen

Erlaubte Befehle

Nur folgende Befehle sind erlaubt:

Datenabfragen

  • SELECT - Daten abfragen

  • WITH / CTE - Common Table Expressions

Metadaten-Abfragen

  • SHOW - Informationen anzeigen (TABLES, DATABASES, COLUMNS, INDEX, etc.)

  • DESCRIBE / DESC - Tabellenstruktur anzeigen

  • EXPLAIN - Ausführungsplan anzeigen

Informationsschema

  • INFORMATION_SCHEMA - Metadaten abfragen

Transaktionssteuerung (nur lesend)

  • START TRANSACTION READ ONLY - Read-Only Transaktion starten

  • BEGIN READ ONLY - Read-Only Transaktion beginnen

  • SET TRANSACTION READ ONLY - Transaktion als read-only setzen

Sonstige

  • HELP - Hilfe anzeigen

Hinweis: USE ist nicht mehr als direkte Abfrage erlaubt. Ein Datenbankwechsel erfolgt über den database-Parameter der Endpunkte (z. B. {"query": "...", "database": "mydb"}). System-Schemata wie mysql oder information_schema sind gesperrt.


:satellite: API Endpunkte

MCP Endpunkte (für Open-WebUI)

Methode

Endpunkt

Beschreibung

GET

/mcp

MCP Server Information (Tools, Capabilities)

POST

/mcp

MCP Anfragen verarbeiten

Standard API Endpunkte (für direkte Nutzung)

Methode

Endpunkt

Beschreibung

Parameter

GET

/

Server-Informationen

-

GET

/health

Health-Check

-

POST

/query

SQL-Abfrage ausführen

query, database (optional), timeout (optional)

GET

/query/validate

SQL-Abfrage validieren

query

POST

/query/validate

SQL-Abfrage validieren

query

GET

/query/stream

SQL-Abfrage mit Streaming

query, timeout (optional)

GET

/tables

Alle Tabellen auflisten

database (optional)

GET

/databases

Alle Datenbanken auflisten

-

GET

/schema/{table}

Schema einer Tabelle abrufen

table

GET

/columns/{table}

Spalten einer Tabelle abrufen

table

GET

/query/examples

Beispiele für erlaubte Abfragen

-

GET

/openapi.json

OpenAPI-Spezifikation (öffentlich)

-

GET

/docs

Swagger UI Dokumentation (auth-pflichtig¹)

-

GET

/redoc

ReDoc Dokumentation (auth-pflichtig¹)

-

¹ Auth-pflichtig, außer PUBLIC_DOCS=true ist gesetzt.


:computer: API Beispiele

Einfache Abfrage mit Authentifizierung

# Mit Authorization Header
curl -X POST http://localhost:8000/query \
  -H "Authorization: Bearer your-api-token" \
  -H "Content-Type: application/json" \
  -d '{"query": "SELECT * FROM customers LIMIT 10"}'

# Mit Query Parameter
curl -X POST http://localhost:8000/query?api_key=your-api-token \
  -H "Content-Type: application/json" \
  -d '{"query": "SELECT * FROM customers LIMIT 10"}'

# Mit Datenbank-Angabe
curl -X POST http://localhost:8000/query \
  -H "Authorization: Bearer your-api-token" \
  -H "Content-Type: application/json" \
  -d '{"query": "SELECT * FROM mails LIMIT 5", "database": "tanss"}'

MCP Endpunkt testen

# MCP Server Info abrufen (keine Authentifizierung nötig)
curl http://localhost:8000/mcp

# MCP Anfrage ausführen (mit Authentifizierung)
curl -X POST http://localhost:8000/mcp \
  -H "Authorization: Bearer your-api-token" \
  -H "Content-Type: application/json" \
  -d '{"method": "execute_query", "params": {"query": "SELECT * FROM customers LIMIT 5"}}'

Streaming Abfrage

curl -H "Authorization: Bearer your-api-token" \
  http://localhost:8000/query/stream?query=SELECT%20*%20FROM%20large_table

Antwort (Server-Sent Events):

data: {"type": "metadata", "columns": ["id", "name"], "query": "SELECT * FROM large_table"}

data: {"type": "row", "data": {"id": 1, "name": "Row 1"}}

data: {"type": "row", "data": {"id": 2, "name": "Row 2"}}

data: {"type": "complete", "total_rows": 1000}

Abfrage validieren

curl -X POST http://localhost:8000/query/validate \
  -H "Authorization: Bearer your-api-token" \
  -H "Content-Type: application/json" \
  -d '{"query": "INSERT INTO users VALUES (1, \"test\")"}'

Antwort:

{
  "valid": false,
  "error": "Abfrage enthält Schreiboperationen. Nur lesende Abfragen sind erlaubt.",
  "blocked_keywords": ["INSERT"]
}

Tabellen auflisten

# Alle Tabellen in der aktuellen Datenbank
curl -H "Authorization: Bearer your-api-token" \
  http://localhost:8000/tables

# Tabellen in einer bestimmten Datenbank
curl -H "Authorization: Bearer your-api-token" \
  http://localhost:8000/tables?database=tanss

Schema einer Tabelle abrufen

curl -H "Authorization: Bearer your-api-token" \
  http://localhost:8000/schema/customers

:hourglass: Rate Limiting

Der Server implementiert Rate Limiting, um die API vor übermäßiger Nutzung zu schützen.

Standard-Konfiguration

  • Aktiviert: Ja (standardmäßig)

  • Anfragen pro Minute: 100

  • Burst-Anfragen: 10

  • Whitelist: /, /health, /docs, /openapi.json, /redoc

Rate Limit Header

Jede Antwort enthält folgende Header:

  • X-RateLimit-Limit: Maximale Anfragen pro Minute

  • X-RateLimit-Remaining: Verbleibende Anfragen

  • X-RateLimit-Reset: Zeitstempel, wann das Limit zurückgesetzt wird

Fehlerbehandlung

Bei Überschreitung des Rate Limits:

  • HTTP Status: 429 Too Many Requests

  • Header: Retry-After: 60 (Sekunden bis zum nächsten Versuch)

  • Body:

    {
      "error": "Too Many Requests",
      "detail": "Rate Limit überschritten. Maximale Anfragen: 100 pro Minute",
      "retry_after": 60
    }

:test_tube: Testen

Automatisierte Tests

# Installiere Test-Abhängigkeiten
pip install pytest httpx

# Führe Tests aus
pytest tests/

Manuelles Testen

  1. Verbindung testen:

    curl http://localhost:8000/health
  2. MCP Endpunkt testen:

    curl http://localhost:8000/mcp
  3. Erlaubte Abfrage testen:

    curl -X POST http://localhost:8000/query \
      -H "Authorization: Bearer your-token" \
      -d '{"query": "SELECT 1"}'
  4. Blockierte Abfrage testen:

    curl -X POST http://localhost:8000/query \
      -H "Authorization: Bearer your-token" \
      -d '{"query": "INSERT INTO test VALUES (1)"}'

    --> Sollte Fehler 403 zurückgeben

  5. Authentifizierung testen:

    # Ohne Token (sollte 401 zurückgeben, wenn Auth aktiviert)
    curl -X POST http://localhost:8000/query \
      -d '{"query": "SELECT 1"}'
    
    # Mit falschem Token (sollte 401 zurückgeben)
    curl -X POST http://localhost:8000/query \
      -H "Authorization: Bearer wrong-token" \
      -d '{"query": "SELECT 1"}'
    
    # Mit richtigem Token (sollte funktionieren)
    curl -X POST http://localhost:8000/query \
      -H "Authorization: Bearer your-correct-token" \
      -d '{"query": "SELECT 1"}'

:wrench: Fehlerbehebung

Häufige Probleme und Lösungen

1. Open-WebUI erkennt den MCP Server nicht

  • Ursache: Falsche URL oder Server nicht erreichbar

  • Lösung:

    • URL in Open-WebUI auf http://localhost:8000 setzen

    • Server-Status prüfen: curl http://localhost:8000/health

    • MCP-Endpunkt testen: curl http://localhost:8000/mcp

2. "Leere Abfrage" Fehler

  • Ursache: Open-WebUI sendet die Abfrage in einem anderen Format

  • Lösung: Der Server unterstützt jetzt:

    • JSON Body: {"query": "SELECT ..."}

    • Formular-Daten: query=SELECT ...

    • Alternative Feldnamen: query, sql, q

    • Datenbank-Angabe: {"query": "...", "database": "tanss"}

3. Verbindung zur Datenbank scheitert

  • Ursache: Falsche Credentials oder MariaDB nicht für Remote-Zugriff konfiguriert

  • Lösung:

    • Prüfe DB_HOST, DB_USER, DB_PASSWORD in docker-compose.yml

    • MariaDB für Remote-Zugriff konfigurieren:

      # In /etc/mysql/mariadb.conf.d/50-server.cnf
      bind-address = 0.0.0.0
    • Benutzer berechtigen:

      GRANT SELECT ON *.* TO 'mcp_user'@'%';
      FLUSH PRIVILEGES;
    • network_mode: host in docker-compose.yml verwenden

4. Server nicht erreichbar

  • Ursache: Port Konflikt oder Firewall

  • Lösung:

    • Prüfe mit curl http://localhost:8000/health

    • Port 8000 freigeben: sudo ufw allow 8000

    • Andere Dienste auf Port 8000 beenden: sudo lsof -i :8000

5. Docker-Container startet nicht

  • Ursache: Berechtigungsprobleme oder fehlende Abhängigkeiten

  • Lösung:

    docker-compose down
    docker-compose up -d --build
    docker-compose logs mariadb-mcp-server

6. Abfragen werden blockiert

  • Ursache: Abfrage enthält Schreiboperationen

  • Lösung:

    • Validierung prüfen: curl -X POST http://localhost:8000/query/validate -d '{"query": "DEINE_ABFRAGE"}'

    • Nur lesende Abfragen verwenden (SELECT, SHOW, DESCRIBE, etc.)

7. 401 Unauthorized Fehler

  • Ursache: API-Token-Authentifizierung aktiviert, aber kein oder falscher Token angegeben

  • Lösung:

    • Token in Authorization Header angeben: -H "Authorization: Bearer your-token"

    • Token als Query Parameter angeben: ?api_key=your-token

    • Authentifizierung deaktivieren: DISABLE_API_AUTH=true

Hinweis: Die Token-Übertragung im Request-Body wird nicht mehr unterstützt (kein Doppelkonsum des Bodies). Verwende Header oder Query-Parameter.


:package: Abhängigkeiten

Der Server verwendet folgende Python-Pakete:

Paket

Version

Zweck

fastapi

>=0.104.0

Web-Framework für die API

uvicorn

>=0.24.0

ASGI-Server

mysql-connector-python

>=8.0.0

MariaDB/MySQL Connector

sse-starlette

>=1.6.0

Server-Sent Events Unterstützung

pydantic

>=2.5.0

Datenvalidierung

python-multipart

>=0.0.6

Formular-Daten Unterstützung

:bulb: Hinweis: Wir verwenden mysql-connector-python statt mariadb, da dieser Connector keine externen Systembibliotheken benötigt und damit Docker-freundlicher ist. Er ist vollständig kompatibel mit MariaDB.


:bookmark: Versionshistorie

Version

Datum

Änderungen

v1.0.0

2026-07-30

Erste stabile Version

Read-only SQL-Validierung

Streaming-Unterstützung

Docker-Unterstützung

Wechsel zu mysql-connector-python

MCP-kompatibler Endpunkt

v1.0.1

2026-08-03

Bugfixes

Behebe "Leere Abfrage" Fehler

Behebe TRANSACTION READ ONLY Fehler

Unterstützung für alternative Anfrage-Formate

Verbesserte Docker-Netzwerk-Konfiguration

v1.1.0

2026-08-05

API-Token-Authentifizierung

Unterstützung für einzelne und mehrere Tokens

Token aus Datei laden

Flexible Token-Übertragung (Header, Query)

Benutzerdefinierte Header/Parameter Namen

Öffentliche Endpunkte ohne Authentifizierung

v1.2.0

2026-08-13

Erweiterte Sicherheit

Thread-sicheres Rate Limiting

Korrigierte asyncio-Probleme

Verbesserte Fehlerbehandlung

Aktualisierte Dokumentation

v1.3.0

2026-08-14

Sicherheits-Härtung

SQL-Injection-Schutz: Identifier-Validierung, parametrisierte Queries

USE blockiert, Datenbank-Allow-Liste (ALLOWED_DATABASES)

Connection-Pool statt globaler Verbindung (Race Condition)

Auth-Middleware liest Request-Body nicht mehr (kein Doppelkonsum)

CORS restriktiviert (CORS_ALLOWED_ORIGINS)

/docs, /redoc auth-pflichtig (PUBLIC_DOCS); /openapi.json öffentlich

Fehlermeldungen leaken keine DB-Interna

Testsuite repariert (119 Tests)

v1.3.1

2026-08-14

Weitere Sicherheits-Mechanismen

Konstanter Token-Vergleich (Timing-Seitenkanal)

Stack-basiertes Kommentar-Stripping (verschachtelte/gestaffelte Kommentare)

Request-Body-Größenbegrenzung (MAX_REQUEST_BODY_BYTES)

Security-Headers (nosniff, DENY, no-store, HSTS bei HTTPS)

Fail-Closed-Startup: Auth ohne Tokens bricht den Start ab

Token-Datei-Hot-Reload (Rotation ohne Restart)

DB_USER=root-Startup-Guard (ALLOW_DB_ROOT)

Strukturiertes Audit-Logging (Token-Index statt Token-Wert)

.dockerignore + Container-Härtung (cap_drop, read_only, no-new-privileges)

config.json-Passwort-Feld als Platzhalter


:busts_in_silhouette: Mitwirken

  1. Fork das Repository

  2. Erstelle einen Feature-Branch (git checkout -b feature/AmazingFeature)

  3. Commit deine Änderungen (git commit -m 'Add some AmazingFeature')

  4. Push zum Branch (git push origin feature/AmazingFeature)

  5. Öffne einen Pull Request


:memo: Lizenz

Dieses Projekt ist unter der MIT-Lizenz lizenziert - siehe LICENSE für Details.


:email: Kontakt


Hinweis: Dieser Server ist ausschließlich für lesende Abfragen konzipiert. Alle Versuche, Schreiboperationen auszuführen, werden blockiert und führen zu einem Fehler.

Technischer Hinweis: Der Server verwendet mysql-connector-python, der vollständig mit MariaDB kompatibel ist und keine externen C-Bibliotheken benötigt, was die Docker-Installation deutlich vereinfacht. Der Server implementiert einen MCP-kompatiblen Endpunkt (/mcp) für nahtlose Integration mit Open-WebUI und unterstützt sowohl JSON- als auch Formular-Daten-Anfragen. Die Read-Only-Funktionalität wird auf Session-Ebene (SET SESSION read_only=ON) und auf Abfrage-Ebene (Validierung) sichergestellt. Die API-Token-Authentifizierung bietet eine zusätzliche Sicherheitsebene für den Zugriff auf die API.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    A read-only PostgreSQL MCP server that enables AI agents to perform schema introspection and execute SELECT-only queries. It supports secure database connections through SSL and SSH tunnels while offering a structure-only mode to restrict query access.
    26
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A lightweight MCP server providing safe, read-only access to MySQL databases. It enables users to query multiple MySQL instances securely while preventing write operations.
    1,090
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Read-only MySQL/MariaDB MCP server for running SELECT queries safely, with automatic read-only enforcement and query limits.
    3
    14
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AndiAtom/mariadb-mcp-strhttp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server