{
"event": "PreToolUse",
"tool_name": "mcp__mcp-docs__docs_get",
"tool_input": {
"path": "\/mcp\/mcp-db\/mcp-db-architektur"
}
}
{
"tool_response": [
{
"type": "text",
"text": "{\n \"success\": true,\n \"doc\": {\n \"id\": 39,\n \"parent_id\": 36,\n \"slug\": \"mcp-db-architektur\",\n \"path\": \"\/mcp\/mcp-db\/mcp-db-architektur\",\n \"title\": \"Architektur\",\n \"description\": \"Aufbau und Struktur des MCP-DB Servers nach OOP, SRP, KISS, YAGNI Prinzipien.\",\n \"content\": \"<nav class=\\\"breadcrumb\\\">\\n <a href=\\\"\/docs\\\">Dokumentation<\/a> » <a href=\\\"\/docs\/mcp\/mcp-db\\\">MCP-DB<\/a> » Architektur\\n<\/nav>\\n\\n<h1>MCP-DB Architektur<\/h1>\\n<p class=\\\"doc-meta\\\"><strong>Erstellt:<\/strong> 2025-12-20 | <strong>Aktualisiert:<\/strong> 2025-12-20<\/p>\\n\\n<p>Aufbau und Struktur des MCP-DB Servers nach OOP, SRP, KISS, YAGNI Prinzipien.<\/p>\\n\\n<h2>Verzeichnisstruktur<\/h2>\\n<pre><code>\/opt\/mcp-servers\/mcp-db\/\\n├── server.py # MCP Server Entrypoint\\n├── config.py # Zentrale Konfiguration\\n├── .env # Credentials (chmod 600)\\n├── .env.example # Template\\n├── requirements.txt # Dependencies\\n│\\n├── domain\/ # Contracts (Interfaces)\\n│ ├── __init__.py\\n│ ├── query_contract.py # QueryRequest, QueryResponse\\n│ └── log_contract.py # LogEntry\\n│\\n├── validators\/ # SRP: Separate Validierung\\n│ ├── __init__.py\\n│ └── query_validator.py # SQL Validierung\\n│\\n├── infrastructure\/ # Implementierungen\\n│ ├── __init__.py\\n│ ├── db_connection.py # MariaDB Connection Pool\\n│ └── protokoll_logger.py # Logging nach ki_protokoll\\n│\\n└── tools\/ # MCP Tools\\n ├── __init__.py\\n ├── select_tool.py # db_select\\n ├── schema_tool.py # db_schema\\n └── stats_tool.py # db_stats<\/code><\/pre>\\n\\n<h2>Komponenten-Diagramm<\/h2>\\n<pre><code>┌─────────────────────────────────────────────────────────────┐\\n│ Claude Code │\\n│ │ │\\n│ MCP Protocol │\\n│ │ │\\n│ ▼ │\\n│ ┌──────────────────────────────────────────────────────┐ │\\n│ │ server.py │ │\\n│ │ (Entrypoint) │ │\\n│ └──────────────────────┬───────────────────────────────┘ │\\n│ │ │\\n│ ┌─────────────┼─────────────┐ │\\n│ ▼ ▼ ▼ │\\n│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │\\n│ │ db_select │ │ db_schema │ │ db_stats │ │\\n│ │ Tool │ │ Tool │ │ Tool │ │\\n│ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘ │\\n│ │ │ │ │\\n│ └──────────────┼──────────────┘ │\\n│ ▼ │\\n│ ┌──────────────────────────────────────────────────────┐ │\\n│ │ QueryValidator │ │\\n│ │ (Blocklist, Allowlist, Limits) │ │\\n│ └──────────────────────┬───────────────────────────────┘ │\\n│ │ │\\n│ ┌─────────────┴─────────────┐ │\\n│ ▼ ▼ │\\n│ ┌────────────────────┐ ┌────────────────────┐ │\\n│ │ DatabaseConnection │ │ ProtokollLogger │ │\\n│ │ (Connection Pool) │ │ (mcp_log) │ │\\n│ └─────────┬──────────┘ └─────────┬──────────┘ │\\n│ │ │ │\\n│ ▼ ▼ │\\n│ ┌──────────────┐ ┌──────────────┐ │\\n│ │ MariaDB │ │ ki_protokoll │ │\\n│ │ (ki_system) │ │ (mcp_log) │ │\\n│ └──────────────┘ └──────────────┘ │\\n└─────────────────────────────────────────────────────────────┘<\/code><\/pre>\\n\\n<h2>Design-Prinzipien<\/h2>\\n<table>\\n <tr><th>Prinzip<\/th><th>Umsetzung<\/th><\/tr>\\n <tr>\\n <td><strong>SRP<\/strong><\/td>\\n <td>Jede Klasse hat eine Verantwortung: Validator validiert, Executor führt aus, Logger loggt<\/td>\\n <\/tr>\\n <tr>\\n <td><strong>OOP<\/strong><\/td>\\n <td>Klassen mit klarer Kapselung, keine globalen Funktionen<\/td>\\n <\/tr>\\n <tr>\\n <td><strong>KISS<\/strong><\/td>\\n <td>Minimale Komplexität, kein Over-Engineering<\/td>\\n <\/tr>\\n <tr>\\n <td><strong>YAGNI<\/strong><\/td>\\n <td>Nur SELECT implementiert, keine CRUD-Operationen<\/td>\\n <\/tr>\\n <tr>\\n <td><strong>Immutability<\/strong><\/td>\\n <td>QueryRequest ist frozen (unveränderlich)<\/td>\\n <\/tr>\\n <tr>\\n <td><strong>Fail-Safe<\/strong><\/td>\\n <td>Exceptions statt silent failures<\/td>\\n <\/tr>\\n<\/table>\\n\\n<h2>Datenfluss<\/h2>\\n<pre><code>1. Claude Code ruft db_select(query, database, max_rows, params)\\n2. Tool empfängt Request\\n3. QueryValidator.validate_query() prüft:\\n - SELECT-Only\\n - Keyword-Blocklist\\n - Database-Allowlist\\n - Table-Allowlist\\n - Query-Länge\\n - Max-Rows\\n4. Bei Fehler: DENIED Response + Log\\n5. Bei Erfolg: SelectExecutor.execute()\\n - Connection aus Pool\\n - SET max_statement_time (MariaDB)\\n - cursor.execute(query, params)\\n - fetchmany(max_rows)\\n6. ProtokollLogger.log() schreibt nach mcp_log\\n7. Response zurück an Claude Code<\/code><\/pre>\\n\\n<h2>Verwandte Kapitel<\/h2>\\n<ul>\\n <li><a href=\\\"\/docs\/mcp\/mcp-db-contracts\\\">Contracts<\/a> - QueryRequest, QueryResponse, LogEntry<\/li>\\n <li><a href=\\\"\/docs\/mcp\/mcp-db-validators\\\">Validators<\/a> - SQL-Validierung<\/li>\\n <li><a href=\\\"\/docs\/mcp\/mcp-db-infrastructure\\\">Infrastructure<\/a> - Connection, Logger<\/li>\\n<\/ul>\",\n \"status\": \"published\",\n \"sort_order\": 3,\n \"depth\": 2,\n \"created_at\": \"2025-12-20T11:13:58\",\n \"updated_at\": \"2025-12-27T15:58:19\"\n }\n}"
}
]
}