Protokoll #3707
| ID | 3707 |
|---|---|
| Zeitstempel | 2025-12-22 08:25:17.549456 |
| Client | root |
| IP | Warning: Undefined array key "request_ip" in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 13 Deprecated: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 13 |
| Modell | claude-sonnet-4-20250514 |
| Status | completed |
| Tokens | 4,490 (Input: 0, Output: 0) |
| Dauer | 16422 ms |
| Request-Zeit | Warning: Undefined array key "request_timestamp" in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 18 |
| Response-Zeit | - |
Warning: Undefined array key "error_message" in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 22
Request
{
"event": "PreToolUse",
"tool_name": "Write",
"tool_input": {
"file_path": "\/opt\/mcp-servers\/mcp-db\/config.py",
"content": "\"\"\"Zentrale Konfiguration für MCP-DB Server mit Hot-Reload aus JSON\"\"\"\nimport json\nimport os\nfrom pathlib import Path\nfrom typing import List\n\n# Pfad zur JSON-Config\nCONFIG_PATH = Path(\"\/etc\/mcp-db\/config.json\")\n\n\ndef _load_json_config() -> dict:\n \"\"\"Lädt JSON-Config bei jedem Aufruf (Hot-Reload).\"\"\"\n if CONFIG_PATH.exists():\n try:\n with open(CONFIG_PATH, \"r\") as f:\n return json.load(f)\n except (json.JSONDecodeError, IOError):\n pass\n return {}\n\n\nclass _ConfigMeta(type):\n \"\"\"Metaclass für dynamische Property-Zugriffe auf Config.\"\"\"\n\n @property\n def ALLOWED_DATABASES(cls) -> List[str]:\n \"\"\"Erlaubte Datenbanken - aus JSON geladen.\"\"\"\n cfg = _load_json_config()\n return cfg.get(\"allowed_databases\", [\"ki_dev\", \"ki_content\"])\n\n @property\n def ALLOWED_TABLES(cls) -> List[str]:\n \"\"\"Erlaubte Tabellen - flache Liste aus allen DBs.\"\"\"\n cfg = _load_json_config()\n tables_dict = cfg.get(\"allowed_tables\", {})\n # Flatten: alle Tabellen aus allen DBs\n all_tables = []\n for db_tables in tables_dict.values():\n if isinstance(db_tables, list):\n all_tables.extend(db_tables)\n return all_tables if all_tables else [\n \"mcp_log\", \"protokoll\", \"tasks\", \"contracts\",\n \"dokumentation\", \"prompts\", \"critics\"\n ]\n\n @property\n def BLOCKED_KEYWORDS(cls) -> List[str]:\n \"\"\"Blockierte SQL-Keywords.\"\"\"\n cfg = _load_json_config()\n return cfg.get(\"blocked_keywords\", [\n \"DROP\", \"DELETE\", \"INSERT\", \"UPDATE\", \"TRUNCATE\",\n \"ALTER\", \"CREATE\", \"RENAME\", \"GRANT\", \"REVOKE\",\n \"LOAD_FILE\", \"INTO OUTFILE\", \"INTO DUMPFILE\",\n \"BENCHMARK\", \"SLEEP\"\n ])\n\n @property\n def MAX_QUERY_LENGTH(cls) -> int:\n \"\"\"Maximale Query-Länge.\"\"\"\n cfg = _load_json_config()\n limits = cfg.get(\"limits\", {})\n return limits.get(\"max_query_length\", 2000)\n\n @property\n def MAX_ROWS(cls) -> int:\n \"\"\"Maximale Ergebniszeilen.\"\"\"\n cfg = _load_json_config()\n limits = cfg.get(\"limits\", {})\n return limits.get(\"max_rows\", 100)\n\n @property\n def QUERY_TIMEOUT_SEC(cls) -> int:\n \"\"\"Query-Timeout in Sekunden.\"\"\"\n cfg = _load_json_config()\n limits = cfg.get(\"limits\", {})\n return limits.get(\"query_timeout_sec\", 30)\n\n\nclass Config(metaclass=_ConfigMeta):\n \"\"\"\n Konfiguration mit Hot-Reload aus \/etc\/mcp-db\/config.json.\n\n Änderungen an der JSON-Datei werden sofort wirksam,\n ohne den MCP-Server neu starten zu müssen.\n\n Statische Werte aus Environment Variables:\n - DB_HOST, DB_USER, DB_PASSWORD (Query-User)\n - LOG_DB_HOST, LOG_DB_NAME, LOG_DB_USER, LOG_DB_PASSWORD (Logger)\n\n Dynamische Werte aus JSON:\n - ALLOWED_DATABASES, ALLOWED_TABLES, BLOCKED_KEYWORDS\n - MAX_QUERY_LENGTH, MAX_ROWS, QUERY_TIMEOUT_SEC\n \"\"\"\n\n # Statische Werte aus Environment (nur bei Start geladen)\n DB_HOST: str = os.getenv(\"DB_HOST\", \"localhost\")\n DB_USER: str = os.getenv(\"DB_USER\", \"mcp_readonly\")\n DB_PASSWORD: str = os.getenv(\"DB_PASSWORD\", \"\")\n\n LOG_DB_HOST: str = os.getenv(\"LOG_DB_HOST\", \"localhost\")\n LOG_DB_NAME: str = os.getenv(\"LOG_DB_NAME\", \"ki_dev\")\n LOG_DB_USER: str = os.getenv(\"LOG_DB_USER\", \"mcp_logger\")\n LOG_DB_PASSWORD: str = os.getenv(\"LOG_DB_PASSWORD\", \"\")\n"
}
}
Response
{
"tool_response": {
"type": "update",
"filePath": "\/opt\/mcp-servers\/mcp-db\/config.py",
"content": "\"\"\"Zentrale Konfiguration für MCP-DB Server mit Hot-Reload aus JSON\"\"\"\nimport json\nimport os\nfrom pathlib import Path\nfrom typing import List\n\n# Pfad zur JSON-Config\nCONFIG_PATH = Path(\"\/etc\/mcp-db\/config.json\")\n\n\ndef _load_json_config() -> dict:\n \"\"\"Lädt JSON-Config bei jedem Aufruf (Hot-Reload).\"\"\"\n if CONFIG_PATH.exists():\n try:\n with open(CONFIG_PATH, \"r\") as f:\n return json.load(f)\n except (json.JSONDecodeError, IOError):\n pass\n return {}\n\n\nclass _ConfigMeta(type):\n \"\"\"Metaclass für dynamische Property-Zugriffe auf Config.\"\"\"\n\n @property\n def ALLOWED_DATABASES(cls) -> List[str]:\n \"\"\"Erlaubte Datenbanken - aus JSON geladen.\"\"\"\n cfg = _load_json_config()\n return cfg.get(\"allowed_databases\", [\"ki_dev\", \"ki_content\"])\n\n @property\n def ALLOWED_TABLES(cls) -> List[str]:\n \"\"\"Erlaubte Tabellen - flache Liste aus allen DBs.\"\"\"\n cfg = _load_json_config()\n tables_dict = cfg.get(\"allowed_tables\", {})\n # Flatten: alle Tabellen aus allen DBs\n all_tables = []\n for db_tables in tables_dict.values():\n if isinstance(db_tables, list):\n all_tables.extend(db_tables)\n return all_tables if all_tables else [\n \"mcp_log\", \"protokoll\", \"tasks\", \"contracts\",\n \"dokumentation\", \"prompts\", \"critics\"\n ]\n\n @property\n def BLOCKED_KEYWORDS(cls) -> List[str]:\n \"\"\"Blockierte SQL-Keywords.\"\"\"\n cfg = _load_json_config()\n return cfg.get(\"blocked_keywords\", [\n \"DROP\", \"DELETE\", \"INSERT\", \"UPDATE\", \"TRUNCATE\",\n \"ALTER\", \"CREATE\", \"RENAME\", \"GRANT\", \"REVOKE\",\n \"LOAD_FILE\", \"INTO OUTFILE\", \"INTO DUMPFILE\",\n \"BENCHMARK\", \"SLEEP\"\n ])\n\n @property\n def MAX_QUERY_LENGTH(cls) -> int:\n \"\"\"Maximale Query-Länge.\"\"\"\n cfg = _load_json_config()\n limits = cfg.get(\"limits\", {})\n return limits.get(\"max_query_length\", 2000)\n\n @property\n def MAX_ROWS(cls) -> int:\n \"\"\"Maximale Ergebniszeilen.\"\"\"\n cfg = _load_json_config()\n limits = cfg.get(\"limits\", {})\n return limits.get(\"max_rows\", 100)\n\n @property\n def QUERY_TIMEOUT_SEC(cls) -> int:\n \"\"\"Query-Timeout in Sekunden.\"\"\"\n cfg = _load_json_config()\n limits = cfg.get(\"limits\", {})\n return limits.get(\"query_timeout_sec\", 30)\n\n\nclass Config(metaclass=_ConfigMeta):\n \"\"\"\n Konfiguration mit Hot-Reload aus \/etc\/mcp-db\/config.json.\n\n Änderungen an der JSON-Datei werden sofort wirksam,\n ohne den MCP-Server neu starten zu müssen.\n\n Statische Werte aus Environment Variables:\n - DB_HOST, DB_USER, DB_PASSWORD (Query-User)\n - LOG_DB_HOST, LOG_DB_NAME, LOG_DB_USER, LOG_DB_PASSWORD (Logger)\n\n Dynamische Werte aus JSON:\n - ALLOWED_DATABASES, ALLOWED_TABLES, BLOCKED_KEYWORDS\n - MAX_QUERY_LENGTH, MAX_ROWS, QUERY_TIMEOUT_SEC\n \"\"\"\n\n # Statische Werte aus Environment (nur bei Start geladen)\n DB_HOST: str = os.getenv(\"DB_HOST\", \"localhost\")\n DB_USER: str = os.getenv(\"DB_USER\", \"mcp_readonly\")\n DB_PASSWORD: str = os.getenv(\"DB_PASSWORD\", \"\")\n\n LOG_DB_HOST: str = os.getenv(\"LOG_DB_HOST\", \"localhost\")\n LOG_DB_NAME: str = os.getenv(\"LOG_DB_NAME\", \"ki_dev\")\n LOG_DB_USER: str = os.getenv(\"LOG_DB_USER\", \"mcp_logger\")\n LOG_DB_PASSWORD: str = os.getenv(\"LOG_DB_PASSWORD\", \"\")\n",
"structuredPatch": [
{
"oldStart": 1,
"oldLines": 107,
"newStart": 1,
"newLines": 103,
"lines": [
"-\"\"\"Zentrale Konfiguration für MCP-DB Server\"\"\"",
"+\"\"\"Zentrale Konfiguration für MCP-DB Server mit Hot-Reload aus JSON\"\"\"",
"+import json",
" import os",
"+from pathlib import Path",
" from typing import List",
" ",
"+# Pfad zur JSON-Config",
"+CONFIG_PATH = Path(\"\/etc\/mcp-db\/config.json\")",
" ",
"-class Config:",
"- \"\"\"Konfiguration aus Environment Variables\"\"\"",
" ",
"- # Datenbank für Queries (mcp_readonly)",
"+def _load_json_config() -> dict:",
"+ \"\"\"Lädt JSON-Config bei jedem Aufruf (Hot-Reload).\"\"\"",
"+ if CONFIG_PATH.exists():",
"+ try:",
"+ with open(CONFIG_PATH, \"r\") as f:",
"+ return json.load(f)",
"+ except (json.JSONDecodeError, IOError):",
"+ pass",
"+ return {}",
"+",
"+",
"+class _ConfigMeta(type):",
"+ \"\"\"Metaclass für dynamische Property-Zugriffe auf Config.\"\"\"",
"+",
"+ @property",
"+ def ALLOWED_DATABASES(cls) -> List[str]:",
"+ \"\"\"Erlaubte Datenbanken - aus JSON geladen.\"\"\"",
"+ cfg = _load_json_config()",
"+ return cfg.get(\"allowed_databases\", [\"ki_dev\", \"ki_content\"])",
"+",
"+ @property",
"+ def ALLOWED_TABLES(cls) -> List[str]:",
"+ \"\"\"Erlaubte Tabellen - flache Liste aus allen DBs.\"\"\"",
"+ cfg = _load_json_config()",
"+ tables_dict = cfg.get(\"allowed_tables\", {})",
"+ # Flatten: alle Tabellen aus allen DBs",
"+ all_tables = []",
"+ for db_tables in tables_dict.values():",
"+ if isinstance(db_tables, list):",
"+ all_tables.extend(db_tables)",
"+ return all_tables if all_tables else [",
"+ \"mcp_log\", \"protokoll\", \"tasks\", \"contracts\",",
"+ \"dokumentation\", \"prompts\", \"critics\"",
"+ ]",
"+",
"+ @property",
"+ def BLOCKED_KEYWORDS(cls) -> List[str]:",
"+ \"\"\"Blockierte SQL-Keywords.\"\"\"",
"+ cfg = _load_json_config()",
"+ return cfg.get(\"blocked_keywords\", [",
"+ \"DROP\", \"DELETE\", \"INSERT\", \"UPDATE\", \"TRUNCATE\",",
"+ \"ALTER\", \"CREATE\", \"RENAME\", \"GRANT\", \"REVOKE\",",
"+ \"LOAD_FILE\", \"INTO OUTFILE\", \"INTO DUMPFILE\",",
"+ \"BENCHMARK\", \"SLEEP\"",
"+ ])",
"+",
"+ @property",
"+ def MAX_QUERY_LENGTH(cls) -> int:",
"+ \"\"\"Maximale Query-Länge.\"\"\"",
"+ cfg = _load_json_config()",
"+ limits = cfg.get(\"limits\", {})",
"+ return limits.get(\"max_query_length\", 2000)",
"+",
"+ @property",
"+ def MAX_ROWS(cls) -> int:",
"+ \"\"\"Maximale Ergebniszeilen.\"\"\"",
"+ cfg = _load_json_config()",
"+ limits = cfg.get(\"limits\", {})",
"+ return limits.get(\"max_rows\", 100)",
"+",
"+ @property",
"+ def QUERY_TIMEOUT_SEC(cls) -> int:",
"+ \"\"\"Query-Timeout in Sekunden.\"\"\"",
"+ cfg = _load_json_config()",
"+ limits = cfg.get(\"limits\", {})",
"+ return limits.get(\"query_timeout_sec\", 30)",
"+",
"+",
"+class Config(metaclass=_ConfigMeta):",
"+ \"\"\"",
"+ Konfiguration mit Hot-Reload aus \/etc\/mcp-db\/config.json.",
"+",
"+ Änderungen an der JSON-Datei werden sofort wirksam,",
"+ ohne den MCP-Server neu starten zu müssen.",
"+",
"+ Statische Werte aus Environment Variables:",
"+ - DB_HOST, DB_USER, DB_PASSWORD (Query-User)",
"+ - LOG_DB_HOST, LOG_DB_NAME, LOG_DB_USER, LOG_DB_PASSWORD (Logger)",
"+",
"+ Dynamische Werte aus JSON:",
"+ - ALLOWED_DATABASES, ALLOWED_TABLES, BLOCKED_KEYWORDS",
"+ - MAX_QUERY_LENGTH, MAX_ROWS, QUERY_TIMEOUT_SEC",
"+ \"\"\"",
"+",
"+ # Statische Werte aus Environment (nur bei Start geladen)",
" DB_HOST: str = os.getenv(\"DB_HOST\", \"localhost\")",
" DB_USER: str = os.getenv(\"DB_USER\", \"mcp_readonly\")",
" DB_PASSWORD: str = os.getenv(\"DB_PASSWORD\", \"\")",
" ",
"- # Datenbank für Logging (mcp_logger)",
" LOG_DB_HOST: str = os.getenv(\"LOG_DB_HOST\", \"localhost\")",
" LOG_DB_NAME: str = os.getenv(\"LOG_DB_NAME\", \"ki_dev\")",
" LOG_DB_USER: str = os.getenv(\"LOG_DB_USER\", \"mcp_logger\")",
" LOG_DB_PASSWORD: str = os.getenv(\"LOG_DB_PASSWORD\", \"\")",
"-",
"- # Database Allowlist",
"- ALLOWED_DATABASES: List[str] = [\"ki_dev\", \"ki_content\"]",
"-",
"- # Dangerous Keyword Blocklist",
"- BLOCKED_KEYWORDS: List[str] = [",
"- \"DROP\",",
"- \"DELETE\",",
"- \"INSERT\",",
"- \"UPDATE\",",
"- \"TRUNCATE\",",
"- \"ALTER\",",
"- \"CREATE\",",
"- \"RENAME\",",
"- \"GRANT\",",
"- \"REVOKE\",",
"- \"LOAD_FILE\",",
"- \"INTO OUTFILE\",",
"- \"INTO DUMPFILE\",",
"- \"BENCHMARK\",",
"- \"SLEEP\",",
"- ]",
"-",
"- # Query Limits",
"- MAX_QUERY_LENGTH: int = 2000",
"- MAX_ROWS: int = 100",
"- QUERY_TIMEOUT_SEC: int = 30",
"-",
"- # Table Allowlist (nur existierende Tabellen)",
"- # ki_dev: mcp_log, protokoll, tasks, contracts, dokumentation, pipeline, prompts",
"- # ki_content: content, chat, chunks, entities, taxonomy",
"- ALLOWED_TABLES: List[str] = [",
"- # ki_dev - Logs",
"- \"mcp_log\",",
"- \"protokoll\",",
"- \"file_backup_history\",",
"- # ki_dev - Tasks",
"- \"tasks\",",
"- \"task_assignments\",",
"- \"task_results\",",
"- \"task_comments\",",
"- # ki_dev - Contracts",
"- \"contracts\",",
"- \"contract_history\",",
"- \"contract_validations\",",
"- # ki_dev - Dokumentation",
"- \"dokumentation\",",
"- \"dokumentation_chunks\",",
"- \"dokumentation_history\",",
"- # ki_dev - Pipeline\/Prompts",
"- \"pipeline_log\",",
"- \"pipeline_queue\",",
"- \"prompts\",",
"- \"prompt_tests\",",
"- \"system_prompts\",",
"- \"llm_requests\",",
"- # ki_content - Content Studio",
"- \"content_orders\",",
"- \"content_versions\",",
"- \"content_contracts\",",
"- \"content_critiques\",",
"- \"content_sources\",",
"- \"content_structures\",",
"- \"content_config\",",
"- \"content_config_history\",",
"- \"author_profiles\",",
"- \"critics\",",
"- # ki_dev - RAG Collections",
"- \"rag_collections\",",
"- # ki_content - RAG\/Documents",
"- \"documents\",",
"- \"chunks\",",
"- \"chunk_semantics\",",
"- \"chunk_entities\",",
"- \"chunk_taxonomy\",",
"- \"document_taxonomy\",",
"- # ki_content - Chat",
"- \"chat_sessions\",",
"- \"chat_messages\",",
"- # ki_content - Entities\/Taxonomy",
"- \"entities\",",
"- \"entity_relations\",",
"- \"entity_synonyms\",",
"- \"entity_classifications\",",
"- \"taxonomy_terms\",",
"- \"ontology_classes\",",
"- # ki_content - Search",
"- \"search_history\",",
"- ]"
]
}
],
"originalFile": "\"\"\"Zentrale Konfiguration für MCP-DB Server\"\"\"\nimport os\nfrom typing import List\n\n\nclass Config:\n \"\"\"Konfiguration aus Environment Variables\"\"\"\n\n # Datenbank für Queries (mcp_readonly)\n DB_HOST: str = os.getenv(\"DB_HOST\", \"localhost\")\n DB_USER: str = os.getenv(\"DB_USER\", \"mcp_readonly\")\n DB_PASSWORD: str = os.getenv(\"DB_PASSWORD\", \"\")\n\n # Datenbank für Logging (mcp_logger)\n LOG_DB_HOST: str = os.getenv(\"LOG_DB_HOST\", \"localhost\")\n LOG_DB_NAME: str = os.getenv(\"LOG_DB_NAME\", \"ki_dev\")\n LOG_DB_USER: str = os.getenv(\"LOG_DB_USER\", \"mcp_logger\")\n LOG_DB_PASSWORD: str = os.getenv(\"LOG_DB_PASSWORD\", \"\")\n\n # Database Allowlist\n ALLOWED_DATABASES: List[str] = [\"ki_dev\", \"ki_content\"]\n\n # Dangerous Keyword Blocklist\n BLOCKED_KEYWORDS: List[str] = [\n \"DROP\",\n \"DELETE\",\n \"INSERT\",\n \"UPDATE\",\n \"TRUNCATE\",\n \"ALTER\",\n \"CREATE\",\n \"RENAME\",\n \"GRANT\",\n \"REVOKE\",\n \"LOAD_FILE\",\n \"INTO OUTFILE\",\n \"INTO DUMPFILE\",\n \"BENCHMARK\",\n \"SLEEP\",\n ]\n\n # Query Limits\n MAX_QUERY_LENGTH: int = 2000\n MAX_ROWS: int = 100\n QUERY_TIMEOUT_SEC: int = 30\n\n # Table Allowlist (nur existierende Tabellen)\n # ki_dev: mcp_log, protokoll, tasks, contracts, dokumentation, pipeline, prompts\n # ki_content: content, chat, chunks, entities, taxonomy\n ALLOWED_TABLES: List[str] = [\n # ki_dev - Logs\n \"mcp_log\",\n \"protokoll\",\n \"file_backup_history\",\n # ki_dev - Tasks\n \"tasks\",\n \"task_assignments\",\n \"task_results\",\n \"task_comments\",\n # ki_dev - Contracts\n \"contracts\",\n \"contract_history\",\n \"contract_validations\",\n # ki_dev - Dokumentation\n \"dokumentation\",\n \"dokumentation_chunks\",\n \"dokumentation_history\",\n # ki_dev - Pipeline\/Prompts\n \"pipeline_log\",\n \"pipeline_queue\",\n \"prompts\",\n \"prompt_tests\",\n \"system_prompts\",\n \"llm_requests\",\n # ki_content - Content Studio\n \"content_orders\",\n \"content_versions\",\n \"content_contracts\",\n \"content_critiques\",\n \"content_sources\",\n \"content_structures\",\n \"content_config\",\n \"content_config_history\",\n \"author_profiles\",\n \"critics\",\n # ki_dev - RAG Collections\n \"rag_collections\",\n # ki_content - RAG\/Documents\n \"documents\",\n \"chunks\",\n \"chunk_semantics\",\n \"chunk_entities\",\n \"chunk_taxonomy\",\n \"document_taxonomy\",\n # ki_content - Chat\n \"chat_sessions\",\n \"chat_messages\",\n # ki_content - Entities\/Taxonomy\n \"entities\",\n \"entity_relations\",\n \"entity_synonyms\",\n \"entity_classifications\",\n \"taxonomy_terms\",\n \"ontology_classes\",\n # ki_content - Search\n \"search_history\",\n ]\n"
}
}