{
"event": "PreToolUse",
"tool_name": "Edit",
"tool_input": {
"file_path": "\/var\/www\/mcp-servers\/mcp-db\/tools\/describe_tool.py",
"old_string": "\"error\": str(e)[:200],",
"new_string": "\"error\": str(e)[:LOG_QUERY_MAX_LENGTH],"
}
}
{
"tool_response": {
"filePath": "\/var\/www\/mcp-servers\/mcp-db\/tools\/describe_tool.py",
"oldString": "\"error\": str(e)[:200],",
"newString": "\"error\": str(e)[:LOG_QUERY_MAX_LENGTH],",
"originalFile": "\"\"\"Describe Tool - Zeigt Tabellen-Struktur an.\"\"\"\nimport re\nimport sys\nimport time\n\nsys.path.insert(0, \"\/opt\/mcp-servers\/mcp-db\")\nsys.path.insert(0, \"\/var\/www\/mcp-servers\/shared\")\n\nfrom constants import LOG_ENTRY_MAX_LENGTH, LOG_QUERY_MAX_LENGTH, MS_PER_SECOND\n\nfrom config import Config\nfrom domain.log_contract import LogEntry\nfrom infrastructure.db_connection import DatabaseConnection\nfrom infrastructure.protokoll_logger import ProtokollLogger\n\n\ndef register_describe_tool(mcp) -> None:\n \"\"\"Registriert db_describe Tool.\"\"\"\n logger = ProtokollLogger()\n\n @mcp.tool()\n def db_describe(\n table: str,\n database: str = \"ki_dev\",\n show_create: bool = False,\n ) -> dict:\n \"\"\"\n Zeigt Tabellen-Struktur an.\n\n Args:\n table: Tabellenname\n database: Zieldatenbank (ki_dev oder ki_content)\n show_create: True = SHOW CREATE TABLE, False = DESCRIBE\n\n Returns:\n Dict mit columns oder create_statement\n \"\"\"\n start = time.time()\n\n # Validierung: Tabellenname (SQL-Injection-Schutz)\n if not re.match(r\"^[a-zA-Z0-9_]+$\", table):\n return {\n \"status\": \"denied\",\n \"error\": \"Invalid table name. Only alphanumeric and underscore allowed.\",\n }\n\n # Validierung: Datenbank\n if database not in Config.ALLOWED_DATABASES:\n return {\n \"status\": \"denied\",\n \"error\": f\"Database '{database}' not allowed.\",\n }\n\n try:\n with DatabaseConnection.get_connection(database) as conn:\n cursor = conn.cursor(dictionary=True, buffered=True)\n\n if show_create:\n cursor.execute(f\"SHOW CREATE TABLE `{table}`\")\n row = cursor.fetchone()\n cursor.close()\n\n duration = int((time.time() - start) * MS_PER_SECOND)\n\n # Log\n try:\n logger.log(\n LogEntry(\n request=f\"SHOW CREATE TABLE {table}\",\n status=\"success\",\n duration_ms=duration,\n )\n )\n except Exception:\n pass\n\n return {\n \"status\": \"success\",\n \"table\": table,\n \"create_statement\": row.get(\"Create Table\", \"\") if row else \"\",\n \"execution_ms\": duration,\n }\n else:\n cursor.execute(f\"DESCRIBE `{table}`\")\n columns = cursor.fetchall()\n cursor.close()\n\n duration = int((time.time() - start) * MS_PER_SECOND)\n\n # Log\n try:\n logger.log(\n LogEntry(\n request=f\"DESCRIBE {table}\",\n status=\"success\",\n duration_ms=duration,\n )\n )\n except Exception:\n pass\n\n return {\n \"status\": \"success\",\n \"table\": table,\n \"columns\": columns,\n \"execution_ms\": duration,\n }\n\n except Exception as e:\n duration = int((time.time() - start) * MS_PER_SECOND)\n\n try:\n logger.log(\n LogEntry(\n request=f\"DESCRIBE {table}\",\n status=\"error\",\n duration_ms=duration,\n error_message=str(e)[:LOG_ENTRY_MAX_LENGTH],\n )\n )\n except Exception:\n pass\n\n return {\n \"status\": \"error\",\n \"error\": str(e)[:200],\n \"execution_ms\": duration,\n }\n",
"structuredPatch": [
{
"oldStart": 123,
"oldLines": 6,
"newStart": 123,
"newLines": 6,
"lines": [
" ",
" return {",
" \"status\": \"error\",",
"- \"error\": str(e)[:200],",
"+ \"error\": str(e)[:LOG_QUERY_MAX_LENGTH],",
" \"execution_ms\": duration,",
" }"
]
}
],
"userModified": false,
"replaceAll": false
}
}