MCP-DB Konfiguration

Konfiguration mit Hot-Reload aus JSON-Datei - Änderungen werden sofort wirksam ohne Neustart.

Übersicht

BereichDateiHot-ReloadBeschreibung
JSON-Config/etc/mcp-db/config.jsonJaAllowlists, Limits, Keywords
Environment/var/www/mcp-servers/mcp_db/.envNeinDB-Credentials
Claude Hooks/root/.claude/settings.jsonNeinBlocking-Hook

Neu: Änderungen an /etc/mcp-db/config.json werden bei jedem Tool-Aufruf automatisch geladen - kein Claude-Neustart nötig!

JSON-Konfiguration (Hot-Reload)

Pfad: /etc/mcp-db/config.json

{
  "_comment": "MCP-DB Konfiguration - Änderungen werden sofort wirksam",

  "allowed_databases": [
    "ki_dev",
    "ki_content"
  ],

  "allowed_tables": {
    "ki_dev": [
      "mcp_log", "protokoll", "file_backup_history",
      "tasks", "task_assignments", "task_results", "task_comments",
      "contracts", "contract_history", "contract_validations",
      "dokumentation", "dokumentation_chunks", "dokumentation_history",
      "pipeline_log", "pipeline_queue", "llm_requests", "rag_collections",
      "ai_models", "audit_log", "code_analysis", "code_dependencies",
      "code_quality", "code_scan_config", "prompts"
    ],
    "ki_content": [
      "content_orders", "content_versions", "content_critiques",
      "content_sources", "content_config", "content_config_history",
      "documents", "chunks", "chunk_semantics", "chunk_entities",
      "chunk_taxonomy", "document_taxonomy", "document_entities",
      "document_pages", "entity_semantics", "entity_taxonomy_mapping",
      "entity_types", "generated_questions",
      "pipeline_configs", "pipeline_queue", "pipeline_runs", "pipeline_steps",
      "provenance", "semantic_queue", "stopwords",
      "chat_sessions", "chat_messages",
      "entities", "entity_relations", "entity_classifications",
      "taxonomy_terms", "ontology_classes", "search_history"
    ]
  },

  "blocked_keywords": [
    "DROP", "DELETE", "INSERT", "UPDATE", "TRUNCATE",
    "ALTER", "CREATE", "RENAME", "GRANT", "REVOKE",
    "LOAD_FILE", "INTO OUTFILE", "INTO DUMPFILE",
    "BENCHMARK", "SLEEP"
  ],

  "limits": {
    "max_query_length": 2000,
    "max_rows": 100,
    "query_timeout_sec": 30
  }
}

Datenbank hinzufügen

# /etc/mcp-db/config.json bearbeiten
{
  "allowed_databases": [
    "ki_dev",
    "ki_content",
    "neue_datenbank"  // NEU
  ],
  "allowed_tables": {
    // ...
    "neue_datenbank": [  // NEU
      "tabelle1",
      "tabelle2"
    ]
  }
}

# Sofort wirksam - kein Neustart nötig!

Environment Variables (.env)

Pfad: /var/www/mcp-servers/mcp_db/.env

Änderungen an .env erfordern einen Claude-Neustart!

VariableBeschreibungDefault
DB_HOSTDatenbank-Host für Querieslocalhost
DB_USERUser für Queriesmcp_readonly
DB_PASSWORDPasswort für Query-User-
LOG_DB_HOSTDatenbank-Host für Logginglocalhost
LOG_DB_NAMEDatenbank für Loggingki_dev
LOG_DB_USERUser für Logging (nur INSERT)mcp_logger
LOG_DB_PASSWORDPasswort für Logger-User-

Claude Code Hook

Der Blocking-Hook verhindert direkte mysql/mariadb-Befehle.

Pfad: /root/.claude/settings.json

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "/var/www/scripts/hooks/block_direct_db.py",
        "timeout": 5
      }]
    }]
  }
}

Exit-Codes

Exit CodeBedeutungAktion
0ErlaubenBefehl wird ausgeführt
2BlockierenBefehl wird abgelehnt

config.py Implementierung

Die Config-Klasse lädt bei jedem Zugriff die JSON-Datei neu (Metaclass mit Properties):

"""config.py - Hot-Reload aus JSON"""
import json
from pathlib import Path

CONFIG_PATH = Path("/etc/mcp-db/config.json")

def _load_json_config() -> dict:
    """Lädt JSON-Config bei jedem Aufruf."""
    if CONFIG_PATH.exists():
        with open(CONFIG_PATH, "r") as f:
            return json.load(f)
    return {}

class _ConfigMeta(type):
    @property
    def ALLOWED_DATABASES(cls) -> list:
        cfg = _load_json_config()
        return cfg.get("allowed_databases", ["ki_dev", "ki_content"])

    @property
    def ALLOWED_TABLES(cls) -> list:
        cfg = _load_json_config()
        tables_dict = cfg.get("allowed_tables", {})
        return [t for tables in tables_dict.values() 
                if isinstance(tables, list) for t in tables]
    # ... weitere Properties

class Config(metaclass=_ConfigMeta):
    # Statische Werte aus Environment
    DB_HOST = os.getenv("DB_HOST", "localhost")
    DB_USER = os.getenv("DB_USER", "mcp_readonly")
    # ...

Keyword Blocklist

KategorieKeywords
DMLDELETE, INSERT, UPDATE
DDLDROP, TRUNCATE, ALTER, CREATE, RENAME
DCLGRANT, REVOKE
File-OpsLOAD_FILE, INTO OUTFILE, INTO DUMPFILE
DoSBENCHMARK, SLEEP

Limits

LimitWertBeschreibung
max_query_length2000Maximale Query-Länge in Zeichen
max_rows100Maximale Ergebniszeilen
query_timeout_sec30Query-Timeout in Sekunden

Verwandte Kapitel