Protokoll #15755

ID15755
Zeitstempel2025-12-25 16:56:34.585342
Clientroot
IP145.224.72.140
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens7,763 (Input: 105, Output: 7,658)
Dauer116 ms
Request-Zeit2025-12-25 16:56:34.585342
Response-Zeit2025-12-25 16:56:34.701797

Request

{
    "event": "PreToolUse",
    "tool_name": "Write",
    "tool_input": {
        "file_path": "\/var\/www\/mcp-servers\/mcp-docs\/tools\/docs_tools.py",
        "content": "\"\"\"\nMCP-Tools for Documentation Management.\n\nThis module delegates to the modularized docs_tools package.\nFor backward compatibility, it re-exports the main registration function.\n\"\"\"\n\nfrom docs_tools import register_docs_tools\n\n__all__ = [\"register_docs_tools\"]\n"
    }
}

Response

{
    "tool_response": {
        "type": "update",
        "filePath": "\/var\/www\/mcp-servers\/mcp-docs\/tools\/docs_tools.py",
        "content": "\"\"\"\nMCP-Tools for Documentation Management.\n\nThis module delegates to the modularized docs_tools package.\nFor backward compatibility, it re-exports the main registration function.\n\"\"\"\n\nfrom docs_tools import register_docs_tools\n\n__all__ = [\"register_docs_tools\"]\n",
        "structuredPatch": [
            {
                "oldStart": 1,
                "oldLines": 526,
                "newStart": 1,
                "newLines": 10,
                "lines": [
                    "-\"\"\"MCP-Tools für Dokumentations-Management\"\"\"",
                    "-import json",
                    "-import sys",
                    "-import time",
                    "-from datetime import datetime",
                    "-from typing import Optional",
                    "+\"\"\"",
                    "+MCP-Tools for Documentation Management.",
                    " ",
                    "-sys.path.insert(0, \"\/opt\/mcp-servers\/mcp-docs\")",
                    "-from domain.dokumentation import Dokumentation, DocStatus, LogEntry",
                    "-from infrastructure.docs_repository import DocsRepository, get_repository",
                    "-from infrastructure.protokoll_logger import get_logger",
                    "+This module delegates to the modularized docs_tools package.",
                    "+For backward compatibility, it re-exports the main registration function.",
                    "+\"\"\"",
                    " ",
                    "+from docs_tools import register_docs_tools",
                    " ",
                    "-def register_docs_tools(mcp):",
                    "-    \"\"\"Registriert alle Dokumentations-Tools beim MCP-Server\"\"\"",
                    "-",
                    "-    @mcp.tool()",
                    "-    def docs_list(",
                    "-        status: Optional[str] = None,",
                    "-        parent_id: Optional[int] = None,",
                    "-        search: Optional[str] = None,",
                    "-        compact: bool = True,",
                    "-        limit: int = 20",
                    "-    ) -> dict:",
                    "-        \"\"\"",
                    "-        Listet alle Dokumente aus der Datenbank.",
                    "-",
                    "-        Args:",
                    "-            status: Filter nach Status (draft, published, archived)",
                    "-            parent_id: Filter nach Parent-ID",
                    "-            search: Volltextsuche in Titel\/Beschreibung",
                    "-            compact: True = nur id\/path\/title\/status (Token-sparend)",
                    "-            limit: Maximale Anzahl Ergebnisse",
                    "-",
                    "-        Returns:",
                    "-            Liste der Dokumente",
                    "-        \"\"\"",
                    "-        start_time = time.time()",
                    "-        logger = get_logger()",
                    "-        repo = get_repository()",
                    "-",
                    "-        try:",
                    "-            docs = repo.find_all(",
                    "-                status=status,",
                    "-                parent_id=parent_id,",
                    "-                search=search,",
                    "-                limit=limit",
                    "-            )",
                    "-            total = repo.count(status=status, parent_id=parent_id, search=search)",
                    "-",
                    "-            result = {",
                    "-                \"success\": True,",
                    "-                \"docs\": [d.to_dict_compact() if compact else d.to_dict() for d in docs],",
                    "-                \"total\": total,",
                    "-                \"limit\": limit,",
                    "-                \"compact\": compact",
                    "-            }",
                    "-",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_list\",",
                    "-                request=json.dumps({\"status\": status, \"parent_id\": parent_id, \"search\": search, \"limit\": limit}),",
                    "-                status=\"success\",",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-",
                    "-            return result",
                    "-",
                    "-        except Exception as e:",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_list\",",
                    "-                request=json.dumps({\"status\": status, \"search\": search}),",
                    "-                status=\"error\",",
                    "-                error_message=str(e),",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-            return {\"success\": False, \"error\": str(e)}",
                    "-",
                    "-    @mcp.tool()",
                    "-    def docs_get(",
                    "-        id: Optional[int] = None,",
                    "-        path: Optional[str] = None,",
                    "-        include_children: bool = False,",
                    "-        include_breadcrumb: bool = False",
                    "-    ) -> dict:",
                    "-        \"\"\"",
                    "-        Holt ein Dokument nach ID oder Pfad.",
                    "-",
                    "-        Args:",
                    "-            id: Dokument-ID",
                    "-            path: Dokument-Pfad (alternativ zu ID)",
                    "-            include_children: Kind-Dokumente einschließen",
                    "-            include_breadcrumb: Breadcrumb-Pfad einschließen",
                    "-",
                    "-        Returns:",
                    "-            Dokument mit Details",
                    "-        \"\"\"",
                    "-        start_time = time.time()",
                    "-        logger = get_logger()",
                    "-        repo = get_repository()",
                    "-",
                    "-        try:",
                    "-            if id is None and path is None:",
                    "-                return {\"success\": False, \"error\": \"Entweder id oder path muss angegeben werden\"}",
                    "-",
                    "-            doc = None",
                    "-            if id is not None:",
                    "-                doc = repo.find_by_id(id)",
                    "-            elif path is not None:",
                    "-                doc = repo.find_by_path(path)",
                    "-",
                    "-            if not doc:",
                    "-                return {\"success\": False, \"error\": \"Dokument nicht gefunden\"}",
                    "-",
                    "-            result = {",
                    "-                \"success\": True,",
                    "-                \"doc\": doc.to_dict()",
                    "-            }",
                    "-",
                    "-            if include_children and doc.id:",
                    "-                children = repo.find_children(doc.id)",
                    "-                result[\"children\"] = [c.to_dict_compact() for c in children]",
                    "-",
                    "-            if include_breadcrumb and doc.id:",
                    "-                result[\"breadcrumb\"] = repo.get_breadcrumb(doc.id)",
                    "-",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_get\",",
                    "-                request=json.dumps({\"id\": id, \"path\": path}),",
                    "-                status=\"success\",",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-",
                    "-            return result",
                    "-",
                    "-        except Exception as e:",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_get\",",
                    "-                request=json.dumps({\"id\": id, \"path\": path}),",
                    "-                status=\"error\",",
                    "-                error_message=str(e),",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-            return {\"success\": False, \"error\": str(e)}",
                    "-",
                    "-    @mcp.tool()",
                    "-    def docs_create(",
                    "-        title: str,",
                    "-        slug: str,",
                    "-        content: str = \"\",",
                    "-        description: Optional[str] = None,",
                    "-        parent_id: Optional[int] = None,",
                    "-        status: str = \"draft\",",
                    "-        sort_order: int = 0",
                    "-    ) -> dict:",
                    "-        \"\"\"",
                    "-        Erstellt ein neues Dokument.",
                    "-",
                    "-        Args:",
                    "-            title: Dokumenttitel (required)",
                    "-            slug: URL-Slug (required)",
                    "-            content: HTML-Inhalt",
                    "-            description: Kurzbeschreibung",
                    "-            parent_id: ID des Parent-Dokuments",
                    "-            status: Status (draft, published, archived)",
                    "-            sort_order: Sortierung innerhalb Parent",
                    "-",
                    "-        Returns:",
                    "-            Erstelltes Dokument",
                    "-        \"\"\"",
                    "-        start_time = time.time()",
                    "-        logger = get_logger()",
                    "-        repo = get_repository()",
                    "-",
                    "-        try:",
                    "-            # Pfad berechnen",
                    "-            if parent_id is not None:",
                    "-                parent = repo.find_by_id(parent_id)",
                    "-                if not parent:",
                    "-                    return {\"success\": False, \"error\": f\"Parent mit ID {parent_id} nicht gefunden\"}",
                    "-                path = f\"{parent.path}\/{slug}\"",
                    "-                depth = parent.depth + 1",
                    "-            else:",
                    "-                path = f\"\/{slug}\"",
                    "-                depth = 0",
                    "-",
                    "-            # Prüfen ob Pfad bereits existiert",
                    "-            existing = repo.find_by_path(path)",
                    "-            if existing:",
                    "-                return {\"success\": False, \"error\": f\"Pfad '{path}' existiert bereits\"}",
                    "-",
                    "-            doc = Dokumentation(",
                    "-                parent_id=parent_id,",
                    "-                slug=slug,",
                    "-                path=path,",
                    "-                title=title,",
                    "-                description=description,",
                    "-                content=content,",
                    "-                status=DocStatus(status) if status in [\"draft\", \"published\", \"archived\"] else DocStatus.DRAFT,",
                    "-                sort_order=sort_order,",
                    "-                depth=depth",
                    "-            )",
                    "-",
                    "-            new_id = repo.create(doc)",
                    "-            created_doc = repo.find_by_id(new_id)",
                    "-",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_create\",",
                    "-                request=json.dumps({\"title\": title, \"slug\": slug, \"parent_id\": parent_id}),",
                    "-                status=\"success\",",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-",
                    "-            return {",
                    "-                \"success\": True,",
                    "-                \"doc\": created_doc.to_dict() if created_doc else None,",
                    "-                \"message\": f\"Dokument '{title}' erstellt mit ID {new_id}\"",
                    "-            }",
                    "-",
                    "-        except Exception as e:",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_create\",",
                    "-                request=json.dumps({\"title\": title, \"slug\": slug}),",
                    "-                status=\"error\",",
                    "-                error_message=str(e),",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-            return {\"success\": False, \"error\": str(e)}",
                    "-",
                    "-    @mcp.tool()",
                    "-    def docs_update(",
                    "-        id: int,",
                    "-        title: Optional[str] = None,",
                    "-        content: Optional[str] = None,",
                    "-        description: Optional[str] = None,",
                    "-        status: Optional[str] = None",
                    "-    ) -> dict:",
                    "-        \"\"\"",
                    "-        Aktualisiert ein Dokument.",
                    "-",
                    "-        Args:",
                    "-            id: Dokument-ID (required)",
                    "-            title: Neuer Titel",
                    "-            content: Neuer Inhalt",
                    "-            description: Neue Beschreibung",
                    "-            status: Neuer Status (draft, published, archived)",
                    "-",
                    "-        Returns:",
                    "-            Aktualisiertes Dokument",
                    "-        \"\"\"",
                    "-        start_time = time.time()",
                    "-        logger = get_logger()",
                    "-        repo = get_repository()",
                    "-",
                    "-        try:",
                    "-            doc = repo.find_by_id(id)",
                    "-            if not doc:",
                    "-                return {\"success\": False, \"error\": f\"Dokument mit ID {id} nicht gefunden\"}",
                    "-",
                    "-            updates = {}",
                    "-            if title is not None:",
                    "-                updates[\"title\"] = title",
                    "-            if content is not None:",
                    "-                updates[\"content\"] = content",
                    "-            if description is not None:",
                    "-                updates[\"description\"] = description",
                    "-            if status is not None and status in [\"draft\", \"published\", \"archived\"]:",
                    "-                updates[\"status\"] = status",
                    "-",
                    "-            if not updates:",
                    "-                return {\"success\": False, \"error\": \"Keine Änderungen angegeben\"}",
                    "-",
                    "-            success = repo.update(id, updates)",
                    "-            if success:",
                    "-                updated_doc = repo.find_by_id(id)",
                    "-",
                    "-                logger.log(LogEntry(",
                    "-                    tool_name=\"docs_update\",",
                    "-                    request=json.dumps({\"id\": id, \"updates\": list(updates.keys())}),",
                    "-                    status=\"success\",",
                    "-                    duration_ms=int((time.time() - start_time) * 1000)",
                    "-                ))",
                    "-",
                    "-                return {",
                    "-                    \"success\": True,",
                    "-                    \"doc\": updated_doc.to_dict() if updated_doc else None,",
                    "-                    \"message\": f\"Dokument #{id} aktualisiert\"",
                    "-                }",
                    "-            else:",
                    "-                return {\"success\": False, \"error\": \"Update fehlgeschlagen\"}",
                    "-",
                    "-        except Exception as e:",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_update\",",
                    "-                request=json.dumps({\"id\": id}),",
                    "-                status=\"error\",",
                    "-                error_message=str(e),",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-            return {\"success\": False, \"error\": str(e)}",
                    "-",
                    "-    @mcp.tool()",
                    "-    def docs_delete(id: int) -> dict:",
                    "-        \"\"\"",
                    "-        Löscht ein Dokument.",
                    "-",
                    "-        Args:",
                    "-            id: Dokument-ID (required)",
                    "-",
                    "-        Returns:",
                    "-            Bestätigung",
                    "-        \"\"\"",
                    "-        start_time = time.time()",
                    "-        logger = get_logger()",
                    "-        repo = get_repository()",
                    "-",
                    "-        try:",
                    "-            doc = repo.find_by_id(id)",
                    "-            if not doc:",
                    "-                return {\"success\": False, \"error\": f\"Dokument mit ID {id} nicht gefunden\"}",
                    "-",
                    "-            success = repo.delete(id)",
                    "-",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_delete\",",
                    "-                request=json.dumps({\"id\": id, \"title\": doc.title}),",
                    "-                status=\"success\" if success else \"error\",",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-",
                    "-            return {",
                    "-                \"success\": success,",
                    "-                \"message\": f\"Dokument '{doc.title}' (ID {id}) gelöscht\" if success else \"Löschen fehlgeschlagen\"",
                    "-            }",
                    "-",
                    "-        except ValueError as e:",
                    "-            # Kinder vorhanden",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_delete\",",
                    "-                request=json.dumps({\"id\": id}),",
                    "-                status=\"denied\",",
                    "-                error_message=str(e),",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-            return {\"success\": False, \"error\": str(e)}",
                    "-",
                    "-        except Exception as e:",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_delete\",",
                    "-                request=json.dumps({\"id\": id}),",
                    "-                status=\"error\",",
                    "-                error_message=str(e),",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-            return {\"success\": False, \"error\": str(e)}",
                    "-",
                    "-    @mcp.tool()",
                    "-    def docs_move(",
                    "-        id: int,",
                    "-        new_parent_id: Optional[int] = None,",
                    "-        new_sort_order: Optional[int] = None",
                    "-    ) -> dict:",
                    "-        \"\"\"",
                    "-        Verschiebt ein Dokument zu einem neuen Parent.",
                    "-",
                    "-        Args:",
                    "-            id: Dokument-ID (required)",
                    "-            new_parent_id: Neue Parent-ID (None für Root)",
                    "-            new_sort_order: Neue Sortierung",
                    "-",
                    "-        Returns:",
                    "-            Aktualisiertes Dokument",
                    "-        \"\"\"",
                    "-        start_time = time.time()",
                    "-        logger = get_logger()",
                    "-        repo = get_repository()",
                    "-",
                    "-        try:",
                    "-            doc = repo.find_by_id(id)",
                    "-            if not doc:",
                    "-                return {\"success\": False, \"error\": f\"Dokument mit ID {id} nicht gefunden\"}",
                    "-",
                    "-            success = repo.move(id, new_parent_id, new_sort_order)",
                    "-            if success:",
                    "-                updated_doc = repo.find_by_id(id)",
                    "-",
                    "-                logger.log(LogEntry(",
                    "-                    tool_name=\"docs_move\",",
                    "-                    request=json.dumps({\"id\": id, \"new_parent_id\": new_parent_id}),",
                    "-                    status=\"success\",",
                    "-                    duration_ms=int((time.time() - start_time) * 1000)",
                    "-                ))",
                    "-",
                    "-                return {",
                    "-                    \"success\": True,",
                    "-                    \"doc\": updated_doc.to_dict_compact() if updated_doc else None,",
                    "-                    \"message\": f\"Dokument #{id} verschoben\"",
                    "-                }",
                    "-            else:",
                    "-                return {\"success\": False, \"error\": \"Verschieben fehlgeschlagen\"}",
                    "-",
                    "-        except Exception as e:",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_move\",",
                    "-                request=json.dumps({\"id\": id}),",
                    "-                status=\"error\",",
                    "-                error_message=str(e),",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-            return {\"success\": False, \"error\": str(e)}",
                    "-",
                    "-    @mcp.tool()",
                    "-    def docs_hierarchy() -> dict:",
                    "-        \"\"\"",
                    "-        Gibt den kompletten Dokumentationsbaum zurück.",
                    "-",
                    "-        Returns:",
                    "-            Hierarchischer Baum aller Dokumente",
                    "-        \"\"\"",
                    "-        start_time = time.time()",
                    "-        logger = get_logger()",
                    "-        repo = get_repository()",
                    "-",
                    "-        try:",
                    "-            hierarchy = repo.get_hierarchy()",
                    "-",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_hierarchy\",",
                    "-                request=\"{}\",",
                    "-                status=\"success\",",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-",
                    "-            return {",
                    "-                \"success\": True,",
                    "-                \"hierarchy\": hierarchy",
                    "-            }",
                    "-",
                    "-        except Exception as e:",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_hierarchy\",",
                    "-                request=\"{}\",",
                    "-                status=\"error\",",
                    "-                error_message=str(e),",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-            return {\"success\": False, \"error\": str(e)}",
                    "-",
                    "-    @mcp.tool()",
                    "-    def docs_search(query: str, limit: int = 20) -> dict:",
                    "-        \"\"\"",
                    "-        Volltextsuche in allen Dokumenten.",
                    "-",
                    "-        Args:",
                    "-            query: Suchbegriff (required)",
                    "-            limit: Maximale Anzahl Ergebnisse",
                    "-",
                    "-        Returns:",
                    "-            Liste der gefundenen Dokumente",
                    "-        \"\"\"",
                    "-        start_time = time.time()",
                    "-        logger = get_logger()",
                    "-        repo = get_repository()",
                    "-",
                    "-        try:",
                    "-            docs = repo.find_all(search=query, limit=limit)",
                    "-",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_search\",",
                    "-                request=json.dumps({\"query\": query, \"limit\": limit}),",
                    "-                status=\"success\",",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-",
                    "-            return {",
                    "-                \"success\": True,",
                    "-                \"query\": query,",
                    "-                \"results\": [d.to_dict_compact() for d in docs],",
                    "-                \"count\": len(docs)",
                    "-            }",
                    "-",
                    "-        except Exception as e:",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_search\",",
                    "-                request=json.dumps({\"query\": query}),",
                    "-                status=\"error\",",
                    "-                error_message=str(e),",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-            return {\"success\": False, \"error\": str(e)}",
                    "-",
                    "-    @mcp.tool()",
                    "-    def docs_statistics() -> dict:",
                    "-        \"\"\"",
                    "-        Gibt Statistiken über alle Dokumente zurück.",
                    "-",
                    "-        Returns:",
                    "-            Statistiken: Dokumente nach Status, Tiefe, etc.",
                    "-        \"\"\"",
                    "-        start_time = time.time()",
                    "-        logger = get_logger()",
                    "-        repo = get_repository()",
                    "-",
                    "-        try:",
                    "-            stats = repo.get_statistics()",
                    "-",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_statistics\",",
                    "-                request=\"{}\",",
                    "-                status=\"success\",",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-",
                    "-            return {",
                    "-                \"success\": True,",
                    "-                \"statistics\": stats",
                    "-            }",
                    "-",
                    "-        except Exception as e:",
                    "-            logger.log(LogEntry(",
                    "-                tool_name=\"docs_statistics\",",
                    "-                request=\"{}\",",
                    "-                status=\"error\",",
                    "-                error_message=str(e),",
                    "-                duration_ms=int((time.time() - start_time) * 1000)",
                    "-            ))",
                    "-            return {\"success\": False, \"error\": str(e)}",
                    "+__all__ = [\"register_docs_tools\"]"
                ]
            }
        ],
        "originalFile": "\"\"\"MCP-Tools für Dokumentations-Management\"\"\"\nimport json\nimport sys\nimport time\nfrom datetime import datetime\nfrom typing import Optional\n\nsys.path.insert(0, \"\/opt\/mcp-servers\/mcp-docs\")\nfrom domain.dokumentation import Dokumentation, DocStatus, LogEntry\nfrom infrastructure.docs_repository import DocsRepository, get_repository\nfrom infrastructure.protokoll_logger import get_logger\n\n\ndef register_docs_tools(mcp):\n    \"\"\"Registriert alle Dokumentations-Tools beim MCP-Server\"\"\"\n\n    @mcp.tool()\n    def docs_list(\n        status: Optional[str] = None,\n        parent_id: Optional[int] = None,\n        search: Optional[str] = None,\n        compact: bool = True,\n        limit: int = 20\n    ) -> dict:\n        \"\"\"\n        Listet alle Dokumente aus der Datenbank.\n\n        Args:\n            status: Filter nach Status (draft, published, archived)\n            parent_id: Filter nach Parent-ID\n            search: Volltextsuche in Titel\/Beschreibung\n            compact: True = nur id\/path\/title\/status (Token-sparend)\n            limit: Maximale Anzahl Ergebnisse\n\n        Returns:\n            Liste der Dokumente\n        \"\"\"\n        start_time = time.time()\n        logger = get_logger()\n        repo = get_repository()\n\n        try:\n            docs = repo.find_all(\n                status=status,\n                parent_id=parent_id,\n                search=search,\n                limit=limit\n            )\n            total = repo.count(status=status, parent_id=parent_id, search=search)\n\n            result = {\n                \"success\": True,\n                \"docs\": [d.to_dict_compact() if compact else d.to_dict() for d in docs],\n                \"total\": total,\n                \"limit\": limit,\n                \"compact\": compact\n            }\n\n            logger.log(LogEntry(\n                tool_name=\"docs_list\",\n                request=json.dumps({\"status\": status, \"parent_id\": parent_id, \"search\": search, \"limit\": limit}),\n                status=\"success\",\n                duration_ms=int((time.time() - start_time) * 1000)\n            ))\n\n            return result\n\n        except Exception as e:\n            logger.log(LogEntry(\n                tool_name=\"docs_list\",\n                request=json.dumps({\"status\": status, \"search\": search}),\n                status=\"error\",\n                error_message=str(e),\n                duration_ms=int((time.time() - start_time) * 1000)\n            ))\n            return {\"success\": False, \"error\": str(e)}\n\n    @mcp.tool()\n    def docs_get(\n        id: Optional[int] = None,\n        path: Optional[str] = None,\n        include_children: bool = False,\n        include_breadcrumb: bool = False\n    ) -> dict:\n        \"\"\"\n        Holt ein Dokument nach ID oder Pfad.\n\n        Args:\n            id: Dokument-ID\n            path: Dokument-Pfad (alternativ zu ID)\n            include_children: Kind-Dokumente einschließen\n            include_breadcrumb: Breadcrumb-Pfad einschließen\n\n        Returns:\n            Dokument mit Details\n        \"\"\"\n        start_time = time.time()\n        logger = get_logger()\n        repo = get_repository()\n\n        try:\n            if id is None and path is None:\n                return {\"success\": False, \"error\": \"Entweder id oder path muss angegeben werden\"}\n\n            doc = None\n            if id is not None:\n                doc = repo.find_by_id(id)\n            elif path is not None:\n                doc = repo.find_by_path(path)\n\n            if not doc:\n                return {\"success\": False, \"error\": \"Dokument nicht gefunden\"}\n\n            result = {\n                \"success\": True,\n                \"doc\": doc.to_dict()\n            }\n\n            if include_children and doc.id:\n                children = repo.find_children(doc.id)\n                result[\"children\"] = [c.to_dict_compact() for c in children]\n\n            if include_breadcrumb and doc.id:\n                result[\"breadcrumb\"] = repo.get_breadcrumb(doc.id)\n\n            logger.log(LogEntry(\n                tool_name=\"docs_get\",\n                request=json.dumps({\"id\": id, \"path\": path}),\n                status=\"success\",\n                duration_ms=int((time.time() - start_time) * 1000)\n            ))\n\n            return result\n\n        except Exception as e:\n            logger.log(LogEntry(\n                tool_name=\"docs_get\",\n                request=json.dumps({\"id\": id, \"path\": path}),\n                status=\"error\",\n                error_message=str(e),\n                duration_ms=int((time.time() - start_time) * 1000)\n            ))\n            return {\"success\": False, \"error\": str(e)}\n\n    @mcp.tool()\n    def docs_create(\n        title: str,\n        slug: str,\n        content: str = \"\",\n        description: Optional[str] = None,\n        parent_id: Optional[int] = None,\n        status: str = \"draft\",\n        sort_order: int = 0\n    ) -> dict:\n        \"\"\"\n        Erstellt ein neues Dokument.\n\n        Args:\n            title: Dokumenttitel (required)\n            slug: URL-Slug (required)\n            content: HTML-Inhalt\n            description: Kurzbeschreibung\n            parent_id: ID des Parent-Dokuments\n            status: Status (draft, published, archived)\n            sort_order: Sortierung innerhalb Parent\n\n        Returns:\n            Erstelltes Dokument\n        \"\"\"\n        start_time = time.time()\n        logger = get_logger()\n        repo = get_repository()\n\n        try:\n            # Pfad berechnen\n            if parent_id is not None:\n                parent = repo.find_by_id(parent_id)\n                if not parent:\n                    return {\"success\": False, \"error\": f\"Parent mit ID {parent_id} nicht gefunden\"}\n                path = f\"{parent.path}\/{slug}\"\n                depth = parent.depth + 1\n            else:\n                path = f\"\/{slug}\"\n                depth = 0\n\n            # Prüfen ob Pfad bereits existiert\n            existing = repo.find_by_path(path)\n            if existing:\n                return {\"success\": False, \"error\": f\"Pfad '{path}' existiert bereits\"}\n\n            doc = Dokumentation(\n                parent_id=parent_id,\n                slug=slug,\n                path=path,\n                title=title,\n                description=description,\n                content=content,\n                status=DocStatus(status) if status in [\"draft\", \"published\", \"archived\"] else DocStatus.DRAFT,\n                sort_order=sort_order,\n                depth=depth\n            )\n\n            new_id = repo.create(doc)\n            created_doc = repo.find_by_id(new_id)\n\n            logger.log(LogEntry(\n                tool_name=\"docs_create\",\n                request=json.dumps({\"title\": title, \"slug\": slug, \"parent_id\": parent_id}),\n                status=\"success\",\n                duration_ms=int((time.time() - start_time) * 1000)\n            ))\n\n            return {\n                \"success\": True,\n                \"doc\": created_doc.to_dict() if created_doc else None,\n                \"message\": f\"Dokument '{title}' erstellt mit ID {new_id}\"\n            }\n\n        except Exception as e:\n            logger.log(LogEntry(\n                tool_name=\"docs_create\",\n                request=json.dumps({\"title\": title, \"slug\": slug}),\n                status=\"error\",\n                error_message=str(e),\n                duration_ms=int((time.time() - start_time) * 1000)\n            ))\n            return {\"success\": False, \"error\": str(e)}\n\n    @mcp.tool()\n    def docs_update(\n        id: int,\n        title: Optional[str] = None,\n        content: Optional[str] = None,\n        description: Optional[str] = None,\n        status: Optional[str] = None\n    ) -> dict:\n        \"\"\"\n        Aktualisiert ein Dokument.\n\n        Args:\n            id: Dokument-ID (required)\n            title: Neuer Titel\n            content: Neuer Inhalt\n            description: Neue Beschreibung\n            status: Neuer Status (draft, published, archived)\n\n        Returns:\n            Aktualisiertes Dokument\n        \"\"\"\n        start_time = time.time()\n        logger = get_logger()\n        repo = get_repository()\n\n        try:\n            doc = repo.find_by_id(id)\n            if not doc:\n                return {\"success\": False, \"error\": f\"Dokument mit ID {id} nicht gefunden\"}\n\n            updates = {}\n            if title is not None:\n                updates[\"title\"] = title\n            if content is not None:\n                updates[\"content\"] = content\n            if description is not None:\n                updates[\"description\"] = description\n            if status is not None and status in [\"draft\", \"published\", \"archived\"]:\n                updates[\"status\"] = status\n\n            if not updates:\n                return {\"success\": False, \"error\": \"Keine Änderungen angegeben\"}\n\n            success = repo.update(id, updates)\n            if success:\n                updated_doc = repo.find_by_id(id)\n\n                logger.log(LogEntry(\n                    tool_name=\"docs_update\",\n                    request=json.dumps({\"id\": id, \"updates\": list(updates.keys())}),\n                    status=\"success\",\n                    duration_ms=int((time.time() - start_time) * 1000)\n                ))\n\n                return {\n                    \"success\": True,\n                    \"doc\": updated_doc.to_dict() if updated_doc else None,\n                    \"message\": f\"Dokument #{id} aktualisiert\"\n                }\n            else:\n                return {\"success\": False, \"error\": \"Update fehlgeschlagen\"}\n\n        except Exception as e:\n            logger.log(LogEntry(\n                tool_name=\"docs_update\",\n                request=json.dumps({\"id\": id}),\n                status=\"error\",\n                error_message=str(e),\n                duration_ms=int((time.time() - start_time) * 1000)\n            ))\n            return {\"success\": False, \"error\": str(e)}\n\n    @mcp.tool()\n    def docs_delete(id: int) -> dict:\n        \"\"\"\n        Löscht ein Dokument.\n\n        Args:\n            id: Dokument-ID (required)\n\n        Returns:\n       ... [TRUNCATED-5e6c4089c15e875f]"
    }
}
← Vorheriger Zur Liste Nächster →