Protokoll #27651

ID27651
Zeitstempel2025-12-28 10:15:38.496277
Clientroot
IP145.224.72.140
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens2,670 (Input: 22, Output: 2,648)
Dauer82 ms
Request-Zeit2025-12-28 10:15:38.496277
Response-Zeit2025-12-28 10:15:38.577941

Request

{
    "event": "PreToolUse",
    "tool_name": "mcp__mcp-docs__docs_get",
    "tool_input": {
        "id": 156
    }
}

Response

{
    "tool_response": [
        {
            "type": "text",
            "text": "{\n  \"success\": true,\n  \"doc\": {\n    \"id\": 156,\n    \"parent_id\": null,\n    \"slug\": \"mcp-server-refactoring-plan\",\n    \"path\": \"\/mcp-server-refactoring-plan\",\n    \"title\": \"MCP Server Refactoring Plan\",\n    \"description\": \"Vollständiger Refactoring-Plan für alle 5 MCP-Server nach DRY, SRP, SOLID, Clean Architecture\",\n    \"content\": \"# MCP Server Refactoring Plan\\n\\n**Version:** 1.0  \\n**Erstellt:** 2025-12-28  \\n**Status:** Zur Supervision  \\n**Task:** #507\\n\\n---\\n\\n## 1. Executive Summary\\n\\n### Ist-Zustand\\n- **5 MCP-Server**: mcp-db, mcp-tasks, mcp-contracts, mcp-docs, mcp-code\\n- **91 Python-Dateien** (ohne venv)\\n- **9.248 LOC** gesamt\\n- **Signifikante Code-Duplikation** (~25% redundanter Code)\\n- **Inkonsistente Patterns** zwischen Servern\\n\\n### Ziel\\nKonsolidierung zu einer modularen, wartbaren Architektur unter Einhaltung von:\\n- **DRY** (Don't Repeat Yourself)\\n- **SRP** (Single Responsibility Principle)\\n- **SOLID** Principles\\n- **Clean Architecture**\\n- **KISS** (Keep It Simple, Stupid)\\n- **YAGNI** (You Aren't Gonna Need It)\\n\\n### Erwartete Verbesserungen\\n- **~35% weniger Code** durch Elimination von Duplikaten\\n- **Einheitliche Patterns** für alle Server\\n- **Verbesserte Wartbarkeit** durch Modularisierung\\n- **Schnellere Feature-Entwicklung** durch shared Components\\n\\n---\\n\\n## 2. Analyse der Code-Duplikation\\n\\n### 2.1 Kritische Duplikate (Sofort beheben)\\n\\n#### db_connection.py (4 Dateien, ~240 LOC dupliziert)\\n\\n| Server | Zeilen | Bibliothek | Methoden |\\n|--------|--------|------------|----------|\\n| mcp-db | 59 | mysql.connector + pooling | get_pool(), get_connection(db) |\\n| mcp-tasks | 62 | pymysql | get_connection(), get_log_connection() |\\n| mcp-contracts | 60 | pymysql | get_connection(), get_log_connection() |\\n| mcp-docs | 60 | pymysql | get_connection(), get_log_connection() |\\n\\n**Problem:** 3 von 4 Dateien sind nahezu identisch (mcp-tasks, mcp-contracts, mcp-docs).\\n\\n**Lösung:** Zentralisieren in `shared\/infrastructure\/db_connection.py`\\n\\n```python\\n# shared\/infrastructure\/db_connection.py\\nclass DatabaseConnection:\\n    \\\"\\\"\\\"Unified DB Connection Manager\\\"\\\"\\\"\\n    \\n    @classmethod\\n    @contextmanager\\n    def get_connection(cls, config: \\\"ServerConfig\\\") -> Generator[Connection, None, None]:\\n        \\\"\\\"\\\"Standard connection with transaction handling\\\"\\\"\\\"\\n        \\n    @classmethod\\n    @contextmanager  \\n    def get_log_connection(cls, config: \\\"ServerConfig\\\") -> Generator[Connection, None, None]:\\n        \\\"\\\"\\\"Logging connection (autocommit)\\\"\\\"\\\"\\n```\\n\\n#### protokoll_logger.py (4 Dateien, ~240 LOC dupliziert)\\n\\n| Server | Zeilen | Unterschied |\\n|--------|--------|-------------|\\n| mcp-db | 60 | Eigenes Pooling, LogEntry aus domain |\\n| mcp-tasks | 62 | Extra: task_id Handling |\\n| mcp-contracts | 60 | Standard Pattern |\\n| mcp-docs | 59 | Standard Pattern |\\n\\n**Problem:** mcp-contracts und mcp-docs sind identisch bis auf Log-Message.\\n\\n**Lösung:** Zentralisieren in `shared\/infrastructure\/protokoll_logger.py`\\n\\n```python\\n# shared\/infrastructure\/protokoll_logger.py\\nclass ProtokollLogger:\\n    def __init__(self, client_name: str):\\n        self.client_name = client_name  # z.B. \\\"MCP-Tasks\\\"\\n    \\n    def log(self, entry: LogEntry) -> None:\\n        \\\"\\\"\\\"Unified logging with optional context fields\\\"\\\"\\\"\\n```\\n\\n#### config.py (5 Dateien, ~300 LOC mit Overlap)\\n\\n**Gemeinsame Felder in allen Servern:**\\n- DB_HOST, DB_PORT, DB_USER, DB_PASSWORD\\n- LOG_DB_HOST, LOG_DB_NAME, LOG_DB_USER, LOG_DB_PASSWORD\\n\\n**Lösung:** Base Config in shared\/\\n\\n```python\\n# shared\/config_base.py\\nclass BaseConfig:\\n    \\\"\\\"\\\"Gemeinsame Konfiguration für alle MCP-Server\\\"\\\"\\\"\\n    DB_HOST: str = os.getenv(\\\"DB_HOST\\\", \\\"localhost\\\")\\n    DB_PORT: int = int(os.getenv(\\\"DB_PORT\\\", \\\"3306\\\"))\\n    # ... alle gemeinsamen Felder\\n\\n# mcp-tasks\/config.py\\nfrom shared.config_base import BaseConfig\\n\\nclass Config(BaseConfig):\\n    \\\"\\\"\\\"Task-spezifische Konfiguration\\\"\\\"\\\"\\n    OLLAMA_HOST: str = ...\\n    VALID_STATUSES: List[str] = ...\\n```\\n\\n### 2.2 Server-Struktur Duplikation\\n\\n#### server.py (5 Dateien, ~250 LOC)\\n\\nAlle Server folgen dem gleichen Pattern:\\n1. Logging Setup\\n2. dotenv laden\\n3. FastMCP initialisieren\\n4. Tools importieren\\n5. Tools registrieren\\n6. main() mit mcp.run()\\n\\n**Lösung:** Factory Pattern\\n\\n```python\\n# shared\/server_factory.py\\ndef create_mcp_server(\\n    name: str,\\n    instructions: str,\\n    tool_registrars: List[Callable[[FastMCP], None]]\\n) -> FastMCP:\\n    \\\"\\\"\\\"Creates configured MCP server with standard setup\\\"\\\"\\\"\\n    \\n    # Unified logging setup\\n    logging.basicConfig(...)\\n    \\n    # Load environment\\n    load_dotenv(Path(__file__).parent \/ \\\".env\\\")\\n    \\n    # Create server\\n    mcp = FastMCP(name, instructions=instructions)\\n    \\n    # Register tools\\n    for registrar in tool_registrars:\\n        registrar(mcp)\\n    \\n    return mcp\\n```\\n\\n---\\n\\n## 3. SRP-Verletzungen\\n\\n### 3.1 ContractValidator (409 Zeilen) - KRITISCH\\n\\n**Aktuelle Verantwortlichkeiten:**\\n1. Pfad-Auflösung aus Scope\\n2. Glob-Pattern Matching\\n3. Datei-Lesen\\n4. Regel-Parsing\\n5. Pattern-Validierung (forbidden\/required)\\n6. Line-Count Check\\n7. Dependency Check\\n8. Outcome Determination\\n\\n**Refactoring-Vorschlag:**\\n\\n```\\nvalidators\/\\n├── contract_validator.py      # Orchestrierung (< 100 Zeilen)\\n├── scope_resolver.py          # Pfad-Auflösung aus YAML\\n├── pattern_matcher.py         # Glob\/Regex Matching\\n├── rules\/\\n│   ├── base_rule.py          # Abstract Rule\\n│   ├── line_count_rule.py\\n│   ├── forbidden_pattern_rule.py\\n│   ├── required_pattern_rule.py\\n│   └── dependency_rule.py\\n└── result_builder.py         # ContractValidationResult erstellen\\n```\\n\\n### 3.2 Repository-Klassen (331-393 Zeilen)\\n\\n**TaskRepository Verantwortlichkeiten:**\\n1. Task CRUD\\n2. Assignment CRUD\\n3. Result CRUD\\n4. Statistics\\n\\n**Refactoring-Vorschlag:**\\n\\n```\\nrepositories\/\\n├── task_repository.py         # Nur Task CRUD (< 150 Zeilen)\\n├── assignment_repository.py   # Assignment CRUD\\n├── result_repository.py       # Result CRUD\\n└── statistics_repository.py   # Statistics Queries\\n```\\n\\n### 3.3 Tool-Dateien (400+ Zeilen)\\n\\n**contract_tools.py (406 Zeilen)** - Bereits gut strukturiert mit Helper-Klassen\\n\\n**Empfehlung:** Behalten, da die Aufteilung in contract_tools\/ bereits erfolgt ist.\\n\\n---\\n\\n## 4. Inkonsistenzen\\n\\n### 4.1 Datenbank-Bibliotheken\\n\\n| Server | Bibliothek | Problem |\\n|--------|------------|---------|\\n| mcp-db | mysql.connector | Anderes Cursor-Handling, kein DictCursor default |\\n| mcp-tasks | pymysql | Standard Pattern |\\n| mcp-contracts | pymysql | Standard Pattern |\\n| mcp-docs | pymysql | Standard Pattern |\\n| mcp-code | Direktes mysql.connector | Kein Context Manager |\\n\\n**Empfehlung:** \\n- **Standardisieren auf pymysql** (4 von 5 Servern nutzen es bereits)\\n- mcp-db auf pymysql migrieren (Breaking Change minimieren durch Wrapper)\\n\\n### 4.2 Singleton Patterns\\n\\n| Server | Pattern |\\n|--------|---------|\\n| mcp-tasks | `_logger_instance` + `get_logger()` |\\n| mcp-contracts | `_logger_instance` + `get_logger()` |\\n| mcp-docs | `_repository_instance` + `get_repository()` |\\n| mcp-db | Keine Singletons |\\n| mcp-code | Keine Singletons |\\n\\n**Empfehlung:** Einheitliches Pattern etablieren\\n\\n```python\\n# shared\/patterns.py\\nfrom functools import lru_cache\\n\\n@lru_cache(maxsize=1)\\ndef get_logger(client_name: str) -> ProtokollLogger:\\n    return ProtokollLogger(client_name)\\n```\\n\\n### 4.3 Hardcoded Pfade\\n\\n**Problem:** Überall `sys.path.insert(0, \\\"\/opt\/mcp-servers\/...\\\")`\\n\\n**Lösung:** Relative Imports + pyproject.toml für Package-Struktur\\n\\n```toml\\n# \/var\/www\/mcp-servers\/pyproject.toml\\n[project]\\nname = \\\"mcp-servers\\\"\\npackages = [\\\"shared\\\", \\\"mcp_db\\\", \\\"mcp_tasks\\\", \\\"mcp_contracts\\\", \\\"mcp_docs\\\", \\\"mcp_code\\\"]\\n```\\n\\n---\\n\\n## 5. Ziel-Architektur\\n\\n### 5.1 Verzeichnisstruktur\\n\\n```\\n\/var\/www\/mcp-servers\/\\n├── shared\/                           # Gemeinsame Komponenten\\n│   ├── __init__.py\\n│   ├── config_base.py               # BaseConfig für alle Server\\n│   ├── constants.py                 # ✓ Existiert bereits\\n│   ├── server_factory.py            # Server Creation Factory\\n│   ├── infrastructure\/\\n│   │   ├── __init__.py\\n│   │   ├── db_connection.py         # Unified DB Connection\\n│   │   └── protokoll_logger.py      # Unified Logger\\n│   ├── domain\/\\n│   │   ├── __init__.py\\n│   │   └── log_entry.py             # Shared LogEntry Dataclass\\n│   └── patterns\/\\n│       ├── __init__.py\\n│       ├── repository_base.py       # Base Repository Pattern\\n│       └── singleton.py             # Singleton Utilities\\n│\\n├── mcp-db\/                          # Bestehendes Layout\\n│   ├── server.py                    # Nutzt shared\/server_factory\\n│   ├── config.py                    # Erbt von shared\/config_base\\n│   ├── tools\/                       # Unverändert\\n│   └── validators\/                  # Unverändert\\n│\\n├── mcp-tasks\/\\n│   ├── server.py\\n│   ├── config.py\\n│   ├── domain\/                      # Unverändert\\n│   ├── infrastructure\/\\n│   │   ├── __init__.py\\n│   │   ├── task_repository.py       # Nutzt shared\/db_connection\\n│   │   └── [protokoll_logger.py]    # ENTFERNT - nutzt shared\/\\n│   └── tools\/\\n│\\n├── mcp-contracts\/\\n│   ├── server.py\\n│   ├── config.py\\n│   ├── domain\/\\n│   ├── infrastructure\/\\n│   │   ├── contract_repository.py\\n│   │   └── [protokoll_logger.py]    # ENTFERNT\\n│   ├── validators\/\\n│   │   ├── contract_validator.py    # Refactored (< 100 Zeilen)\\n│   │   ├── scope_resolver.py        # NEU\\n│   │   ├── pattern_matcher.py       # NEU\\n│   │   └── rules\/                   # NEU\\n│   └── tools\/\\n│\\n├── mcp-docs\/\\n│   └── ...\\n│\\n└── mcp-code\/\\n    └── ...\\n```\\n\\n### 5.2 Abhängigkeiten (Clean Architecture)\\n\\n```\\n┌─────────────────────────────────────────────────────────┐\\n│                       SHARED                             │\\n│  ┌───────────────────────────────────────────────────... [TRUNCATED-7ba37dac0f7584a6]"
        }
    ]
}
← Vorheriger Zur Liste Nächster →